radiator 0.4.6 → 0.4.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +27 -12
  3. data/Rakefile +53 -23
  4. data/lib/radiator.rb +3 -1
  5. data/lib/radiator/api.rb +111 -16
  6. data/lib/radiator/bridge.rb +34 -0
  7. data/lib/radiator/broadcast_operations.json +7 -7
  8. data/lib/radiator/chain.rb +1 -1
  9. data/lib/radiator/chain_config.rb +9 -2
  10. data/lib/radiator/database_api.rb +1 -1
  11. data/lib/radiator/error_parser.rb +1 -1
  12. data/lib/radiator/follow_api.rb +1 -1
  13. data/lib/radiator/market_history_api.rb +1 -1
  14. data/lib/radiator/mixins/acts_as_poster.rb +4 -4
  15. data/lib/radiator/operation.rb +3 -2
  16. data/lib/radiator/operation_types.rb +43 -27
  17. data/lib/radiator/ssc/base_steem_smart_contract_rpc.rb +1 -1
  18. data/lib/radiator/stream.rb +21 -8
  19. data/lib/radiator/transaction.rb +43 -3
  20. data/lib/radiator/type/amount.rb +8 -50
  21. data/lib/radiator/type/beneficiaries.rb +8 -1
  22. data/lib/radiator/type/price.rb +2 -2
  23. data/lib/radiator/version.rb +1 -1
  24. data/radiator.gemspec +17 -13
  25. data/test/fixtures/empty.json +1 -0
  26. data/test/fixtures/error.json +29 -0
  27. data/test/fixtures/follow_api_get_followers.json +1 -0
  28. data/test/fixtures/get_account.json +165 -0
  29. data/test/fixtures/get_account_count.json +1 -0
  30. data/test/fixtures/get_account_references.json +1 -0
  31. data/test/fixtures/get_block.json +193 -0
  32. data/test/fixtures/get_dynamic_global_properties.json +32 -0
  33. data/test/fixtures/get_feed_history.json +684 -0
  34. data/test/fixtures/get_hardfork_version.json +1 -0
  35. data/test/fixtures/get_key_references.json +14 -0
  36. data/test/fixtures/get_stats_for_time.json +57 -0
  37. data/test/fixtures/get_vesting_delegation.json +936 -0
  38. data/test/fixtures/golos_get_dynamic_global_properties.json +32 -0
  39. data/test/fixtures/market_history_api_get_market_history_buckets.json +1 -0
  40. data/test/fixtures/market_history_api_get_order_book.json +109 -0
  41. data/test/fixtures/market_history_api_get_recent_trades.json +55 -0
  42. data/test/fixtures/market_history_api_get_ticker.json +11 -0
  43. data/test/fixtures/market_history_api_get_volume.json +1 -0
  44. data/test/fixtures/null.json +1 -0
  45. data/test/fixtures/vcr_cassettes/account_by_key_api_all_methods.yml +1465 -0
  46. data/test/fixtures/vcr_cassettes/account_by_key_api_jsonrpc.yml +199 -0
  47. data/test/fixtures/vcr_cassettes/api_all_methods.yml +13802 -0
  48. data/test/fixtures/vcr_cassettes/api_jsonrpc.yml +53 -0
  49. data/test/fixtures/vcr_cassettes/base_per_debt.yml +11068 -0
  50. data/test/fixtures/vcr_cassettes/base_per_mvest.yml +6024 -0
  51. data/test/fixtures/vcr_cassettes/block_time.yml +5368 -0
  52. data/test/fixtures/vcr_cassettes/broadcast_transaction.yml +1723 -0
  53. data/test/fixtures/vcr_cassettes/chain_stats_api_jsonrpc.yml +51 -0
  54. data/test/fixtures/vcr_cassettes/condenser_all_all_methods.yml +13770 -0
  55. data/test/fixtures/vcr_cassettes/condenser_api_jsonrpc.yml +103 -0
  56. data/test/fixtures/vcr_cassettes/expiration_initialize.yml +16108 -0
  57. data/test/fixtures/vcr_cassettes/find_account.yml +5732 -0
  58. data/test/fixtures/vcr_cassettes/find_block.yml +5322 -0
  59. data/test/fixtures/vcr_cassettes/find_comment.yml +16386 -0
  60. data/test/fixtures/vcr_cassettes/follow_api_jsonrpc.yml +99 -0
  61. data/test/fixtures/vcr_cassettes/get_account_count.yml +783 -0
  62. data/test/fixtures/vcr_cassettes/get_account_references.yml +773 -0
  63. data/test/fixtures/vcr_cassettes/get_accounts.yml +918 -0
  64. data/test/fixtures/vcr_cassettes/get_accounts_no_argument.yml +773 -0
  65. data/test/fixtures/vcr_cassettes/get_dynamic_global_properties.yml +893 -0
  66. data/test/fixtures/vcr_cassettes/get_feed_history.yml +1432 -0
  67. data/test/fixtures/vcr_cassettes/get_hardfork_version.yml +835 -0
  68. data/test/fixtures/vcr_cassettes/get_key_references.yml +1571 -0
  69. data/test/fixtures/vcr_cassettes/get_market_history.yml +1563 -0
  70. data/test/fixtures/vcr_cassettes/get_market_history_buckets.yml +1665 -0
  71. data/test/fixtures/vcr_cassettes/get_order_book.yml +1459 -0
  72. data/test/fixtures/vcr_cassettes/get_recent_trades.yml +1459 -0
  73. data/test/fixtures/vcr_cassettes/get_ticker.yml +1563 -0
  74. data/test/fixtures/vcr_cassettes/get_trade_history.yml +1459 -0
  75. data/test/fixtures/vcr_cassettes/get_vesting_delegations.yml +731 -0
  76. data/test/fixtures/vcr_cassettes/get_volume.yml +1561 -0
  77. data/test/fixtures/vcr_cassettes/get_witness_by_account.yml +835 -0
  78. data/test/fixtures/vcr_cassettes/look_up_witnesses.yml +831 -0
  79. data/test/fixtures/vcr_cassettes/market_history_api_all_methods.yml +10191 -0
  80. data/test/fixtures/vcr_cassettes/market_history_api_jsonrpc.yml +51 -0
  81. data/test/fixtures/vcr_cassettes/network_broadcast_api_all_methods.yml +2455 -0
  82. data/test/fixtures/vcr_cassettes/network_broadcast_api_jsonrpc.yml +51 -0
  83. data/test/fixtures/vcr_cassettes/properties.yml +5551 -0
  84. data/test/fixtures/vcr_cassettes/recover_transaction.yml +1815 -0
  85. data/test/fixtures/vcr_cassettes/ssc_blockchain_block_info.yml +90 -0
  86. data/test/fixtures/vcr_cassettes/ssc_blockchain_block_info_invalid.yml +88 -0
  87. data/test/fixtures/vcr_cassettes/ssc_blockchain_latest_block_info.yml +90 -0
  88. data/test/fixtures/vcr_cassettes/ssc_blockchain_transaction_info.yml +90 -0
  89. data/test/fixtures/vcr_cassettes/ssc_contracts_contract.yml +364 -0
  90. data/test/fixtures/vcr_cassettes/ssc_contracts_find.yml +89 -0
  91. data/test/fixtures/vcr_cassettes/ssc_contracts_find_one.yml +87 -0
  92. data/test/fixtures/vcr_cassettes/stream_jsonrpc.yml +27502 -0
  93. data/test/fixtures/vcr_cassettes/tag_api_jsonrpc.yml +155 -0
  94. data/test/fixtures/vcr_cassettes/transaction_expiration_initialize_nil.yml +17597 -0
  95. data/test/fixtures/vcr_cassettes/transaction_jsonrpc.yml +61 -0
  96. data/test/fixtures/vcr_cassettes/unknown_chain_id.yml +13038 -0
  97. data/test/fixtures/vcr_cassettes/valid_chains.yml +11450 -0
  98. data/test/radiator/account_by_key_api_test.rb +46 -0
  99. data/test/radiator/api_test.rb +135 -0
  100. data/test/radiator/chain_stats_api_test.rb +49 -0
  101. data/test/radiator/chain_test.rb +153 -0
  102. data/test/radiator/condenser_api_test.rb +48 -0
  103. data/test/radiator/follow_api_test.rb +48 -0
  104. data/test/radiator/market_history_api_test.rb +100 -0
  105. data/test/radiator/network_broadcast_api_test.rb +48 -0
  106. data/test/radiator/operation_test.rb +116 -0
  107. data/test/radiator/ssc/blockchain_test.rb +58 -0
  108. data/test/radiator/ssc/contracts_test.rb +65 -0
  109. data/test/radiator/stream_test.rb +48 -0
  110. data/test/radiator/tag_api_test.rb +40 -0
  111. data/test/radiator/transaction_test.rb +755 -0
  112. data/test/test_helper.rb +66 -0
  113. metadata +187 -79
  114. data/.codeclimate.yml +0 -19
  115. data/.gitignore +0 -52
  116. data/.travis.yml +0 -23
  117. data/gource.sh +0 -8
  118. data/images/Anthony Martin.png +0 -0
  119. data/images/Marvin Hofmann.jpg +0 -0
  120. data/images/Marvin Hofmann.png +0 -0
  121. data/lib/steem.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a1109869bdcd5e344793dad14ab64e9057529ec0
4
- data.tar.gz: '0608af42e9b00b20c25356f246933071d3ba4fd5'
2
+ SHA256:
3
+ metadata.gz: e19fc174759ced3e7e36ca803a0c75c5e9a2d0ad4dd2500df7349aa586beb951
4
+ data.tar.gz: 616820b9a03134f1a88eb9dba05eac08e06aa451c4bc244005f16ba0cdb5b29d
5
5
  SHA512:
6
- metadata.gz: 924b43fa78be2bdf26f6278b81a0f294909f2c7692bf322dcbe93e5e2ad58b23cf0954adf921e3125ad266ac546a131c6b6e9c162df60b6e084ef108c037c5db
7
- data.tar.gz: e83db7eb0a2ef39b7c9b09cb9d1007cd1a329de81c7637c346fc0b3acde618306b17ee12fecd0f24cdb9d6ed65c4225297fad41bac3bea691827a4868fdba0c3
6
+ metadata.gz: 602bc8f91295d5c731cbfb1d5c077ef35e0f7d1048d7c43a1ccbffd767aab1d9bb69dd16aee84ac9abdc1819ed9dfc7297e0a92bcc5f274ec89940a427af33d2
7
+ data.tar.gz: 4b9ca072034850498b5807cfd5e92152921b5e6b279356da6b2e635e636255a92cef82f74218d51ea46a685468cc8cd2af6c7b4a7301663c9697b5eab47cd557
data/README.md CHANGED
@@ -6,9 +6,24 @@
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.8
14
+
15
+ * Eclipse Update
16
+ * Now wrapping [`hive-ruby`](https://gitlab.syncad.com/hive/hive-ruby) and [`steem-ruby`](https://github.com/steemit/steem-ruby)
17
+
18
+ #### Changes in v0.4.7
19
+
20
+ * Added `attr_reader` for `Radiator::Type::Amount` [#28](https://github.com/inertia186/radiator/issues/28)
21
+ * Added restful fallback for `get_transaction` during `recover_transactions_on_error`
22
+ * Fix beneficiary serialization (thanks @eonwarped)
23
+
24
+ #### Changes in v0.4.6
25
+
26
+ * Added health check and persist option
12
27
 
13
28
  #### Changes in v0.4.5
14
29
 
@@ -123,7 +138,7 @@ If you don't have `bundler`, see the next section.
123
138
 
124
139
  ### Prerequisites
125
140
 
126
- `minimum ruby version: 2.2`
141
+ `minimum ruby version: 2.5`
127
142
 
128
143
  #### Linux
129
144
 
@@ -190,7 +205,7 @@ end
190
205
 
191
206
  #### Side Chain Support
192
207
 
193
- Steem Smart Contract side-chains are supported by Radiator. The default side-chain is Steem Engine.
208
+ Steem Smart Contract side-chains are supported by Radiator. The default side-chain is Hive/Steem Engine.
194
209
 
195
210
  This will fetch the latest block from the side-chain ...
196
211
 
@@ -441,7 +456,7 @@ Example of the output:
441
456
  Streaming side-chain transactions are supported:
442
457
 
443
458
  ```ruby
444
- # Default side-chain is Steem Engine.
459
+ # Default side-chain is Hive Engine.
445
460
  stream = Radiator::SSC::Stream.new
446
461
  stream.transactions do |tx, trx_id|
447
462
  puts "[#{trx_id}] #{tx.to_json}"
@@ -517,10 +532,10 @@ Radiator supports failover for situations where a node has, for example, become
517
532
 
518
533
  ```ruby
519
534
  options = {
520
- url: 'https://api.steemit.com',
535
+ url: 'https://api.hive.blog',
521
536
  failover_urls: [
522
- 'https://api.steemitstage.com',
523
- 'https://api.steem.house'
537
+ 'https://anyx.io',
538
+ 'https://api.hivekings.com',
524
539
  ]
525
540
  }
526
541
 
@@ -623,20 +638,20 @@ https://github.com/inertia186/radiator/issues/12
623
638
  * `rake`
624
639
  * To run tests with parallelization and local code coverage:
625
640
  * `HELL_ENABLED=true rake`
626
- * To run a stream test on the live STEEM blockchain with debug logging enabled:
641
+ * To run a stream test on the live Hive/Steem blockchain with debug logging enabled:
627
642
  * `LOG=DEBUG rake test_live_stream`
628
643
 
629
644
  ---
630
645
 
631
646
  <center>
632
- <img src="https://steemitimages.com/0x0/http://www.steemimg.com/images/2016/08/19/RadiatorCoolingFan-54in-Webfdcb1.png" />
647
+ <img src="https://i.imgur.com/9LcZKYD.png" />
633
648
  </center>
634
649
 
635
- See my previous Ruby How To posts in: [#radiator](https://steemit.com/created/radiator) [#ruby](https://steemit.com/created/ruby)
650
+ See my previous Ruby How To posts in: [#radiator](https://hive.blog/created/radiator) [#ruby](https://hive.blog/created/ruby)
636
651
 
637
652
  ## Get in touch!
638
653
 
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 STEEM.
654
+ 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.
640
655
 
641
656
  ## License
642
657
 
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] || 'hive').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,19 +68,28 @@ 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
- desc 'Tests the ability to stream live data. defaults: chain = steem; persist = true.'
84
+ desc 'Tests the ability to stream live data. defaults: chain = hive; 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
66
- options = {chain: chain, persist: persist, url: url}
90
+ url = chain == :steem ? 'https://api.steemit.com' : 'http://anyx.io'
91
+ # url = nil # use default
92
+ options = {chain: chain, persist: persist, url: url, use_condenser_namespace: false}
67
93
  total_ops = 0.0
68
94
  total_vops = 0.0
69
95
  elapsed = 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
 
@@ -128,7 +158,7 @@ end
128
158
 
129
159
  desc 'Publish the current version of the radiator gem.'
130
160
  task :push do
131
- exec "gem push radiator-#{Radiator::VERSION}.gem"
161
+ exec "gem push pkg/radiator-#{Radiator::VERSION}.gem"
132
162
  end
133
163
 
134
164
  # We're not going to yank on a regular basis, but this is how it's done if you
@@ -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'
@@ -44,6 +47,5 @@ module Radiator
44
47
  require 'radiator/ssc/blockchain'
45
48
  require 'radiator/ssc/stream'
46
49
  require 'radiator/ssc/contracts'
47
- require 'steem' unless defined? Steem
48
50
  extend self
49
51
  end
@@ -138,15 +138,33 @@ 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
- 'https://steemd.minnowsupportproject.org',
144
- 'https://steemd.privex.io',
145
- 'https://rpc.steemviz.com',
141
+ 'https://api.justyy.com',
142
+ 'https://steem.61bts.com'
143
+ ]
144
+
145
+ DEFAULT_STEEM_RESTFUL_URL = nil
146
+
147
+ DEFAULT_HIVE_URL = 'https://api.openhive.network'
148
+
149
+ DEFAULT_HIVE_FAILOVER_URLS = [
150
+ DEFAULT_HIVE_URL,
146
151
  'https://anyx.io',
147
- 'httpd://rpc.usesteem.com'
152
+ 'https://api.hivekings.com',
153
+ 'https://api.hive.blog',
154
+ 'https://techcoderx.com',
155
+ 'https://rpc.ecency.com',
156
+ 'https://hive.roelandp.nl',
157
+ 'https://api.c0ff33a.uk',
158
+ 'https://api.deathwing.me',
159
+ 'https://hive-api.arcange.eu',
160
+ 'https://fin.hive.3speak.co',
161
+ 'https://hived.privex.io',
162
+ 'https://api.pharesim.me',
163
+ # 'https://rpc.ausbit.dev'
148
164
  ]
149
165
 
166
+ DEFAULT_HIVE_RESTFUL_URL = 'https://anyx.io/v1'
167
+
150
168
  # @private
151
169
  POST_HEADERS = {
152
170
  'Content-Type' => 'application/json',
@@ -159,15 +177,65 @@ module Radiator
159
177
  def self.default_url(chain)
160
178
  case chain.to_sym
161
179
  when :steem then DEFAULT_STEEM_URL
180
+ when :hive then DEFAULT_HIVE_URL
162
181
  else; raise ApiError, "Unsupported chain: #{chain}"
163
182
  end
164
183
  end
165
184
 
185
+ def self.default_restful_url(chain)
186
+ case chain.to_sym
187
+ when :steem then DEFAULT_STEEM_RESTFUL_URL
188
+ when :hive then DEFAULT_HIVE_RESTFUL_URL
189
+ end
190
+ end
191
+
166
192
  def self.default_failover_urls(chain)
167
193
  case chain.to_sym
168
- when :steem then DEFAULT_STEEM_FAILOVER_URLS
194
+ when :steem, :hive
195
+ begin
196
+ _api = Radiator::Api.new(url: DEFAULT_HIVE_FAILOVER_URLS.sample, failover_urls: DEFAULT_HIVE_FAILOVER_URLS)
197
+
198
+ default_failover_urls = _api.get_accounts(['fullnodeupdate']) do |accounts|
199
+ fullnodeupdate = accounts.first
200
+ metadata = (JSON[fullnodeupdate.json_metadata] rescue nil) || {}
201
+ report = metadata.fetch('report', [])
202
+
203
+ if report.any?
204
+ report.map do |r|
205
+ if chain.to_sym == :steem && !r.fetch('hive', false)
206
+ r.fetch('node')
207
+ elsif chain.to_sym == :hive && r.fetch('hive', false)
208
+ r.fetch('node')
209
+ end
210
+ end.compact
211
+ end
212
+ end
213
+ rescue => e
214
+ puts e
215
+ end
169
216
  else; raise ApiError, "Unsupported chain: #{chain}"
170
217
  end
218
+
219
+ if !!default_failover_urls
220
+ default_failover_urls
221
+ else
222
+ case chain.to_sym
223
+ when :steem then DEFAULT_STEEM_FAILOVER_URLS
224
+ when :hive then DEFAULT_HIVE_FAILOVER_URLS
225
+ else; []
226
+ end
227
+ end
228
+ end
229
+
230
+ def self.network_api(chain, api_name, options = {})
231
+ api = case chain.to_sym
232
+ when :steem then Steem::Api.clone(freeze: true) rescue Api.clone
233
+ when :hive then Hive::Api.clone(freeze: true) rescue Api.clone
234
+ else; raise ApiError, "Unsupported chain: #{chain}"
235
+ end
236
+
237
+ api.api_name = api_name
238
+ api.new(options) rescue nil
171
239
  end
172
240
 
173
241
  # Cretes a new instance of Radiator::Api.
@@ -188,8 +256,9 @@ module Radiator
188
256
  def initialize(options = {})
189
257
  @user = options[:user]
190
258
  @password = options[:password]
191
- @chain = options[:chain] || :steem
259
+ @chain = (options[:chain] || 'hive').to_sym
192
260
  @url = options[:url] || Api::default_url(@chain)
261
+ @restful_url = options[:restful_url] || Api::default_restful_url(@chain)
193
262
  @preferred_url = @url.dup
194
263
  @failover_urls = options[:failover_urls]
195
264
  @debug = !!options[:debug]
@@ -263,6 +332,7 @@ module Radiator
263
332
  @block_api = nil
264
333
  @backoff_at = nil
265
334
  @jussi_supported = []
335
+ @network_api = Api::network_api(@chain, api_name, url: @url)
266
336
  end
267
337
 
268
338
  # Get a specific block or range of blocks.
@@ -357,6 +427,8 @@ module Radiator
357
427
 
358
428
  # @private
359
429
  def respond_to_missing?(m, include_private = false)
430
+ return true if @network_api.respond_to? m.to_sym
431
+
360
432
  method_names.nil? ? false : method_names.include?(m.to_sym)
361
433
  end
362
434
 
@@ -412,6 +484,18 @@ module Radiator
412
484
  end
413
485
  end
414
486
 
487
+ @network_api ||= Api::network_api(@chain, api_name, url: @uri)
488
+
489
+ if !!@network_api && @network_api.respond_to?(m)
490
+ if !!block
491
+ @network_api.send(m, *args) do |*r|
492
+ return yield(*r)
493
+ end
494
+ else
495
+ return @network_api.send(m, *args)
496
+ end
497
+ end
498
+
415
499
  if response.nil?
416
500
  response = request(options)
417
501
 
@@ -497,6 +581,9 @@ module Radiator
497
581
  # warning e
498
582
  end
499
583
 
584
+ # failover latch
585
+ @network_api = nil if !!@network_api
586
+
500
587
  if !!response
501
588
  @persist_error_count = 0
502
589
 
@@ -618,7 +705,7 @@ module Radiator
618
705
  http.keep_alive = 30
619
706
  http.idle_timeout = idempotent ? 10 : nil
620
707
  http.max_requests = @max_requests
621
- http.retry_change_requests = idempotent
708
+ http.retry_change_requests = idempotent if defined? http.retry_change_requests
622
709
  http.reuse_ssl_sessions = @reuse_ssl_sessions
623
710
 
624
711
  http
@@ -789,15 +876,23 @@ module Radiator
789
876
 
790
877
  if @recover_transactions_on_error
791
878
  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
879
+ if !!@restful_url
880
+ JSON[open("#{@restful_url}/account_history_api/get_transaction?id=#{parser.trx_id}").read].tap do |tx|
881
+ response[:result][:block_num] = tx['block_num']
882
+ response[:result][:trx_num] = tx['transaction_num']
883
+ end
884
+ else
885
+ # Node operators often disable this operation.
886
+ api.get_transaction(parser.trx_id) do |tx|
887
+ if !!tx
888
+ response[:result][:block_num] = tx.block_num
889
+ response[:result][:trx_num] = tx.transaction_num
890
+ end
799
891
  end
800
892
  end
893
+
894
+ response[:recovered_by] = http_id
895
+ response.delete('error') # no need for this, now
801
896
  rescue
802
897
  debug "Couldn't find block for trx_id: #{parser.trx_id}, giving up."
803
898
  end