radiator 0.4.4 → 0.4.8.pre.1

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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +90 -6
  3. data/Rakefile +50 -20
  4. data/lib/radiator.rb +7 -1
  5. data/lib/radiator/api.rb +105 -14
  6. data/lib/radiator/bridge.rb +34 -0
  7. data/lib/radiator/chain_config.rb +9 -2
  8. data/lib/radiator/database_api.rb +1 -1
  9. data/lib/radiator/follow_api.rb +1 -1
  10. data/lib/radiator/market_history_api.rb +1 -1
  11. data/lib/radiator/operation.rb +3 -2
  12. data/lib/radiator/operation_types.rb +43 -27
  13. data/lib/radiator/ssc/base_steem_smart_contract_rpc.rb +147 -0
  14. data/lib/radiator/ssc/blockchain.rb +57 -0
  15. data/lib/radiator/ssc/contracts.rb +88 -0
  16. data/lib/radiator/ssc/stream.rb +62 -0
  17. data/lib/radiator/stream.rb +15 -6
  18. data/lib/radiator/transaction.rb +41 -1
  19. data/lib/radiator/type/amount.rb +26 -50
  20. data/lib/radiator/type/beneficiaries.rb +8 -1
  21. data/lib/radiator/type/price.rb +2 -2
  22. data/lib/radiator/version.rb +1 -1
  23. data/radiator.gemspec +15 -12
  24. data/test/fixtures/empty.json +1 -0
  25. data/test/fixtures/error.json +29 -0
  26. data/test/fixtures/follow_api_get_followers.json +1 -0
  27. data/test/fixtures/get_account.json +165 -0
  28. data/test/fixtures/get_account_count.json +1 -0
  29. data/test/fixtures/get_account_references.json +1 -0
  30. data/test/fixtures/get_block.json +193 -0
  31. data/test/fixtures/get_dynamic_global_properties.json +32 -0
  32. data/test/fixtures/get_feed_history.json +684 -0
  33. data/test/fixtures/get_hardfork_version.json +1 -0
  34. data/test/fixtures/get_key_references.json +14 -0
  35. data/test/fixtures/get_stats_for_time.json +57 -0
  36. data/test/fixtures/get_vesting_delegation.json +936 -0
  37. data/test/fixtures/golos_get_dynamic_global_properties.json +32 -0
  38. data/test/fixtures/market_history_api_get_market_history_buckets.json +1 -0
  39. data/test/fixtures/market_history_api_get_order_book.json +109 -0
  40. data/test/fixtures/market_history_api_get_recent_trades.json +55 -0
  41. data/test/fixtures/market_history_api_get_ticker.json +11 -0
  42. data/test/fixtures/market_history_api_get_volume.json +1 -0
  43. data/test/fixtures/null.json +1 -0
  44. data/test/fixtures/vcr_cassettes/account_by_key_api_all_methods.yml +525 -0
  45. data/test/fixtures/vcr_cassettes/account_by_key_api_jsonrpc.yml +52 -0
  46. data/test/fixtures/vcr_cassettes/all_methods.yml +18155 -0
  47. data/test/fixtures/vcr_cassettes/api_all_methods.yml +13254 -0
  48. data/test/fixtures/vcr_cassettes/base_per_debt.yml +4946 -0
  49. data/test/fixtures/vcr_cassettes/base_per_mvest.yml +3969 -0
  50. data/test/fixtures/vcr_cassettes/block_time.yml +3322 -0
  51. data/test/fixtures/vcr_cassettes/broadcast_transaction.yml +1186 -0
  52. data/test/fixtures/vcr_cassettes/condenser_all_all_methods.yml +13297 -0
  53. data/test/fixtures/vcr_cassettes/expiration_initialize.yml +3428 -0
  54. data/test/fixtures/vcr_cassettes/find_account.yml +3681 -0
  55. data/test/fixtures/vcr_cassettes/find_block.yml +3589 -0
  56. data/test/fixtures/vcr_cassettes/find_comment.yml +11464 -0
  57. data/test/fixtures/vcr_cassettes/follow_api_jsonrpc.yml +52 -0
  58. data/test/fixtures/vcr_cassettes/get_account_count.yml +575 -0
  59. data/test/fixtures/vcr_cassettes/get_account_references.yml +608 -0
  60. data/test/fixtures/vcr_cassettes/get_accounts.yml +674 -0
  61. data/test/fixtures/vcr_cassettes/get_accounts_no_argument.yml +608 -0
  62. data/test/fixtures/vcr_cassettes/get_dynamic_global_properties.yml +661 -0
  63. data/test/fixtures/vcr_cassettes/get_feed_history.yml +1106 -0
  64. data/test/fixtures/vcr_cassettes/get_hardfork_version.yml +577 -0
  65. data/test/fixtures/vcr_cassettes/get_key_references.yml +987 -0
  66. data/test/fixtures/vcr_cassettes/get_market_history.yml +1043 -0
  67. data/test/fixtures/vcr_cassettes/get_market_history_buckets.yml +1043 -0
  68. data/test/fixtures/vcr_cassettes/get_order_book.yml +1091 -0
  69. data/test/fixtures/vcr_cassettes/get_recent_trades.yml +1043 -0
  70. data/test/fixtures/vcr_cassettes/get_ticker.yml +1047 -0
  71. data/test/fixtures/vcr_cassettes/get_trade_history.yml +1049 -0
  72. data/test/fixtures/vcr_cassettes/get_vesting_delegations.yml +523 -0
  73. data/test/fixtures/vcr_cassettes/get_volume.yml +1051 -0
  74. data/test/fixtures/vcr_cassettes/get_witness_by_account.yml +575 -0
  75. data/test/fixtures/vcr_cassettes/look_up_witnesses.yml +523 -0
  76. data/test/fixtures/vcr_cassettes/market_history_api_all_methods.yml +4373 -0
  77. data/test/fixtures/vcr_cassettes/network_broadcast_api_all_methods.yml +1288 -0
  78. data/test/fixtures/vcr_cassettes/properties.yml +3627 -0
  79. data/test/fixtures/vcr_cassettes/recover_transaction.yml +1099 -0
  80. data/test/fixtures/vcr_cassettes/ssc_blockchain_block_info.yml +92 -0
  81. data/test/fixtures/vcr_cassettes/ssc_blockchain_block_info_invalid.yml +90 -0
  82. data/test/fixtures/vcr_cassettes/ssc_blockchain_latest_block_info.yml +91 -0
  83. data/test/fixtures/vcr_cassettes/ssc_blockchain_transaction_info.yml +92 -0
  84. data/test/fixtures/vcr_cassettes/ssc_contracts_contract.yml +366 -0
  85. data/test/fixtures/vcr_cassettes/ssc_contracts_find.yml +91 -0
  86. data/test/fixtures/vcr_cassettes/ssc_contracts_find_one.yml +89 -0
  87. data/test/fixtures/vcr_cassettes/stream_jsonrpc.yml +8253 -0
  88. data/test/fixtures/vcr_cassettes/transaction_expiration_initialize_nil.yml +3176 -0
  89. data/test/fixtures/vcr_cassettes/transaction_jsonrpc.yml +151 -0
  90. data/test/fixtures/vcr_cassettes/unknown_chain_id.yml +3343 -0
  91. data/test/fixtures/vcr_cassettes/valid_chains.yml +3124 -0
  92. data/test/radiator/account_by_key_api_test.rb +46 -0
  93. data/test/radiator/api_test.rb +135 -0
  94. data/test/radiator/chain_stats_api_test.rb +49 -0
  95. data/test/radiator/chain_test.rb +153 -0
  96. data/test/radiator/condenser_api_test.rb +48 -0
  97. data/test/radiator/follow_api_test.rb +48 -0
  98. data/test/radiator/market_history_api_test.rb +100 -0
  99. data/test/radiator/network_broadcast_api_test.rb +48 -0
  100. data/test/radiator/operation_test.rb +117 -0
  101. data/test/radiator/ssc/blockchain_test.rb +58 -0
  102. data/test/radiator/ssc/contracts_test.rb +65 -0
  103. data/test/radiator/stream_test.rb +48 -0
  104. data/test/radiator/tag_api_test.rb +40 -0
  105. data/test/radiator/transaction_test.rb +755 -0
  106. data/test/test_helper.rb +66 -0
  107. metadata +206 -73
  108. data/.codeclimate.yml +0 -19
  109. data/.gitignore +0 -52
  110. data/.travis.yml +0 -23
  111. data/gource.sh +0 -8
  112. data/images/Anthony Martin.png +0 -0
  113. data/images/Marvin Hofmann.jpg +0 -0
  114. data/images/Marvin Hofmann.png +0 -0
  115. data/lib/steem.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5999a627f1c05a48b41ec3b2cef269ce3a9d9e32f71cc9f33ea8afd18a0e6fc9
4
- data.tar.gz: e0121879ce1fea0eda06f3550988d6ca9393fdcc66a19f8ac10e26f44974fd48
3
+ metadata.gz: 0c7aa2b09067f5b8443c46a49587832b075c29b11e4d002c87a7bc504b6f546a
4
+ data.tar.gz: a46a5d171ca0ed83f865dbdef347a7ec03d4c2e065913edb4b09d85a3bd0ac32
5
5
  SHA512:
6
- metadata.gz: 5499a1b95cabf4931380818280aee212d89d320b20dc98d79cdd943d4f8d05eb59565f1f85ad73fb5f2e585a053f2f55d41ae0c1ed69a1e6b54f14bddf02e1d3
7
- data.tar.gz: 6d8e26c93dcd7176c43f04f37e11821bbebfd13163509fb94a9c6f2f61712b6ea55413c81d57024d7c677e42155325bff42d5720681a42481509ef5b75efcf6a
6
+ metadata.gz: 468b09c3e7ddfac6b1c8f4ea1e82661cb7aa99edd326a64002ff7d4b92ff8d727a2ef4d80bbcd073b1093f992e09de63c8fbb5b00ede4eb048eeabaea5a4942d
7
+ data.tar.gz: 1487e9e0521e6e2e914272fd58adc705beb8f067bef070145e681e510dcae6eeebc5300e90351e903e198797d5bcc7380e849af4a929d0e9ac102c125d245e74
data/README.md CHANGED
@@ -6,9 +6,16 @@
6
6
  [radiator](https://github.com/inertia186/radiator)
7
7
  ========
8
8
 
9
- #### STEEM Ruby API Client
9
+ #### Hive/Steem Ruby API Client
10
10
 
11
- Radiator is an API Client for interaction with the STEEM network using Ruby.
11
+ Radiator is an API Client for interaction with the Hive/Steem network using Ruby.
12
+
13
+ #### Changes in v0.4.5
14
+
15
+ * Added support to query and stream a Steem Smart Contract backed side-chains like Steem Engine.
16
+ * [Blockchain](https://www.rubydoc.info/gems/radiator/0.4.5/Radiator/SSC/Blockchain.html)
17
+ * [Stream](https://www.rubydoc.info/gems/radiator/0.4.5/Radiator/SSC/Stream.html)
18
+ * [Contracts](https://www.rubydoc.info/gems/radiator/0.4.5/Radiator/SSC/Contracts.html)
12
19
 
13
20
  #### Changes in v0.4.0
14
21
 
@@ -116,7 +123,7 @@ If you don't have `bundler`, see the next section.
116
123
 
117
124
  ### Prerequisites
118
125
 
119
- `minimum ruby version: 2.2`
126
+ `minimum ruby version: 2.5`
120
127
 
121
128
  #### Linux
122
129
 
@@ -181,6 +188,63 @@ end
181
188
  "steemzine"]
182
189
  ```
183
190
 
191
+ #### Side Chain Support
192
+
193
+ Steem Smart Contract side-chains are supported by Radiator. The default side-chain is Hive/Steem Engine.
194
+
195
+ This will fetch the latest block from the side-chain ...
196
+
197
+ ```ruby
198
+ rpc = Radiator::SSC::Blockchain.new
199
+ rpc.latest_block_info
200
+ ```
201
+
202
+ This will fetch block 1 ...
203
+
204
+ ```ruby
205
+ rpc.block_info(1)
206
+ ```
207
+
208
+ Or a specific transaction ...
209
+
210
+ ```ruby
211
+ rpc.transaction_info('9d288aab2eb66064dc0d4492cb281512386e2293')
212
+ ```
213
+
214
+ You can also do contract queries. This will look up the `tokens` contract:
215
+
216
+ ```ruby
217
+ rpc = Radiator::SSC::Contracts.new
218
+ rpc.contract('tokens')
219
+ ```
220
+
221
+ This will look up a specific record in a contract result ...
222
+
223
+ ```ruby
224
+ rpc.find_one(
225
+ contract: "tokens",
226
+ table: "balances",
227
+ query: {
228
+ symbol: "STINGY",
229
+ account: "inertia"
230
+ }
231
+ )
232
+ ```
233
+
234
+ Or get multiple results ...
235
+
236
+ ```ruby
237
+ rpc.find(
238
+ contract: "tokens",
239
+ table: "balances",
240
+ query: {
241
+ symbol: "STINGY"
242
+ }
243
+ )
244
+ ```
245
+
246
+
247
+
184
248
  #### Streaming
185
249
 
186
250
  Here's an example of how to use a streaming instance to listen for votes:
@@ -372,6 +436,26 @@ Example of the output:
372
436
  .
373
437
  ```
374
438
 
439
+ #### Side-chain Streaming
440
+
441
+ Streaming side-chain transactions are supported:
442
+
443
+ ```ruby
444
+ # Default side-chain is Hive Engine.
445
+ stream = Radiator::SSC::Stream.new
446
+ stream.transactions do |tx, trx_id|
447
+ puts "[#{trx_id}] #{tx.to_json}"
448
+ end
449
+ ```
450
+
451
+ Even whole side-chain blocks:
452
+
453
+ ```ruby
454
+ stream.blocks do |bk, num|
455
+ puts "[#{num}] #{bk.to_json}"
456
+ end
457
+ ```
458
+
375
459
  #### Transaction Signing
376
460
 
377
461
  Radiator supports transaction signing, so you can use it to vote:
@@ -539,20 +623,20 @@ https://github.com/inertia186/radiator/issues/12
539
623
  * `rake`
540
624
  * To run tests with parallelization and local code coverage:
541
625
  * `HELL_ENABLED=true rake`
542
- * To run a stream test on the live STEEM blockchain with debug logging enabled:
626
+ * To run a stream test on the live Hive/Steem blockchain with debug logging enabled:
543
627
  * `LOG=DEBUG rake test_live_stream`
544
628
 
545
629
  ---
546
630
 
547
631
  <center>
548
- <img src="http://www.steemimg.com/images/2016/08/19/RadiatorCoolingFan-54in-Webfdcb1.png" />
632
+ <img src="https://steemitimages.com/0x0/http://www.steemimg.com/images/2016/08/19/RadiatorCoolingFan-54in-Webfdcb1.png" />
549
633
  </center>
550
634
 
551
635
  See my previous Ruby How To posts in: [#radiator](https://steemit.com/created/radiator) [#ruby](https://steemit.com/created/ruby)
552
636
 
553
637
  ## Get in touch!
554
638
 
555
- If you're using Radiator, I'd love to hear from you. Drop me a line and tell me what you think! I'm @inertia on STEEM.
639
+ If you're using Radiator, I'd love to hear from you. Drop me a line and tell me what you think! I'm @inertia on Hive/Steem.
556
640
 
557
641
  ## License
558
642
 
data/Rakefile CHANGED
@@ -32,18 +32,35 @@ desc 'Tests the ability to broadcast live data. This task broadcasts a claim_re
32
32
  task :test_live_broadcast, [:account, :wif, :chain] do |t, args|
33
33
  account_name = args[:account] || 'social'
34
34
  posting_wif = args[:wif] || '5JrvPrQeBBvCRdjv29iDvkwn3EQYZ9jqfAHzrCyUvfbEbRkrYFC'
35
- chain = args[:chain] || 'steem'
35
+ chain = (args[:chain] || 'steem').to_sym
36
36
  # url = 'https://testnet.steemitdev.com/' # use testnet
37
37
  url = nil # use default
38
38
  options = {chain: chain, wif: posting_wif, url: url}
39
39
  tx = Radiator::Transaction.new(options)
40
- tx.operations << {
41
- type: :claim_reward_balance,
42
- account: account_name,
43
- reward_steem: '0.000 STEEM',
44
- reward_sbd: '0.000 SBD',
45
- reward_vests: '0.000001 VESTS'
46
- }
40
+
41
+ reward_core, reward_debt, reward_vest = case chain
42
+ when :steem then ['0.000 STEEM', '0.000 SBD', '0.000001 VESTS']
43
+ when :hive then ['0.000 HIVE', '0.000 HBD', '0.000001 VESTS']
44
+ end
45
+
46
+ case chain
47
+ when :steem
48
+ tx.operations << {
49
+ type: :claim_reward_balance,
50
+ account: account_name,
51
+ reward_steem: reward_core,
52
+ reward_sbd: reward_debt,
53
+ reward_vests: reward_vest
54
+ }
55
+ when :hive
56
+ tx.operations << {
57
+ type: :claim_reward_balance,
58
+ account: account_name,
59
+ reward_hive: reward_core,
60
+ reward_hbd: reward_debt,
61
+ reward_vests: reward_vest
62
+ }
63
+ end
47
64
 
48
65
  response = tx.process(true)
49
66
  ap response
@@ -51,18 +68,27 @@ task :test_live_broadcast, [:account, :wif, :chain] do |t, args|
51
68
  if !!response.result
52
69
  result = response.result
53
70
 
54
- puts "https://steemd.com/b/#{result[:block_num]}" if !!result[:block_num]
55
- puts "https://steemd.com/tx/#{result[:id]}" if !!result[:id]
71
+ case chain
72
+ when :steem
73
+ puts "https://steemd.com/b/#{result[:block_num]}" if !!result[:block_num]
74
+ puts "https://steemd.com/tx/#{result[:id]}" if !!result[:id]
75
+ when :hive
76
+ puts "https://hiveblocks.com/b/#{result[:block_num]}" if !!result[:block_num]
77
+ puts "https://hiveblocks.com/tx/#{result[:id]}" if !!result[:id]
78
+ else
79
+ puts result
80
+ end
56
81
  end
57
82
  end
58
83
 
59
84
  desc 'Tests the ability to stream live data. defaults: chain = steem; persist = true.'
60
85
  task :test_live_stream, [:chain, :persist] do |t, args|
61
- chain = args[:chain] || 'steem'
86
+ chain = (args[:chain] || 'hive').to_sym
62
87
  persist = (args[:persist] || 'true') == 'true'
63
88
  last_block_number = 0
64
89
  # url = 'https://testnet.steemitdev.com/'
65
- url = nil # use default
90
+ url = chain == :steem ? 'https://api.steemit.com' : 'http://anyx.io'
91
+ # url = nil # use default
66
92
  options = {chain: chain, persist: persist, url: url}
67
93
  total_ops = 0.0
68
94
  total_vops = 0.0
@@ -81,18 +107,22 @@ task :test_live_stream, [:chain, :persist] do |t, args|
81
107
  op_size = o.map(&:size).reduce(0, :+)
82
108
  total_ops += op_size
83
109
 
84
- api.get_ops_in_block(n, true) do |vops, error|
110
+ catch :try_vops do; api.get_ops_in_block(n, true) do |vops, error|
85
111
  if !!error
86
112
  puts "Error on get_ops_in_block for block #{n}"
87
113
  ap error if defined? ap
88
114
  end
89
115
 
90
- puts "Problem: vops is nil!" if vops.nil?
91
-
92
- # Did we reach this point with an unhandled error that wasn't retried?
93
- # If so, vops might be nil and we might need this error to get handled
94
- # instead of checking for vops.nil?.
95
-
116
+ if vops.nil?
117
+ puts "#{n}: #{b.witness}; Problem: vops is nil! Retrying ..."
118
+ sleep 3 # Possibly fall behind a bit and catch up later.
119
+ throw :try_vops
120
+
121
+ # Did we reach this point with an unhandled error that wasn't retried?
122
+ # If so, vops might be nil and we might need this error to get handled
123
+ # instead of checking for vops.nil?.
124
+ end
125
+
96
126
  vop_size = vops.size
97
127
  total_vops += vop_size
98
128
 
@@ -105,7 +135,7 @@ task :test_live_stream, [:chain, :persist] do |t, args|
105
135
  elapsed += Time.now.utc - start
106
136
  count += 1
107
137
  puts "#{n}: #{b.witness}; trx: #{t_size}; op: #{op_size}, vop: #{vop_size} (cumulative vop ratio: #{('%.2f' % (vop_ratio * 100))} %; average #{((elapsed / count) * 1000).to_i}ms)"
108
- end
138
+ end; end
109
139
  else
110
140
  # This should not happen. If it does, there's likely a bug in Radiator.
111
141
 
@@ -1,4 +1,6 @@
1
1
  require 'radiator/version'
2
+ require 'steem'
3
+ require 'hive'
2
4
  require 'json'
3
5
  require 'awesome_print' if ENV['USE_AWESOME_PRINT'] == 'true'
4
6
 
@@ -29,6 +31,7 @@ module Radiator
29
31
  require 'radiator/account_history_api'
30
32
  require 'radiator/condenser_api'
31
33
  require 'radiator/block_api'
34
+ require 'radiator/bridge'
32
35
  require 'radiator/stream'
33
36
  require 'radiator/operation_ids'
34
37
  require 'radiator/operation_types'
@@ -40,6 +43,9 @@ module Radiator
40
43
  require 'radiator/mixins/acts_as_voter'
41
44
  require 'radiator/mixins/acts_as_wallet'
42
45
  require 'radiator/chain'
43
- require 'steem' unless defined? Steem
46
+ require 'radiator/ssc/base_steem_smart_contract_rpc'
47
+ require 'radiator/ssc/blockchain'
48
+ require 'radiator/ssc/stream'
49
+ require 'radiator/ssc/contracts'
44
50
  extend self
45
51
  end
@@ -138,15 +138,29 @@ module Radiator
138
138
 
139
139
  DEFAULT_STEEM_FAILOVER_URLS = [
140
140
  DEFAULT_STEEM_URL,
141
- 'https://appbasetest.timcliff.com',
142
- 'https://api.steem.house',
143
141
  'https://steemd.minnowsupportproject.org',
144
- 'https://steemd.privex.io',
145
- 'https://rpc.steemviz.com',
142
+ 'https://api.justyy.com',
143
+ 'https://steem.bts.tw'
144
+ ]
145
+
146
+ DEFAULT_STEEM_RESTFUL_URL = nil
147
+
148
+ DEFAULT_HIVE_URL = 'https://api.openhive.network'
149
+
150
+ DEFAULT_HIVE_FAILOVER_URLS = [
151
+ DEFAULT_HIVE_URL,
146
152
  'https://anyx.io',
147
- 'httpd://rpc.usesteem.com'
153
+ 'https://api.hivekings.com',
154
+ 'https://api.hive.blog',
155
+ 'https://techcoderx.com',
156
+ 'https://rpc.esteem.app',
157
+ 'https://hived.privex.io',
158
+ 'https://api.pharesim.me',
159
+ 'https://rpc.ausbit.dev'
148
160
  ]
149
161
 
162
+ DEFAULT_HIVE_RESTFUL_URL = 'https://anyx.io/v1'
163
+
150
164
  # @private
151
165
  POST_HEADERS = {
152
166
  'Content-Type' => 'application/json',
@@ -159,15 +173,65 @@ module Radiator
159
173
  def self.default_url(chain)
160
174
  case chain.to_sym
161
175
  when :steem then DEFAULT_STEEM_URL
176
+ when :hive then DEFAULT_HIVE_URL
162
177
  else; raise ApiError, "Unsupported chain: #{chain}"
163
178
  end
164
179
  end
165
180
 
181
+ def self.default_restful_url(chain)
182
+ case chain.to_sym
183
+ when :steem then DEFAULT_STEEM_RESTFUL_URL
184
+ when :hive then DEFAULT_HIVE_RESTFUL_URL
185
+ end
186
+ end
187
+
166
188
  def self.default_failover_urls(chain)
167
189
  case chain.to_sym
168
- when :steem then DEFAULT_STEEM_FAILOVER_URLS
190
+ when :steem, :hive
191
+ begin
192
+ _api = Radiator::Api.new(url: DEFAULT_STEEM_FAILOVER_URLS.sample, failover_urls: DEFAULT_STEEM_FAILOVER_URLS)
193
+
194
+ default_failover_urls = _api.get_accounts(['fullnodeupdate']) do |accounts|
195
+ fullnodeupdate = accounts.first
196
+ metadata = (JSON[fullnodeupdate.json_metadata] rescue nil) || {}
197
+ report = metadata.fetch('report', [])
198
+
199
+ if report.any?
200
+ report.map do |r|
201
+ if chain.to_sym == :steem && !r.fetch('hive', false)
202
+ r.fetch('node')
203
+ elsif chain.to_sym == :hive && r.fetch('hive', false)
204
+ r.fetch('node')
205
+ end
206
+ end.compact
207
+ end
208
+ end
209
+ rescue => e
210
+ puts e
211
+ end
169
212
  else; raise ApiError, "Unsupported chain: #{chain}"
170
213
  end
214
+
215
+ if !!default_failover_urls
216
+ default_failover_urls
217
+ else
218
+ case chain.to_sym
219
+ when :steem then DEFAULT_STEEM_FAILOVER_URLS
220
+ when :hive then DEFAULT_HIVE_FAILOVER_URLS
221
+ else; []
222
+ end
223
+ end
224
+ end
225
+
226
+ def self.network_api(chain, api_name, options = {})
227
+ api = case chain.to_sym
228
+ when :steem then Steem::Api.clone(freeze: true) rescue Api.clone
229
+ when :hive then Hive::Api.clone(freeze: true) rescue Api.clone
230
+ else; raise ApiError, "Unsupported chain: #{chain}"
231
+ end
232
+
233
+ api.api_name = api_name
234
+ api.new(options) rescue nil
171
235
  end
172
236
 
173
237
  # Cretes a new instance of Radiator::Api.
@@ -190,6 +254,7 @@ module Radiator
190
254
  @password = options[:password]
191
255
  @chain = options[:chain] || :steem
192
256
  @url = options[:url] || Api::default_url(@chain)
257
+ @restful_url = options[:restful_url] || Api::default_restful_url(@chain)
193
258
  @preferred_url = @url.dup
194
259
  @failover_urls = options[:failover_urls]
195
260
  @debug = !!options[:debug]
@@ -263,6 +328,7 @@ module Radiator
263
328
  @block_api = nil
264
329
  @backoff_at = nil
265
330
  @jussi_supported = []
331
+ @network_api = Api::network_api(@chain, api_name, url: @url)
266
332
  end
267
333
 
268
334
  # Get a specific block or range of blocks.
@@ -357,6 +423,8 @@ module Radiator
357
423
 
358
424
  # @private
359
425
  def respond_to_missing?(m, include_private = false)
426
+ return true if @network_api.respond_to? m.to_sym
427
+
360
428
  method_names.nil? ? false : method_names.include?(m.to_sym)
361
429
  end
362
430
 
@@ -412,6 +480,18 @@ module Radiator
412
480
  end
413
481
  end
414
482
 
483
+ @network_api ||= Api::network_api(@chain, api_name, url: @uri)
484
+
485
+ if !!@network_api && @network_api.respond_to?(m)
486
+ if !!block
487
+ @network_api.send(m, *args) do |*r|
488
+ return yield(*r)
489
+ end
490
+ else
491
+ return @network_api.send(m, *args)
492
+ end
493
+ end
494
+
415
495
  if response.nil?
416
496
  response = request(options)
417
497
 
@@ -497,6 +577,9 @@ module Radiator
497
577
  # warning e
498
578
  end
499
579
 
580
+ # failover latch
581
+ @network_api = nil if !!@network_api
582
+
500
583
  if !!response
501
584
  @persist_error_count = 0
502
585
 
@@ -618,7 +701,7 @@ module Radiator
618
701
  http.keep_alive = 30
619
702
  http.idle_timeout = idempotent ? 10 : nil
620
703
  http.max_requests = @max_requests
621
- http.retry_change_requests = idempotent
704
+ http.retry_change_requests = idempotent if defined? http.retry_change_requests
622
705
  http.reuse_ssl_sessions = @reuse_ssl_sessions
623
706
 
624
707
  http
@@ -789,15 +872,23 @@ module Radiator
789
872
 
790
873
  if @recover_transactions_on_error
791
874
  begin
792
- # Node operators often disable this operation.
793
- api.get_transaction(parser.trx_id) do |tx|
794
- if !!tx
795
- response[:result][:block_num] = tx.block_num
796
- response[:result][:trx_num] = tx.transaction_num
797
- response[:recovered_by] = http_id
798
- response.delete('error') # no need for this, now
875
+ if !!@restful_url
876
+ JSON[open("#{@restful_url}/account_history_api/get_transaction?id=#{parser.trx_id}").read].tap do |tx|
877
+ response[:result][:block_num] = tx['block_num']
878
+ response[:result][:trx_num] = tx['transaction_num']
879
+ end
880
+ else
881
+ # Node operators often disable this operation.
882
+ api.get_transaction(parser.trx_id) do |tx|
883
+ if !!tx
884
+ response[:result][:block_num] = tx.block_num
885
+ response[:result][:trx_num] = tx.transaction_num
886
+ end
799
887
  end
800
888
  end
889
+
890
+ response[:recovered_by] = http_id
891
+ response.delete('error') # no need for this, now
801
892
  rescue
802
893
  debug "Couldn't find block for trx_id: #{parser.trx_id}, giving up."
803
894
  end