istox 0.1.81 → 0.1.82
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +102 -0
- data/.solargraph.yml +14 -0
- data/Gemfile.lock +1 -1
- data/lib/istox.rb +23 -22
- data/lib/istox/consumers/blockchain_status_handler.rb +47 -106
- data/lib/istox/helpers/blockchain_service.rb +64 -0
- data/lib/istox/helpers/common_helper.rb +45 -0
- data/lib/istox/helpers/f_math.rb +16 -19
- data/lib/istox/helpers/graphql_client.rb +29 -29
- data/lib/istox/helpers/grpc_client.rb +51 -54
- data/lib/istox/helpers/my_open_struct.rb +13 -0
- data/lib/istox/helpers/order_book.rb +68 -40
- data/lib/istox/logging/hash_logging.rb +2 -3
- data/lib/istox/logging/log_formatter.rb +4 -5
- data/lib/istox/migrations/create_blockchain_receipts.rb +23 -24
- data/lib/istox/models/blockchain_receipt.rb +2 -5
- data/lib/istox/models/concerns/blockchain_receipt_query.rb +10 -24
- data/lib/istox/version.rb +1 -1
- metadata +7 -4
- data/lib/istox/consumers/blockchain_hash_handler.rb +0 -19
- data/lib/istox/helpers/blockchain_receipt_service.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 143b2d10bf2308d6fa9600f98b27c2e4da90c7cc92c18f3fca1cadf4c0e1998e
|
4
|
+
data.tar.gz: 0cad5b15227ba33e92c097a796038a6a931c9a2754ef4ea76f32c9de9c6a0580
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46dc524ec7f211533dc1ecccb7825391d78afcfc2b3fb687a418772ca257c8a0f8ee7681ed124b2bfda798bce998d62f0ed611edbeb65455784fae89d1d92494
|
7
|
+
data.tar.gz: 7095b75a70ab832b522b135027206529f16dd11f34fb4838d0334d55e83313a878851459825e51171fd79a669b84c02f6e0c1f8883efef12b056462cbd880c11
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,102 @@
|
|
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
ADDED
data/Gemfile.lock
CHANGED
data/lib/istox.rb
CHANGED
@@ -1,34 +1,35 @@
|
|
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
|
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_service'
|
25
|
+
require 'istox/helpers/f_math'
|
26
|
+
require 'istox/helpers/my_open_struct'
|
27
|
+
require 'istox/helpers/common_helper'
|
28
|
+
require 'istox/models/blockchain_receipt'
|
29
|
+
require 'istox/models/concerns/blockchain_receipt_query'
|
30
|
+
require 'istox/consumers/blockchain_status_handler'
|
31
|
+
require 'istox/migrations/create_blockchain_receipts'
|
32
|
+
require 'istox/logging/hash_logging'
|
33
|
+
require 'istox/logging/log_formatter'
|
33
34
|
require "istox/quant/bond"
|
34
35
|
end
|
@@ -1,105 +1,54 @@
|
|
1
1
|
module Istox
|
2
2
|
class BlockchainStatusHandler
|
3
3
|
class << self
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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)
|
33
|
-
|
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
|
42
|
-
|
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
|
43
19
|
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
20
|
|
60
|
-
|
61
|
-
receipt = ::Istox::BlockchainReceipt.where(txhash: transaction.id, txid: transaction.uuid).first
|
21
|
+
status = transaction.success ? 'confirmed' : 'failed'
|
62
22
|
|
63
|
-
|
64
|
-
|
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
|
23
|
+
receipt.update!(status: status, message: transaction.message,
|
24
|
+
txhash: transaction.txnHashes.present? ? transaction.txnHashes.join(',') : nil)
|
72
25
|
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
+
end
|
76
32
|
|
77
|
-
|
78
|
-
# next if resource.outcome == 'pending'
|
33
|
+
return if resource_handled?(receipt)
|
79
34
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
# mark_resource_handled(receipt_list)
|
84
|
-
# publish_to_frontend(resource, true, receipt, receipt.sid, receipt_list)
|
85
|
-
# end
|
86
|
-
# end
|
35
|
+
if status == 'confirmed'
|
36
|
+
resource.handle_confirm(receipt)
|
87
37
|
|
88
|
-
|
89
|
-
|
38
|
+
mark_resource_handled(receipt)
|
39
|
+
publish_to_frontend(resource, true, receipt, receipt.sid)
|
90
40
|
|
91
|
-
|
92
|
-
|
93
|
-
end
|
41
|
+
elsif status == 'failed'
|
42
|
+
resource.handle_fail(receipt)
|
94
43
|
|
44
|
+
mark_resource_handled(receipt)
|
45
|
+
publish_to_frontend(resource, false, receipt, receipt.sid)
|
95
46
|
end
|
96
47
|
end
|
97
48
|
|
98
49
|
private
|
99
50
|
|
100
|
-
def publish_to_frontend(model, success, receipt, sid
|
101
|
-
yield if block_given?
|
102
|
-
|
51
|
+
def publish_to_frontend(model, success, receipt, sid)
|
103
52
|
::Istox::Publisher.publish(
|
104
53
|
'amq.topic',
|
105
54
|
model.class.name.gsub('::', '').underscore.to_s,
|
@@ -115,34 +64,26 @@ module Istox
|
|
115
64
|
data: {
|
116
65
|
success: success,
|
117
66
|
purpose: receipt.activity,
|
118
|
-
|
67
|
+
message: receipt.message
|
119
68
|
}
|
120
69
|
)
|
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
|
121
74
|
end
|
122
75
|
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
76
|
+
def mark_resource_handled(receipt)
|
77
|
+
receipt.update(resource_handled: true)
|
78
|
+
rescue StandardError => e
|
79
|
+
Rails.logger.error "Unable to update resource_handled for receipt #{receipt.inspect},
|
80
|
+
but will silently ignore the error"
|
81
|
+
Rails.logger.error e
|
127
82
|
end
|
128
83
|
|
129
|
-
def
|
130
|
-
|
131
|
-
receipt.update(resource_handled: true)
|
132
|
-
end
|
84
|
+
def resource_handled?(receipt)
|
85
|
+
receipt.resource_handled == true
|
133
86
|
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
|
-
|
146
87
|
end
|
147
88
|
end
|
148
89
|
end
|
@@ -0,0 +1,64 @@
|
|
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
|
@@ -0,0 +1,45 @@
|
|
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
|
data/lib/istox/helpers/f_math.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
+
# rubocop:disable Naming/UncommunicativeMethodParamName
|
1
2
|
module Istox
|
2
3
|
class FMath
|
3
4
|
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
|
-
|
14
|
+
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
|
-
|
26
|
+
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
|
-
|
38
|
+
x.mult(y, 100).truncate(18).to_s
|
39
39
|
end
|
40
40
|
|
41
41
|
def div(x, y)
|
@@ -47,19 +47,17 @@ module Istox
|
|
47
47
|
x = to_fixed(x)
|
48
48
|
y = to_fixed(y)
|
49
49
|
|
50
|
-
return ::BigDecimal.new(
|
50
|
+
return ::BigDecimal.new('1').to_s if x == y
|
51
|
+
|
52
|
+
fixed1 = ::BigDecimal.new('1e18')
|
51
53
|
|
52
|
-
|
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
|
54
|
+
return from_fixed(x.div(y, 100).mult(fixed1, 100)).to_s if x.div(y, 100).modulo(BigDecimal.new(10)).zero? && x.modulo(y).zero?
|
57
55
|
|
58
|
-
r_y =
|
56
|
+
r_y = fixed1.mult(fixed1, 100).truncate(0).div(y, 100).truncate(0)
|
59
57
|
|
60
|
-
result = from_fixed(x.mult(r_y, 100).truncate(0).div(
|
58
|
+
result = from_fixed(x.mult(r_y, 100).truncate(0).div(fixed1, 100).truncate(0))
|
61
59
|
|
62
|
-
|
60
|
+
result.truncate(18).to_s
|
63
61
|
end
|
64
62
|
|
65
63
|
def round_up(x, digits)
|
@@ -67,24 +65,23 @@ module Istox
|
|
67
65
|
x = 0 if x.blank?
|
68
66
|
::BigDecimal.new(x.to_s).round(digits).to_s
|
69
67
|
end
|
70
|
-
|
68
|
+
|
71
69
|
def round_down(x, digits)
|
72
70
|
BigDecimal.mode(BigDecimal::ROUND_MODE, :down)
|
73
71
|
x = 0 if x.blank?
|
74
72
|
::BigDecimal.new(x.to_s).round(digits).to_s
|
75
73
|
end
|
76
74
|
|
77
|
-
private
|
75
|
+
private
|
78
76
|
|
79
77
|
def to_fixed(x)
|
80
|
-
|
78
|
+
::BigDecimal.new(x.to_s).mult(::BigDecimal.new('1e18'), 100).truncate(18)
|
81
79
|
end
|
82
80
|
|
83
81
|
def from_fixed(x)
|
84
|
-
|
82
|
+
::BigDecimal.new(x.to_s).div(::BigDecimal.new('1e18'), 100).truncate(18)
|
85
83
|
end
|
86
|
-
|
87
|
-
|
88
84
|
end
|
89
85
|
end
|
90
86
|
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
|
-
|
30
|
-
@@hosts[host_type] = client
|
31
|
-
end
|
5
|
+
class << self
|
6
|
+
def add_host(host_type, url)
|
7
|
+
@@hosts = {} unless defined?(@@hosts)
|
8
|
+
init_host(host_type, url)
|
9
|
+
end
|
10
|
+
|
11
|
+
def query(host_type, query, variables = {})
|
12
|
+
client = @@hosts[host_type]
|
13
|
+
|
14
|
+
raise "Please make sure you have initialised graphql cient for host #{host_type}" unless client
|
15
|
+
|
16
|
+
Rails.logger.info "Querying Graphql host: #{host_type}, query: #{query}, variables: #{variables.inspect}"
|
17
|
+
result = client.query(query, variables)
|
18
|
+
|
19
|
+
return_values = ::Istox::CommonHelper.to_open_struct(result&.data)
|
20
|
+
|
21
|
+
Rails.logger.info "Graphql result: #{return_values.inspect}"
|
22
|
+
|
23
|
+
return_values
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def init_host(host_type, url)
|
29
|
+
client = Graphlient::Client.new(url, http: Graphlient::Adapters::HTTP::HTTPAdapter)
|
32
30
|
|
31
|
+
@@hosts[host_type] = client
|
33
32
|
end
|
33
|
+
end
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
@@ -1,66 +1,63 @@
|
|
1
1
|
module Istox
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@@hosts = {}
|
7
|
-
end
|
2
|
+
class GrpcClient
|
3
|
+
class << self
|
4
|
+
def add_host(host_type, url)
|
5
|
+
@@hosts = {} unless defined?(@@hosts)
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
@@hosts[host_type] = url
|
8
|
+
end
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
private
|
10
|
+
def call(host_type, service, method, **keyword_args)
|
11
|
+
execute(host_type, service, method, **keyword_args)
|
12
|
+
# rescue => e
|
13
|
+
# reinitiate service and try again, second chance
|
14
|
+
# reinitiate_service(host_type, service)
|
15
|
+
# execute(host_type, service, method, **keyword_args)
|
16
|
+
end
|
21
17
|
|
22
|
-
|
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
|
18
|
+
private
|
31
19
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
20
|
+
def execute(host_type, service, method, **keyword_args)
|
21
|
+
Rails.logger.info "Calling method in grpc method: #{method.inspect}, params: #{keyword_args.inspect}"
|
22
|
+
t1 = Time.now
|
36
23
|
|
37
|
-
|
24
|
+
result = get_host(host_type, service).call(method, keyword_args)
|
25
|
+
Rails.logger.info "Time taken for grpc execution: #{Time.now - t1} seconds"
|
38
26
|
|
39
|
-
|
40
|
-
|
41
|
-
else
|
42
|
-
reinitiate_service(host_type, service)
|
43
|
-
return @@services[get_key(host_type, service)]
|
44
|
-
end
|
45
|
-
end
|
27
|
+
return_values = ::Istox::CommonHelper.to_open_struct(result.message)
|
28
|
+
Rails.logger.info "Result: #{return_values}"
|
46
29
|
|
47
|
-
|
48
|
-
|
49
|
-
@@services = {}
|
50
|
-
end
|
30
|
+
return_values
|
31
|
+
end
|
51
32
|
|
52
|
-
|
53
|
-
|
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
|
33
|
+
def get_host(host_type, service)
|
34
|
+
@@services = {} unless defined?(@@services)
|
60
35
|
|
61
|
-
|
62
|
-
|
63
|
-
|
36
|
+
grpc_client = @@services[get_key(host_type, service)]
|
37
|
+
|
38
|
+
if grpc_client
|
39
|
+
return grpc_client
|
40
|
+
else
|
41
|
+
reinitiate_service(host_type, service)
|
42
|
+
return @@services[get_key(host_type, service)]
|
64
43
|
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
|
65
61
|
end
|
66
|
-
end
|
62
|
+
end
|
63
|
+
end
|
@@ -2,7 +2,6 @@ module Istox
|
|
2
2
|
class OrderBook
|
3
3
|
class << self
|
4
4
|
def allocation(soft_cap, total_supply, investments)
|
5
|
-
|
6
5
|
# sort by token price desc, and id asc
|
7
6
|
investments = investments.sort do |a, b|
|
8
7
|
[b[:token_price], a[:id]] <=> [a[:token_price], b[:id]]
|
@@ -11,50 +10,79 @@ module Istox
|
|
11
10
|
total_supply = ::BigDecimal.new(total_supply.to_s)
|
12
11
|
|
13
12
|
interests = investments
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
is_cutoff = false
|
13
|
+
cutoff_price = 0.0
|
14
|
+
total_bid_token = 0.0
|
15
|
+
total_allocated = 0.0
|
16
|
+
total_unallocated = 0.0
|
17
|
+
total_investment = 0.0
|
18
|
+
cutoff_price = ::Istox::FMath.round_up(::Istox::FMath.div(soft_cap, total_supply), 2)
|
19
|
+
is_cutoff = false
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
21
|
+
# return result immediately if no interest
|
22
|
+
unless interests.count.positive?
|
23
|
+
return { total_supply: total_supply.to_s, total_investment: '0',
|
24
|
+
cutoff_price: cutoff_price, total_bid_token: '0',
|
25
|
+
total_allocated: '0', total_unallocated: total_supply.to_s,
|
26
|
+
interests: [] }
|
27
|
+
end
|
28
|
+
|
29
|
+
interests = interests.map do |item|
|
30
|
+
bid_token = ::Istox::FMath.div(item[:fiat_amount], item[:token_price])
|
31
|
+
total_bid_token = ::Istox::FMath.add(total_bid_token, bid_token)
|
32
|
+
allocated = 0.0
|
33
|
+
unallocated = bid_token
|
34
|
+
unless is_cutoff
|
35
|
+
allocated = bid_token
|
36
|
+
unallocated = 0.0
|
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
|
39
42
|
end
|
40
|
-
|
41
|
-
|
43
|
+
total_allocated = ::Istox::FMath.add(total_allocated, allocated)
|
44
|
+
total_unallocated = ::Istox::FMath.add(total_unallocated, unallocated)
|
42
45
|
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
|
43
60
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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'
|
61
|
+
interests = interests.map do |item|
|
62
|
+
investment = ::Istox::FMath.mul(item[:allocated], cutoff_price)
|
63
|
+
total_investment = ::Istox::FMath.add(total_investment, investment)
|
64
|
+
|
65
|
+
# each user maximum total investment amount in fiat
|
66
|
+
item.merge!(investment: investment)
|
56
67
|
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
|
+
}
|
57
85
|
end
|
58
86
|
end
|
59
87
|
end
|
60
|
-
end
|
88
|
+
end
|
@@ -13,9 +13,8 @@ module Istox
|
|
13
13
|
include ActiveSupport::TaggedLogging::Formatter
|
14
14
|
|
15
15
|
def call(severity, timestamp, progname, msg)
|
16
|
-
tagged_message =
|
17
|
-
|
18
|
-
when tags_text.present? then { message: msg, tag: tags_text }
|
16
|
+
tagged_message = if msg.is_a?(Hash) then tags_text.present? ? msg.merge(tags: tags_text) : msg
|
17
|
+
elsif tags_text.present? then { message: msg, tag: tags_text }
|
19
18
|
else msg
|
20
19
|
end
|
21
20
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Istox
|
3
4
|
module Logging
|
4
5
|
class LogFormatter
|
5
|
-
def call(severity,
|
6
|
+
def call(severity, _time, progname, msg = '')
|
6
7
|
return '' if msg.blank?
|
7
8
|
|
8
9
|
hash = {
|
@@ -10,11 +11,9 @@ module Istox
|
|
10
11
|
message: processed_message(msg)
|
11
12
|
}
|
12
13
|
|
13
|
-
if progname.present?
|
14
|
-
hash[:app] = progname
|
15
|
-
end
|
14
|
+
hash[:app] = progname if progname.present?
|
16
15
|
|
17
|
-
|
16
|
+
hash.to_json + "\n"
|
18
17
|
|
19
18
|
# return "timestamp='#{time}' level=#{severity} progname='#{progname}' #{processed_message(msg)}\n" if progname.present?
|
20
19
|
# "timestamp='#{time}' level=#{severity} #{processed_message(msg)}\n"
|
@@ -1,27 +1,26 @@
|
|
1
1
|
module Istox
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
end
|
2
|
+
class CreateBlockchainReceipts < ActiveRecord::Migration[5.0]
|
3
|
+
def initialize(_, _, table_name = nil)
|
4
|
+
@table_name = table_name
|
5
|
+
@table_name ||= :blockchain_receipts
|
6
|
+
end
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
8
|
+
def change
|
9
|
+
create_table @table_name do |t|
|
10
|
+
t.string :txid
|
11
|
+
t.string :txhash
|
12
|
+
t.integer :resource_id
|
13
|
+
t.string :resource_action
|
14
|
+
t.string :resource_name
|
15
|
+
t.boolean :resource_handled
|
16
|
+
t.datetime :deleted_at, index: true
|
17
|
+
t.timestamps
|
18
|
+
t.string :sid
|
19
|
+
t.string :status, default: 'pending'
|
20
|
+
t.text :message
|
21
|
+
t.boolean :is_request, default: false
|
22
|
+
t.integer :lock_version
|
23
|
+
end
|
26
24
|
end
|
27
|
-
end
|
25
|
+
end
|
26
|
+
end
|
@@ -2,11 +2,8 @@ module Istox
|
|
2
2
|
class BlockchainReceipt < ActiveRecord::Base
|
3
3
|
acts_as_paranoid
|
4
4
|
|
5
|
-
|
6
5
|
def activity
|
7
|
-
if resource_name.present? && resource_action.present?
|
8
|
-
I18n.t("#{resource_name}.#{resource_action}")
|
9
|
-
end
|
6
|
+
I18n.t("#{resource_name}.#{resource_action}") if resource_name.present? && resource_action.present?
|
10
7
|
end
|
11
8
|
end
|
12
|
-
end
|
9
|
+
end
|
@@ -1,45 +1,31 @@
|
|
1
1
|
module Istox
|
2
2
|
module BlockchainReceiptQuery
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
#overrideable, when blockchain transaction has confirmed
|
6
|
-
def handle_confirm(
|
4
|
+
|
5
|
+
# overrideable, when blockchain transaction has confirmed
|
6
|
+
def handle_confirm(_receipt)
|
7
7
|
self
|
8
8
|
end
|
9
9
|
|
10
|
-
#overrideable, when blockchain transaction has failed
|
11
|
-
def handle_fail(
|
10
|
+
# overrideable, when blockchain transaction has failed
|
11
|
+
def handle_fail(_receipt)
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
|
-
#overrideable, extra data that will be published back to frontend
|
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
|
-
|
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' }
|
22
|
+
blockchain_receipt = ::Istox::BlockchainReceipt.where(resource_id: id, resource_name: self.class.name).first
|
28
23
|
|
29
|
-
|
30
|
-
return "pending" if blockchain_receipts.any?{ |r| r.status == 'pending' }
|
24
|
+
return 'confirmed' unless blockchain_receipt.present?
|
31
25
|
|
32
|
-
|
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
|
26
|
+
return 'confirmed' if blockchain_receipt.status.blank?
|
39
27
|
|
40
|
-
|
41
|
-
::Istox::BlockchainReceipt.where(resource_id: self.id, resource_name: self.class.name).last
|
28
|
+
blockchain_receipt.status
|
42
29
|
end
|
43
|
-
|
44
30
|
end
|
45
31
|
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.
|
4
|
+
version: 0.1.82
|
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-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bunny
|
@@ -278,6 +278,8 @@ files:
|
|
278
278
|
- ".idea/modules.xml"
|
279
279
|
- ".idea/vcs.xml"
|
280
280
|
- ".idea/workspace.xml"
|
281
|
+
- ".rubocop.yml"
|
282
|
+
- ".solargraph.yml"
|
281
283
|
- CODE_OF_CONDUCT.md
|
282
284
|
- Gemfile
|
283
285
|
- Gemfile.lock
|
@@ -287,15 +289,16 @@ files:
|
|
287
289
|
- bin/setup
|
288
290
|
- istox.gemspec
|
289
291
|
- lib/istox.rb
|
290
|
-
- lib/istox/consumers/blockchain_hash_handler.rb
|
291
292
|
- lib/istox/consumers/blockchain_status_handler.rb
|
292
|
-
- lib/istox/helpers/
|
293
|
+
- lib/istox/helpers/blockchain_service.rb
|
293
294
|
- lib/istox/helpers/bunny_boot.rb
|
295
|
+
- lib/istox/helpers/common_helper.rb
|
294
296
|
- lib/istox/helpers/f_math.rb
|
295
297
|
- lib/istox/helpers/graphql_client.rb
|
296
298
|
- lib/istox/helpers/grpc_client.rb
|
297
299
|
- lib/istox/helpers/gruf_listener_hook.rb
|
298
300
|
- lib/istox/helpers/message_service.rb
|
301
|
+
- lib/istox/helpers/my_open_struct.rb
|
299
302
|
- lib/istox/helpers/order_book.rb
|
300
303
|
- lib/istox/helpers/publisher.rb
|
301
304
|
- lib/istox/helpers/vault.rb
|
@@ -1,19 +0,0 @@
|
|
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,71 +0,0 @@
|
|
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
|