istox 0.1.81.pre.test10 → 0.1.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/istox.rb +22 -23
- data/lib/istox/consumers/blockchain_hash_handler.rb +19 -0
- data/lib/istox/consumers/blockchain_status_handler.rb +106 -47
- data/lib/istox/helpers/blockchain_receipt_service.rb +71 -0
- data/lib/istox/helpers/f_math.rb +19 -16
- data/lib/istox/helpers/graphql_client.rb +29 -29
- data/lib/istox/helpers/grpc_client.rb +54 -51
- data/lib/istox/helpers/order_book.rb +40 -68
- data/lib/istox/logging/hash_logging.rb +3 -2
- data/lib/istox/logging/log_formatter.rb +5 -4
- data/lib/istox/migrations/create_blockchain_receipts.rb +24 -23
- data/lib/istox/models/blockchain_receipt.rb +5 -2
- data/lib/istox/models/concerns/blockchain_receipt_query.rb +24 -10
- data/lib/istox/version.rb +1 -1
- metadata +6 -9
- data/.rubocop.yml +0 -102
- data/.solargraph.yml +0 -14
- data/lib/istox/helpers/blockchain_service.rb +0 -64
- data/lib/istox/helpers/common_helper.rb +0 -45
- data/lib/istox/helpers/my_open_struct.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9b67e7deab7a2a53ab80d237842554f21ca126e3542bf75dfbbb68a46961395
|
4
|
+
data.tar.gz: 913e6213c402f933ac375bb77999119131d25e0a886c5cf2819c8ed56685ba88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c02663da343a9b5efef558084c5a14f32c92900b055d3fc3041e71dec38a1fa828b2e8ed4aee8ef7f1c2f7eccc991bd11a24bb2e7300505b6b11e025ff4249d
|
7
|
+
data.tar.gz: a57ed4210294057d2ef6cbbb9dedab41b28e0a2f78f8f75e2d97d17f5afce0b3a9948f9aca7ad0a8b0d685bfd58ebbf08d0876a0236b0833ff100beed7595368
|
data/Gemfile.lock
CHANGED
data/lib/istox.rb
CHANGED
@@ -1,35 +1,34 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
require 'paranoia'
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "gruf"
|
4
|
+
require "listen"
|
5
|
+
require "istox/version"
|
6
6
|
|
7
7
|
module Istox
|
8
8
|
# Your code goes here...
|
9
9
|
class Test
|
10
10
|
def self.method1
|
11
|
-
|
11
|
+
"abc"
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
28
|
-
require
|
29
|
-
require
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
33
|
-
require 'istox/logging/log_formatter'
|
15
|
+
require "istox/interfaces/chainhub/transaction"
|
16
|
+
require "istox/helpers/publisher"
|
17
|
+
require "istox/helpers/bunny_boot"
|
18
|
+
require "istox/helpers/vault"
|
19
|
+
require "istox/helpers/order_book"
|
20
|
+
require "istox/helpers/grpc_client"
|
21
|
+
require "istox/helpers/graphql_client"
|
22
|
+
require "istox/helpers/gruf_listener_hook"
|
23
|
+
require "istox/helpers/message_service"
|
24
|
+
require "istox/helpers/blockchain_receipt_service"
|
25
|
+
require "istox/helpers/f_math"
|
26
|
+
require "istox/models/blockchain_receipt"
|
27
|
+
require "istox/models/concerns/blockchain_receipt_query"
|
28
|
+
require "istox/consumers/blockchain_status_handler"
|
29
|
+
require "istox/consumers/blockchain_hash_handler"
|
30
|
+
require "istox/migrations/create_blockchain_receipts"
|
31
|
+
require "istox/logging/hash_logging"
|
32
|
+
require "istox/logging/log_formatter"
|
34
33
|
require "istox/quant/bond"
|
35
34
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Istox
|
2
|
+
class BlockchainHashHandler
|
3
|
+
class << self
|
4
|
+
def hash_generated(data, payload_target)
|
5
|
+
receipt = ::Istox::BlockchainReceipt.where(txid: data.uuid).first
|
6
|
+
if receipt.nil?
|
7
|
+
puts 'Transaction doesnt belong here, skipping...'
|
8
|
+
return
|
9
|
+
end
|
10
|
+
|
11
|
+
# sid cannot be nil
|
12
|
+
update_receipt = ::Istox::BlockchainReceipt.where(txid: data.uuid, txhash: nil).where.not(sid: nil).first
|
13
|
+
raise "Unable to find receipt to update" if update_receipt.blank?
|
14
|
+
|
15
|
+
update_receipt.update!(txhash: data.txnHash)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,54 +1,105 @@
|
|
1
1
|
module Istox
|
2
2
|
class BlockchainStatusHandler
|
3
3
|
class << self
|
4
|
-
# format of transaction
|
5
|
-
# {
|
6
|
-
# type: 'CHAINHUB_RESPONSE_EVENT',
|
7
|
-
# uuid:'123', //original request uuid sent from backend
|
8
|
-
# success:true, //status of the whole request in true/false
|
9
|
-
# message:'', //In case of error, the message contain the error reason
|
10
|
-
# txnCount:1, //Number of blockchain transactions from the original request
|
11
|
-
# txnHashes:[] //Hashes for all transactions that has been submitted and mined by the blockchain for verification purpose
|
12
|
-
# }
|
13
|
-
|
14
|
-
def chainhub_response_event(transaction)
|
15
|
-
receipt = ::Istox::BlockchainReceipt.where(txid: transaction.uuid).first
|
16
|
-
if receipt.blank?
|
17
|
-
puts 'Transaction doesn\'t belong to this backend, skipping...'
|
18
|
-
return
|
19
|
-
end
|
20
4
|
|
21
|
-
|
5
|
+
def txn_data_confirmed(transactions)
|
6
|
+
found_txns = transactions.map do |transaction|
|
7
|
+
receipt = ::Istox::BlockchainReceipt.where(txid: transaction.uuid).first
|
8
|
+
if !receipt.blank?
|
9
|
+
handling_receipt = ::Istox::BlockchainReceipt.where(txhash: transaction.id, txid: transaction.uuid).first
|
10
|
+
raise 'Unable to find receipt' if handling_receipt.blank?
|
11
|
+
transaction
|
12
|
+
else
|
13
|
+
puts 'Transaction doesnt belong here, skipping...'
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
end.compact
|
17
|
+
|
18
|
+
found_txns.each do |transaction|
|
19
|
+
receipt = ::Istox::BlockchainReceipt.where(txhash: transaction.id, txid: transaction.uuid).first
|
20
|
+
|
21
|
+
receipt.update!(status: "confirmed")
|
22
|
+
|
23
|
+
resource = begin
|
24
|
+
class_eval("::#{receipt.resource_name}").find(receipt.resource_id)
|
25
|
+
rescue => e
|
26
|
+
puts "Class not found, skipping..."
|
27
|
+
next
|
28
|
+
end
|
29
|
+
|
30
|
+
receipt_list = get_receipt_list(resource)
|
31
|
+
|
32
|
+
next if resource_handled?(receipt_list)
|
22
33
|
|
23
|
-
|
24
|
-
|
34
|
+
next if resource.outcome == 'pending'
|
35
|
+
|
36
|
+
if resource.outcome == 'confirmed'
|
37
|
+
resource.handle_confirm(receipt.resource_action)
|
38
|
+
|
39
|
+
mark_resource_handled(receipt_list)
|
40
|
+
publish_to_frontend(resource, true, receipt, receipt.sid, receipt_list)
|
41
|
+
end
|
25
42
|
|
26
|
-
resource = begin
|
27
|
-
class_eval("::#{receipt.resource_name}", __FILE__, __LINE__).find(receipt.resource_id)
|
28
|
-
rescue StandardError
|
29
|
-
puts 'Class not found, skipping...'
|
30
|
-
return
|
31
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def txn_status_changed(transactions, payload_target)
|
47
|
+
# pre check all transaction does exists
|
48
|
+
found_txns = transactions.map do |transaction|
|
49
|
+
receipt = ::Istox::BlockchainReceipt.where(txid: transaction.uuid).first
|
50
|
+
if !receipt.blank?
|
51
|
+
handling_receipt = ::Istox::BlockchainReceipt.where(txhash: transaction.id, txid: transaction.uuid).first
|
52
|
+
raise 'Unable to find receipt' if handling_receipt.blank?
|
53
|
+
transaction
|
54
|
+
else
|
55
|
+
puts 'Transaction doesnt belong here, skipping...'
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end.compact
|
59
|
+
|
60
|
+
found_txns.each do |transaction|
|
61
|
+
receipt = ::Istox::BlockchainReceipt.where(txhash: transaction.id, txid: transaction.uuid).first
|
62
|
+
|
63
|
+
next if !(%w[failed pending].include?(transaction.status))
|
64
|
+
receipt.update!(status: transaction.status)
|
65
|
+
|
66
|
+
resource = begin
|
67
|
+
class_eval("::#{receipt.resource_name}").find(receipt.resource_id)
|
68
|
+
rescue => e
|
69
|
+
puts "Class not found, skipping..."
|
70
|
+
next
|
71
|
+
end
|
32
72
|
|
33
|
-
|
73
|
+
receipt_list = get_receipt_list(resource)
|
34
74
|
|
35
|
-
|
36
|
-
resource.handle_confirm(receipt)
|
75
|
+
next if resource_handled?(receipt_list)
|
37
76
|
|
38
|
-
|
39
|
-
|
77
|
+
# if transaction.status == 'confirmed'
|
78
|
+
# next if resource.outcome == 'pending'
|
40
79
|
|
41
|
-
|
42
|
-
resource.
|
80
|
+
# if resource.outcome == 'confirmed'
|
81
|
+
# resource.handle_confirm(receipt.resource_action)
|
82
|
+
|
83
|
+
# mark_resource_handled(receipt_list)
|
84
|
+
# publish_to_frontend(resource, true, receipt, receipt.sid, receipt_list)
|
85
|
+
# end
|
86
|
+
# end
|
87
|
+
|
88
|
+
if transaction.status == 'failed'
|
89
|
+
resource.handle_fail(receipt.resource_action)
|
90
|
+
|
91
|
+
mark_resource_handled(receipt_list)
|
92
|
+
publish_to_frontend(resource, false, receipt, receipt.sid, receipt_list)
|
93
|
+
end
|
43
94
|
|
44
|
-
mark_resource_handled(receipt)
|
45
|
-
publish_to_frontend(resource, false, receipt, receipt.sid)
|
46
95
|
end
|
47
96
|
end
|
48
97
|
|
49
98
|
private
|
50
99
|
|
51
|
-
def publish_to_frontend(model, success, receipt, sid)
|
100
|
+
def publish_to_frontend(model, success, receipt, sid, receipt_list)
|
101
|
+
yield if block_given?
|
102
|
+
|
52
103
|
::Istox::Publisher.publish(
|
53
104
|
'amq.topic',
|
54
105
|
model.class.name.gsub('::', '').underscore.to_s,
|
@@ -64,26 +115,34 @@ module Istox
|
|
64
115
|
data: {
|
65
116
|
success: success,
|
66
117
|
purpose: receipt.activity,
|
67
|
-
|
118
|
+
txids: get_receipts_tx_hashes(receipt_list)
|
68
119
|
}
|
69
120
|
)
|
70
|
-
rescue StandardError => e
|
71
|
-
Rails.logger.error "Unable to publish to frontend for receipt #{receipt.inspect},
|
72
|
-
but will silently ignore the error"
|
73
|
-
Rails.logger.error e
|
74
121
|
end
|
75
122
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
but will silently ignore the error"
|
81
|
-
Rails.logger.error e
|
123
|
+
def get_receipts_tx_hashes(receipt_list)
|
124
|
+
tx_hashes = receipt_list.map(&:txhash).compact
|
125
|
+
|
126
|
+
tx_hashes.join(', ')
|
82
127
|
end
|
83
128
|
|
84
|
-
def
|
85
|
-
|
129
|
+
def mark_resource_handled(receipt_list)
|
130
|
+
receipt_list.each do |receipt|
|
131
|
+
receipt.update(resource_handled: true)
|
132
|
+
end
|
86
133
|
end
|
134
|
+
|
135
|
+
def resource_handled?(receipt_list)
|
136
|
+
receipt_list.map(&:resource_handled).none? { |item| item.nil? || item == false }
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_receipt_list(resource)
|
140
|
+
::Istox::BlockchainReceipt.where(
|
141
|
+
resource_name: resource.class.name,
|
142
|
+
resource_id: resource.id
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
87
146
|
end
|
88
147
|
end
|
89
148
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Istox
|
2
|
+
class BlockchainReceiptService
|
3
|
+
|
4
|
+
def self.init(blockchain_receipt_klass)
|
5
|
+
@@blockchain_receipt_klass = blockchain_receipt_klass
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.get_blockchain_receipt_klass
|
9
|
+
@@blockchain_receipt_klass
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.generate_uuid
|
13
|
+
klass = ::Istox::BlockchainReceiptService.blockchain_receipt_class
|
14
|
+
uuid = SecureRandom.uuid
|
15
|
+
|
16
|
+
klass.create!({
|
17
|
+
txid: uuid
|
18
|
+
})
|
19
|
+
|
20
|
+
uuid
|
21
|
+
end
|
22
|
+
|
23
|
+
def create!(tx_message, model, sid, action, is_request: false)
|
24
|
+
klass = ::Istox::BlockchainReceiptService.blockchain_receipt_class
|
25
|
+
|
26
|
+
# delete the previous existing blockchain receipts
|
27
|
+
klass.where(resource_name: model.class.name,
|
28
|
+
resource_id: model.id).destroy_all
|
29
|
+
|
30
|
+
(0...tx_message.txnCount).each do |i|
|
31
|
+
if i == 0
|
32
|
+
blockchain_receipt = klass.find_by_txid(tx_message.uuid)
|
33
|
+
|
34
|
+
raise "Unable to find blockchain receipt with uuid #{tx_message.uuid}, have you forgetten to generate uuid?" if blockchain_receipt.blank?
|
35
|
+
|
36
|
+
blockchain_receipt.update!({
|
37
|
+
sid: sid,
|
38
|
+
txid: tx_message.uuid,
|
39
|
+
resource_name: model.class.name,
|
40
|
+
resource_id: model.id,
|
41
|
+
resource_action: action,
|
42
|
+
is_request: is_request
|
43
|
+
})
|
44
|
+
else
|
45
|
+
blockchain_receipt = klass.new(
|
46
|
+
sid: sid,
|
47
|
+
txid: tx_message.uuid,
|
48
|
+
resource_name: model.class.name,
|
49
|
+
resource_id: model.id,
|
50
|
+
resource_action: action,
|
51
|
+
is_request: is_request
|
52
|
+
)
|
53
|
+
blockchain_receipt.save!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.blockchain_receipt_class
|
59
|
+
raise "Have you forgetten to init blockchain receipt service?" if ::Istox::BlockchainReceiptService.get_blockchain_receipt_klass == nil
|
60
|
+
|
61
|
+
blockchain_receipt_klass = ::Istox::BlockchainReceiptService.get_blockchain_receipt_klass
|
62
|
+
klass = class_eval("::#{blockchain_receipt_klass.name}")
|
63
|
+
unless klass <= ::Istox::BlockchainReceipt
|
64
|
+
raise RuntimeError, "#{blockchain_receipt_klass.name} does not inherit istox blockchain receipt"
|
65
|
+
end
|
66
|
+
|
67
|
+
return klass
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
data/lib/istox/helpers/f_math.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# rubocop:disable Naming/UncommunicativeMethodParamName
|
2
1
|
module Istox
|
3
2
|
class FMath
|
4
3
|
class << self
|
4
|
+
|
5
5
|
def add(x, y)
|
6
6
|
BigDecimal.mode(BigDecimal::ROUND_MODE, :down)
|
7
7
|
|
@@ -11,7 +11,7 @@ module Istox
|
|
11
11
|
x = ::BigDecimal.new(x.to_s)
|
12
12
|
y = ::BigDecimal.new(y.to_s)
|
13
13
|
|
14
|
-
x.add(y, 100).truncate(18).to_s
|
14
|
+
return x.add(y, 100).truncate(18).to_s
|
15
15
|
end
|
16
16
|
|
17
17
|
def sub(x, y)
|
@@ -23,7 +23,7 @@ module Istox
|
|
23
23
|
x = ::BigDecimal.new(x.to_s)
|
24
24
|
y = ::BigDecimal.new(y.to_s)
|
25
25
|
|
26
|
-
x.sub(y, 100).truncate(18).to_s
|
26
|
+
return x.sub(y, 100).truncate(18).to_s
|
27
27
|
end
|
28
28
|
|
29
29
|
def mul(x, y)
|
@@ -35,7 +35,7 @@ module Istox
|
|
35
35
|
x = ::BigDecimal.new(x.to_s)
|
36
36
|
y = ::BigDecimal.new(y.to_s)
|
37
37
|
|
38
|
-
x.mult(y, 100).truncate(18).to_s
|
38
|
+
return x.mult(y, 100).truncate(18).to_s
|
39
39
|
end
|
40
40
|
|
41
41
|
def div(x, y)
|
@@ -47,17 +47,19 @@ module Istox
|
|
47
47
|
x = to_fixed(x)
|
48
48
|
y = to_fixed(y)
|
49
49
|
|
50
|
-
return ::BigDecimal.new(
|
51
|
-
|
52
|
-
fixed1 = ::BigDecimal.new('1e18')
|
50
|
+
return ::BigDecimal.new("1").to_s if x == y
|
53
51
|
|
54
|
-
|
52
|
+
fixed_1 = ::BigDecimal.new("1e18")
|
53
|
+
|
54
|
+
if (((x.div(y, 100)).modulo(BigDecimal.new(10)) == 0) && (x.modulo(y) == 0))
|
55
|
+
return from_fixed((x.div(y, 100).mult(fixed_1, 100)))
|
56
|
+
end
|
55
57
|
|
56
|
-
r_y =
|
58
|
+
r_y = fixed_1.mult(fixed_1, 100).truncate(0).div(y, 100).truncate(0)
|
57
59
|
|
58
|
-
result = from_fixed(x.mult(r_y, 100).truncate(0).div(
|
60
|
+
result = from_fixed(x.mult(r_y, 100).truncate(0).div(fixed_1, 100).truncate(0))
|
59
61
|
|
60
|
-
result.truncate(18).to_s
|
62
|
+
return result.truncate(18).to_s
|
61
63
|
end
|
62
64
|
|
63
65
|
def round_up(x, digits)
|
@@ -65,23 +67,24 @@ module Istox
|
|
65
67
|
x = 0 if x.blank?
|
66
68
|
::BigDecimal.new(x.to_s).round(digits).to_s
|
67
69
|
end
|
68
|
-
|
70
|
+
|
69
71
|
def round_down(x, digits)
|
70
72
|
BigDecimal.mode(BigDecimal::ROUND_MODE, :down)
|
71
73
|
x = 0 if x.blank?
|
72
74
|
::BigDecimal.new(x.to_s).round(digits).to_s
|
73
75
|
end
|
74
76
|
|
75
|
-
private
|
77
|
+
private
|
76
78
|
|
77
79
|
def to_fixed(x)
|
78
|
-
::BigDecimal.new(x.to_s).mult(::BigDecimal.new('1e18'), 100).truncate(18)
|
80
|
+
return ::BigDecimal.new(x.to_s).mult(::BigDecimal.new('1e18'), 100).truncate(18)
|
79
81
|
end
|
80
82
|
|
81
83
|
def from_fixed(x)
|
82
|
-
::BigDecimal.new(x.to_s).div(::BigDecimal.new('1e18'), 100).truncate(18)
|
84
|
+
return ::BigDecimal.new(x.to_s).div(::BigDecimal.new('1e18'), 100).truncate(18)
|
83
85
|
end
|
86
|
+
|
87
|
+
|
84
88
|
end
|
85
89
|
end
|
86
90
|
end
|
87
|
-
# rubocop:enable Naming/UncommunicativeMethodParamName
|
@@ -1,35 +1,35 @@
|
|
1
|
-
require
|
1
|
+
require "graphlient"
|
2
2
|
|
3
3
|
module Istox
|
4
4
|
class GraphqlClient
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
5
|
+
class << self
|
6
|
+
def add_host(host_type, url)
|
7
|
+
unless defined?(@@hosts)
|
8
|
+
@@hosts = {}
|
9
|
+
end
|
10
|
+
init_host(host_type, url)
|
11
|
+
end
|
12
|
+
|
13
|
+
def query(host_type, query, variables = {})
|
14
|
+
client = @@hosts[host_type]
|
15
|
+
|
16
|
+
raise "Please make sure you have initialised graphql cient for host #{host_type}" if !client
|
17
|
+
|
18
|
+
Rails.logger.info "Querying Graphql host: #{host_type}, query: #{query}, variables: #{variables.inspect}"
|
19
|
+
result = client.query(query, variables)
|
20
|
+
Rails.logger.info "Graphql result: #{result.inspect}"
|
21
|
+
|
22
|
+
return result
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def init_host(host_type, url)
|
28
|
+
client = Graphlient::Client.new(url, http: Graphlient::Adapters::HTTP::HTTPAdapter)
|
29
|
+
|
30
|
+
@@hosts[host_type] = client
|
31
|
+
end
|
30
32
|
|
31
|
-
@@hosts[host_type] = client
|
32
33
|
end
|
33
|
-
end
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
@@ -1,63 +1,66 @@
|
|
1
1
|
module Istox
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class GrpcClient
|
3
|
+
class << self
|
4
|
+
def add_host(host_type, url)
|
5
|
+
unless defined?(@@hosts)
|
6
|
+
@@hosts = {}
|
7
|
+
end
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
@@hosts[host_type] = url
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def call(host_type, service, method, **keyword_args)
|
13
|
+
execute(host_type, service, method, **keyword_args)
|
14
|
+
# rescue => e
|
15
|
+
# reinitiate service and try again, second chance
|
16
|
+
# reinitiate_service(host_type, service)
|
17
|
+
# execute(host_type, service, method, **keyword_args)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
17
21
|
|
18
|
-
|
22
|
+
def execute(host_type, service, method, **keyword_args)
|
23
|
+
Rails.logger.info "Calling method in grpc method: #{method.inspect}, params: #{keyword_args.inspect}"
|
24
|
+
t1 = Time.now
|
25
|
+
|
26
|
+
result = get_host(host_type, service).call(method, keyword_args)
|
27
|
+
Rails.logger.info "Time taken for grpc execution: #{Time.now - t1} seconds"
|
28
|
+
Rails.logger.info "Result: #{result.message.inspect}"
|
29
|
+
result
|
30
|
+
end
|
19
31
|
|
20
|
-
|
21
|
-
|
22
|
-
|
32
|
+
def get_host(host_type, service)
|
33
|
+
unless defined?(@@services)
|
34
|
+
@@services = {}
|
35
|
+
end
|
23
36
|
|
24
|
-
|
25
|
-
Rails.logger.info "Time taken for grpc execution: #{Time.now - t1} seconds"
|
37
|
+
grpc_client = @@services[get_key(host_type, service)]
|
26
38
|
|
27
|
-
|
28
|
-
|
39
|
+
if grpc_client
|
40
|
+
return grpc_client
|
41
|
+
else
|
42
|
+
reinitiate_service(host_type, service)
|
43
|
+
return @@services[get_key(host_type, service)]
|
44
|
+
end
|
45
|
+
end
|
29
46
|
|
30
|
-
|
31
|
-
|
47
|
+
def reinitiate_service(host_type, service)
|
48
|
+
unless defined?(@@services)
|
49
|
+
@@services = {}
|
50
|
+
end
|
32
51
|
|
33
|
-
|
34
|
-
|
52
|
+
host_url = @@hosts[host_type]
|
53
|
+
raise StandardError, 'Unable to find host, have you forgotten to add host to grpc client?' if !host_url
|
54
|
+
|
55
|
+
Rails.logger.info 'Reinitiating to grpc host at ' + host_url
|
56
|
+
t1 = Time.now
|
57
|
+
@@services[get_key(host_type, service)] = ::Gruf::Client.new(service: service, options: { hostname: host_url })
|
58
|
+
Rails.logger.info "Time taken for reinitiating grpc host: #{Time.now - t1} seconds"
|
59
|
+
end
|
35
60
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
return grpc_client
|
40
|
-
else
|
41
|
-
reinitiate_service(host_type, service)
|
42
|
-
return @@services[get_key(host_type, service)]
|
61
|
+
def get_key(host_type, service)
|
62
|
+
host_type.to_s + service.to_s
|
63
|
+
end
|
43
64
|
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def reinitiate_service(host_type, service)
|
47
|
-
@@services = {} unless defined?(@@services)
|
48
|
-
|
49
|
-
host_url = @@hosts[host_type]
|
50
|
-
raise StandardError, 'Unable to find host, have you forgotten to add host to grpc client?' unless host_url
|
51
|
-
|
52
|
-
Rails.logger.info 'Reinitiating to grpc host at ' + host_url
|
53
|
-
t1 = Time.now
|
54
|
-
@@services[get_key(host_type, service)] = ::Gruf::Client.new(service: service, options: { hostname: host_url })
|
55
|
-
Rails.logger.info "Time taken for reinitiating grpc host: #{Time.now - t1} seconds"
|
56
|
-
end
|
57
|
-
|
58
|
-
def get_key(host_type, service)
|
59
|
-
host_type.to_s + service.to_s
|
60
|
-
end
|
61
65
|
end
|
62
|
-
|
63
|
-
end
|
66
|
+
end
|
@@ -2,6 +2,7 @@ module Istox
|
|
2
2
|
class OrderBook
|
3
3
|
class << self
|
4
4
|
def allocation(soft_cap, total_supply, investments)
|
5
|
+
|
5
6
|
# sort by token price desc, and id asc
|
6
7
|
investments = investments.sort do |a, b|
|
7
8
|
[b[:token_price], a[:id]] <=> [a[:token_price], b[:id]]
|
@@ -10,79 +11,50 @@ module Istox
|
|
10
11
|
total_supply = ::BigDecimal.new(total_supply.to_s)
|
11
12
|
|
12
13
|
interests = investments
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
if interests.count > 0
|
15
|
+
cutoff_price = 0.0
|
16
|
+
total_bid_token = 0.0
|
17
|
+
total_allocated = 0.0
|
18
|
+
total_unallocated = 0.0
|
19
|
+
total_investment = 0.0
|
20
|
+
cutoff_price = ::Istox::FMath.round_down(::Istox::FMath.div(soft_cap, total_supply), 2)
|
21
|
+
is_cutoff = false
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
if ::BigDecimal.new(::Istox::FMath.add(total_allocated, bid_token)) >= total_supply
|
38
|
-
unallocated = ::Istox::FMath.sub(::Istox::FMath.add(total_allocated, bid_token), total_supply)
|
39
|
-
allocated = ::Istox::FMath.sub(bid_token, unallocated)
|
40
|
-
cutoff_price = item[:token_price]
|
41
|
-
is_cutoff = true
|
23
|
+
interests = interests.map do |item|
|
24
|
+
bid_token = ::Istox::FMath.div(item[:fiat_amount], item[:token_price])
|
25
|
+
total_bid_token = ::Istox::FMath.add(total_bid_token, bid_token)
|
26
|
+
allocated = 0.0
|
27
|
+
unallocated = bid_token
|
28
|
+
unless is_cutoff
|
29
|
+
allocated = bid_token
|
30
|
+
unallocated = 0.0
|
31
|
+
if ::BigDecimal.new(::Istox::FMath.add(total_allocated, bid_token)) >= total_supply
|
32
|
+
unallocated = ::Istox::FMath.sub(::Istox::FMath.add(total_allocated, bid_token), total_supply)
|
33
|
+
allocated = ::Istox::FMath.sub(bid_token, unallocated)
|
34
|
+
cutoff_price = item[:token_price]
|
35
|
+
is_cutoff = true
|
36
|
+
end
|
37
|
+
total_allocated = ::Istox::FMath.add(total_allocated, allocated)
|
38
|
+
total_unallocated = ::Istox::FMath.add(total_unallocated, unallocated)
|
42
39
|
end
|
43
|
-
|
44
|
-
|
40
|
+
{ id: item[:id], fiat_amount: item[:fiat_amount], bid_price: item[:token_price], bid_token: bid_token,
|
41
|
+
allocated: allocated, unallocated: unallocated }
|
45
42
|
end
|
46
|
-
{
|
47
|
-
id: item[:id],
|
48
|
-
# user bidding total fiat amount
|
49
|
-
fiat_amount: item[:fiat_amount],
|
50
|
-
# user bidding price
|
51
|
-
bid_price: item[:token_price],
|
52
|
-
# total user bidding token derived from fiat_amount / token_price
|
53
|
-
bid_token: bid_token,
|
54
|
-
# round down allocated token to whole number
|
55
|
-
allocated: ::Istox::FMath.round_down(allocated, 0),
|
56
|
-
# round up unallocated token to whole number
|
57
|
-
unallocated: ::Istox::FMath.round_up(unallocated, 0)
|
58
|
-
}
|
59
|
-
end
|
60
43
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
44
|
+
interests = interests.map do |item|
|
45
|
+
investment = ::Istox::FMath.mul(item[:allocated], cutoff_price)
|
46
|
+
total_investment = ::Istox::FMath.add(total_investment, investment)
|
47
|
+
item.merge!(investment: investment)
|
48
|
+
end
|
49
|
+
|
50
|
+
return { total_supply: total_supply, total_investment: total_investment,
|
51
|
+
cutoff_price: cutoff_price, total_bid_token: total_bid_token,
|
52
|
+
total_allocated: total_allocated, total_unallocated: total_unallocated,
|
53
|
+
interests: interests }
|
54
|
+
else
|
55
|
+
raise 'Registration interest is empty'
|
67
56
|
end
|
68
|
-
|
69
|
-
{
|
70
|
-
# total token supply
|
71
|
-
total_supply: total_supply.to_s,
|
72
|
-
# total investment in fiat
|
73
|
-
total_investment: total_investment,
|
74
|
-
# cut off price
|
75
|
-
cutoff_price: cutoff_price.to_s,
|
76
|
-
# total bid tokens, more than total supply for oversubscribe case
|
77
|
-
total_bid_token: total_bid_token,
|
78
|
-
# total allocated tokens
|
79
|
-
total_allocated: total_allocated,
|
80
|
-
# total unallocated tokens
|
81
|
-
total_unallocated: total_unallocated,
|
82
|
-
# all investor interest results
|
83
|
-
interests: interests
|
84
|
-
}
|
85
57
|
end
|
86
58
|
end
|
87
59
|
end
|
88
|
-
end
|
60
|
+
end
|
@@ -13,8 +13,9 @@ module Istox
|
|
13
13
|
include ActiveSupport::TaggedLogging::Formatter
|
14
14
|
|
15
15
|
def call(severity, timestamp, progname, msg)
|
16
|
-
tagged_message =
|
17
|
-
|
16
|
+
tagged_message = case
|
17
|
+
when msg.is_a?(Hash) then tags_text.present? ? msg.merge(tags: tags_text) : msg
|
18
|
+
when tags_text.present? then { message: msg, tag: tags_text }
|
18
19
|
else msg
|
19
20
|
end
|
20
21
|
|
@@ -1,9 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
2
|
module Istox
|
4
3
|
module Logging
|
5
4
|
class LogFormatter
|
6
|
-
def call(severity,
|
5
|
+
def call(severity, time, progname, msg='')
|
7
6
|
return '' if msg.blank?
|
8
7
|
|
9
8
|
hash = {
|
@@ -11,9 +10,11 @@ module Istox
|
|
11
10
|
message: processed_message(msg)
|
12
11
|
}
|
13
12
|
|
14
|
-
|
13
|
+
if progname.present?
|
14
|
+
hash[:app] = progname
|
15
|
+
end
|
15
16
|
|
16
|
-
hash.to_json + "\n"
|
17
|
+
return hash.to_json + "\n"
|
17
18
|
|
18
19
|
# return "timestamp='#{time}' level=#{severity} progname='#{progname}' #{processed_message(msg)}\n" if progname.present?
|
19
20
|
# "timestamp='#{time}' level=#{severity} #{processed_message(msg)}\n"
|
@@ -1,26 +1,27 @@
|
|
1
1
|
module Istox
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
class CreateBlockchainReceipts < ActiveRecord::Migration[5.0]
|
3
|
+
def initialize(_, _, table_name = nil)
|
4
|
+
@table_name = table_name
|
5
|
+
unless @table_name
|
6
|
+
@table_name = :blockchain_receipts
|
7
|
+
end
|
8
|
+
end
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
10
|
+
def change
|
11
|
+
create_table @table_name do |t|
|
12
|
+
t.string :txid
|
13
|
+
t.string :txhash
|
14
|
+
t.integer :resource_id
|
15
|
+
t.string :resource_action
|
16
|
+
t.string :resource_name
|
17
|
+
t.boolean :resource_handled
|
18
|
+
t.datetime :deleted_at, index: true
|
19
|
+
t.timestamps
|
20
|
+
t.string :sid
|
21
|
+
t.string :status, :default => "pending"
|
22
|
+
t.boolean :is_request, :default => false
|
23
|
+
t.integer :lock_version
|
24
|
+
end
|
25
|
+
end
|
24
26
|
end
|
25
|
-
|
26
|
-
end
|
27
|
+
end
|
@@ -2,8 +2,11 @@ module Istox
|
|
2
2
|
class BlockchainReceipt < ActiveRecord::Base
|
3
3
|
acts_as_paranoid
|
4
4
|
|
5
|
+
|
5
6
|
def activity
|
6
|
-
|
7
|
+
if resource_name.present? && resource_action.present?
|
8
|
+
I18n.t("#{resource_name}.#{resource_action}")
|
9
|
+
end
|
7
10
|
end
|
8
11
|
end
|
9
|
-
end
|
12
|
+
end
|
@@ -1,31 +1,45 @@
|
|
1
1
|
module Istox
|
2
2
|
module BlockchainReceiptQuery
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
#
|
6
|
-
def handle_confirm(
|
4
|
+
|
5
|
+
#overrideable, when blockchain transaction has confirmed
|
6
|
+
def handle_confirm(resource_action)
|
7
7
|
self
|
8
8
|
end
|
9
9
|
|
10
|
-
#
|
11
|
-
def handle_fail(
|
10
|
+
#overrideable, when blockchain transaction has failed
|
11
|
+
def handle_fail(resource_action)
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
15
|
+
#overrideable, extra data that will be published back to frontend
|
16
16
|
def handle_extra
|
17
17
|
nil
|
18
18
|
end
|
19
19
|
|
20
20
|
# outcome of the blockchain transaction, can be "pending" / "confirmed" / "failed"
|
21
21
|
def outcome
|
22
|
-
|
22
|
+
blockchain_receipts = get_blockchain_receipts
|
23
|
+
|
24
|
+
return "confirmed" if blockchain_receipts.empty?
|
25
|
+
|
26
|
+
# return failed state if there is any failed hashes
|
27
|
+
return "failed" if blockchain_receipts.any?{ |r| r.status == 'failed' }
|
23
28
|
|
24
|
-
return
|
29
|
+
# return pending state if there is any pending hashes
|
30
|
+
return "pending" if blockchain_receipts.any?{ |r| r.status == 'pending' }
|
25
31
|
|
26
|
-
return
|
32
|
+
# return confirmed otherwise
|
33
|
+
return "confirmed"
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_blockchain_receipts
|
37
|
+
::Istox::BlockchainReceipt.where(resource_id: self.id, resource_name: self.class.name).all
|
38
|
+
end
|
27
39
|
|
28
|
-
|
40
|
+
def last_receipt
|
41
|
+
::Istox::BlockchainReceipt.where(resource_id: self.id, resource_name: self.class.name).last
|
29
42
|
end
|
43
|
+
|
30
44
|
end
|
31
45
|
end
|
data/lib/istox/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: istox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.81
|
4
|
+
version: 0.1.81
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Siong Leng
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -278,8 +278,6 @@ files:
|
|
278
278
|
- ".idea/modules.xml"
|
279
279
|
- ".idea/vcs.xml"
|
280
280
|
- ".idea/workspace.xml"
|
281
|
-
- ".rubocop.yml"
|
282
|
-
- ".solargraph.yml"
|
283
281
|
- CODE_OF_CONDUCT.md
|
284
282
|
- Gemfile
|
285
283
|
- Gemfile.lock
|
@@ -289,16 +287,15 @@ files:
|
|
289
287
|
- bin/setup
|
290
288
|
- istox.gemspec
|
291
289
|
- lib/istox.rb
|
290
|
+
- lib/istox/consumers/blockchain_hash_handler.rb
|
292
291
|
- lib/istox/consumers/blockchain_status_handler.rb
|
293
|
-
- lib/istox/helpers/
|
292
|
+
- lib/istox/helpers/blockchain_receipt_service.rb
|
294
293
|
- lib/istox/helpers/bunny_boot.rb
|
295
|
-
- lib/istox/helpers/common_helper.rb
|
296
294
|
- lib/istox/helpers/f_math.rb
|
297
295
|
- lib/istox/helpers/graphql_client.rb
|
298
296
|
- lib/istox/helpers/grpc_client.rb
|
299
297
|
- lib/istox/helpers/gruf_listener_hook.rb
|
300
298
|
- lib/istox/helpers/message_service.rb
|
301
|
-
- lib/istox/helpers/my_open_struct.rb
|
302
299
|
- lib/istox/helpers/order_book.rb
|
303
300
|
- lib/istox/helpers/publisher.rb
|
304
301
|
- lib/istox/helpers/vault.rb
|
@@ -324,9 +321,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
324
321
|
version: '0'
|
325
322
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
326
323
|
requirements:
|
327
|
-
- - "
|
324
|
+
- - ">="
|
328
325
|
- !ruby/object:Gem::Version
|
329
|
-
version:
|
326
|
+
version: '0'
|
330
327
|
requirements: []
|
331
328
|
rubygems_version: 3.0.6
|
332
329
|
signing_key:
|
data/.rubocop.yml
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
require: rubocop-rspec
|
2
|
-
|
3
|
-
AllCops:
|
4
|
-
TargetRubyVersion: 2.5
|
5
|
-
Exclude:
|
6
|
-
- .gems/**/*
|
7
|
-
- bin/**/*
|
8
|
-
- config/**/*
|
9
|
-
- db/**/*
|
10
|
-
- log/**/*
|
11
|
-
- public/**/*
|
12
|
-
- tmp/**/*
|
13
|
-
- vendor/**/*
|
14
|
-
- spec/rails_helper.rb
|
15
|
-
- spec/spec_helper.rb
|
16
|
-
- config.ru
|
17
|
-
- Guardfile
|
18
|
-
- Rakefile
|
19
|
-
|
20
|
-
Documentation:
|
21
|
-
Enabled: false
|
22
|
-
|
23
|
-
Layout/SpaceBeforeFirstArg:
|
24
|
-
Exclude:
|
25
|
-
- app/views/api/**/**/*
|
26
|
-
|
27
|
-
Lint/AmbiguousBlockAssociation:
|
28
|
-
Exclude:
|
29
|
-
- spec/**/*
|
30
|
-
|
31
|
-
Metrics/AbcSize:
|
32
|
-
# The ABC size is a calculated magnitude, so this number can be an Integer or
|
33
|
-
# a Float.
|
34
|
-
Max: 100
|
35
|
-
|
36
|
-
Metrics/BlockLength:
|
37
|
-
CountComments: false # count full line comments?
|
38
|
-
Max: 25
|
39
|
-
Exclude:
|
40
|
-
- config/**/*
|
41
|
-
- spec/**/*
|
42
|
-
- app/admin/**/*
|
43
|
-
|
44
|
-
Metrics/BlockNesting:
|
45
|
-
Max: 4
|
46
|
-
|
47
|
-
Metrics/ClassLength:
|
48
|
-
CountComments: false # count full line comments?
|
49
|
-
Max: 200
|
50
|
-
|
51
|
-
# Avoid complex methods.
|
52
|
-
Metrics/CyclomaticComplexity:
|
53
|
-
Max: 20
|
54
|
-
|
55
|
-
Metrics/MethodLength:
|
56
|
-
CountComments: false # count full line comments?
|
57
|
-
Max: 100
|
58
|
-
|
59
|
-
Metrics/ModuleLength:
|
60
|
-
CountComments: false # count full line comments?
|
61
|
-
Max: 200
|
62
|
-
|
63
|
-
Metrics/LineLength:
|
64
|
-
Max: 130
|
65
|
-
# To make it possible to copy or click on URIs in the code, we allow lines
|
66
|
-
# containing a URI to be longer than Max.
|
67
|
-
AllowURI: true
|
68
|
-
URISchemes:
|
69
|
-
- http
|
70
|
-
- https
|
71
|
-
|
72
|
-
Metrics/ParameterLists:
|
73
|
-
Max: 5
|
74
|
-
CountKeywordArgs: true
|
75
|
-
|
76
|
-
Metrics/PerceivedComplexity:
|
77
|
-
Max: 12
|
78
|
-
|
79
|
-
Style/FrozenStringLiteralComment:
|
80
|
-
Enabled: false
|
81
|
-
|
82
|
-
Style/ModuleFunction:
|
83
|
-
Enabled: false
|
84
|
-
|
85
|
-
RSpec/MultipleExpectations:
|
86
|
-
Max: 99
|
87
|
-
|
88
|
-
RSpec/ExampleLength:
|
89
|
-
Max: 100
|
90
|
-
|
91
|
-
Lint/BigDecimalNew:
|
92
|
-
Enabled: false
|
93
|
-
|
94
|
-
|
95
|
-
RSpec/MessageSpies:
|
96
|
-
Enabled: false
|
97
|
-
|
98
|
-
RSpec/AnyInstance:
|
99
|
-
Enabled: false
|
100
|
-
|
101
|
-
RSpec/VerifiedDoubles:
|
102
|
-
Enabled: false
|
data/.solargraph.yml
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
module Istox
|
2
|
-
class BlockchainService
|
3
|
-
def self.init(blockchain_receipt_klass)
|
4
|
-
@@blockchain_receipt_klass = blockchain_receipt_klass
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.get_blockchain_receipt_klass
|
8
|
-
@@blockchain_receipt_klass
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.request(sid:, action:, before:, execute:)
|
12
|
-
start(sid: sid, action: action, before: before, execute: execute, is_request: true)
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.run(sid:, action:, before:, execute:)
|
16
|
-
start(sid: sid, action: action, before: before, execute: execute)
|
17
|
-
end
|
18
|
-
class << self
|
19
|
-
private
|
20
|
-
|
21
|
-
# before is the proc that will be executed before, must return the main model blockchain receipt will bind to
|
22
|
-
def start(sid:, action:, before:, execute:, is_request: false)
|
23
|
-
# create blockchain receipt first
|
24
|
-
klass = blockchain_receipt_class
|
25
|
-
uuid = ::SecureRandom.uuid
|
26
|
-
@receipt = klass.create!(
|
27
|
-
txid: uuid,
|
28
|
-
sid: sid,
|
29
|
-
is_request: is_request,
|
30
|
-
resource_action: action
|
31
|
-
)
|
32
|
-
|
33
|
-
::ActiveRecord::Base.transaction do
|
34
|
-
# execute before proc, and get the model that blockchain receipt should bind to
|
35
|
-
model = before.call(uuid)
|
36
|
-
|
37
|
-
# delete the previous existing blockchain receipts
|
38
|
-
klass.where(resource_name: model.class.name, resource_id: model.id).destroy_all
|
39
|
-
|
40
|
-
# then update receipt
|
41
|
-
@receipt.update!(resource_id: model.id, resource_name: model.class.name)
|
42
|
-
|
43
|
-
# execute the actual call to chainhub
|
44
|
-
execute.call(uuid)
|
45
|
-
end
|
46
|
-
rescue StandardError => e
|
47
|
-
@receipt&.destroy
|
48
|
-
raise e
|
49
|
-
end
|
50
|
-
|
51
|
-
def blockchain_receipt_class
|
52
|
-
raise 'Have you forgetten to init blockchain receipt service?' if get_blockchain_receipt_klass.nil?
|
53
|
-
|
54
|
-
blockchain_receipt_klass = get_blockchain_receipt_klass
|
55
|
-
klass = class_eval("::#{blockchain_receipt_klass.name}", __FILE__, __LINE__)
|
56
|
-
unless klass <= ::Istox::BlockchainReceipt
|
57
|
-
raise "#{blockchain_receipt_klass.name} does not inherit istox blockchain receipt"
|
58
|
-
end
|
59
|
-
|
60
|
-
klass
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Istox
|
2
|
-
module CommonHelper
|
3
|
-
def self.to_open_struct(model)
|
4
|
-
return nil if model.blank?
|
5
|
-
|
6
|
-
if model.is_a?(Array)
|
7
|
-
model.map do |item|
|
8
|
-
hash = deep_to_h(item).deep_transform_keys { |key| key.to_s.underscore.to_sym }
|
9
|
-
to_recursive_ostruct(hash)
|
10
|
-
end
|
11
|
-
else
|
12
|
-
hash = deep_to_h(model).deep_transform_keys { |key| key.to_s.underscore.to_sym }
|
13
|
-
to_recursive_ostruct(hash)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.to_recursive_ostruct(obj)
|
18
|
-
if obj.is_a?(Hash)
|
19
|
-
::Istox::MyOpenStruct.new(obj.map { |key, val| [key, to_recursive_ostruct(val)] }.to_h)
|
20
|
-
elsif obj.is_a?(Array)
|
21
|
-
obj.map { |o| to_recursive_ostruct(o) }
|
22
|
-
elsif obj.is_a?(OpenStruct)
|
23
|
-
::Istox::MyOpenStruct.new(obj)
|
24
|
-
else # Assumed to be a primitive value
|
25
|
-
obj
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.deep_to_h(obj)
|
30
|
-
if obj.is_a?(Array)
|
31
|
-
obj.map { |r| deep_to_h(r) }
|
32
|
-
elsif obj.is_a?(OpenStruct) || obj.is_a?(Hash) || (obj.methods.include?(:to_h) && obj.present?)
|
33
|
-
obj.to_h.transform_values do |v|
|
34
|
-
if v.is_a?(OpenStruct) || v.is_a?(Array)
|
35
|
-
deep_to_h(v)
|
36
|
-
else
|
37
|
-
v
|
38
|
-
end
|
39
|
-
end
|
40
|
-
else
|
41
|
-
obj
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|