istox 0.1.81 → 0.1.82
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/.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
|