radiator 0.4.6 → 0.4.8

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 (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
@@ -0,0 +1,755 @@
1
+ require 'test_helper'
2
+
3
+ module Radiator
4
+ class TransactionTest < Radiator::Test
5
+ include Utils
6
+
7
+ def setup
8
+ options = {
9
+ wif: '5JLw5dgQAx6rhZEgNN5C2ds1V47RweGshynFSWFbaMohsYsBvE8',
10
+ ref_block_num: 36029,
11
+ ref_block_prefix: 1164960351,
12
+ expiration: Time.parse('2016-08-08T12:24:17 Z'),
13
+ failover_urls: [],
14
+ logger: Logger.new(nil).tap do |logger|
15
+ logger.progname = 'transction-test'
16
+ end
17
+ }
18
+
19
+ vcr_cassette('transaction_jsonrpc') do
20
+ @transaction = Radiator::Transaction.new(options.dup)
21
+ end
22
+ end
23
+
24
+ def test_valid_chains
25
+ vcr_cassette('valid_chains') do
26
+ %w(steem test).each do |chain|
27
+ io = StringIO.new
28
+ log = Logger.new(io).tap do |logger|
29
+ logger.progname = 'test-valid-chains'
30
+ end
31
+
32
+ case chain.to_sym
33
+ when :steem
34
+ transaction = Radiator::Transaction.new(chain: chain, logger: log)
35
+ assert_equal Radiator::Transaction::NETWORKS_STEEM_CHAIN_ID, transaction.chain_id, 'expect steem chain'
36
+ when :hive
37
+ transaction = Radiator::Transaction.new(chain: chain, logger: log)
38
+ assert_equal Radiator::Transaction::NETWORKS_HIVE_CHAIN_ID, transaction.chain_id, 'expect hive chain'
39
+ when :test
40
+ assert_raises ApiError do
41
+ transaction = Radiator::Transaction.new(chain: chain, logger: log)
42
+ end
43
+ else
44
+ # :nocov:
45
+ fail "did not expect chain: #{chain}"
46
+ # :nocov:
47
+ end
48
+ assert_equal '', io.string, 'expect empty log'
49
+ end
50
+ end
51
+ end
52
+
53
+ def test_unknown_chain
54
+ io = StringIO.new
55
+ Radiator.logger = Logger.new(io).tap do |logger| # side effect: increase code coverage
56
+ logger.progname = 'test-unknown-chain'
57
+ end
58
+ chain = 'ginger'
59
+ assert_raises ApiError do
60
+ Radiator::Transaction.new(chain: chain)
61
+ end
62
+ refute_equal '', io.string, 'did not expect empty log'
63
+ assert io.string.include?('Unknown chain id'), 'expect log to mention unknown chain id'
64
+ end
65
+
66
+ def test_unknown_chain_id
67
+ vcr_cassette('unknown_chain_id') do
68
+ io = StringIO.new
69
+ log = Logger.new(io).tap do |logger|
70
+ logger.progname = 'test-unknown-chain-id'
71
+ end
72
+ unknown_chain_id = 'F' * (256 / 4)
73
+ Radiator::Transaction.new(chain_id: unknown_chain_id, logger: log)
74
+
75
+ refute_equal '', io.string, 'did not expect empty log'
76
+ assert io.string.include?(unknown_chain_id), 'expect log to mention unknown chain id'
77
+ end
78
+ end
79
+
80
+ def test_wif_and_private_key
81
+ assert_raises TransactionError, 'expect transaction to freak when it sees both' do
82
+ Radiator::Transaction.new(wif: 'wif', private_key: 'private key')
83
+ end
84
+ end
85
+
86
+ def test_ref_block_num
87
+ vcr_cassette('ref_block_num') do
88
+ @transaction.operations << {type: :vote}
89
+ @transaction.process(false)
90
+ payload = @transaction.send(:payload)
91
+ assert_equal 36029, payload[:ref_block_num], 'expect a certain ref_block_prefix'
92
+ end
93
+ end
94
+
95
+ def test_ref_block_prefix
96
+ vcr_cassette('ref_block_prefix') do
97
+ @transaction.operations << {type: :vote}
98
+ @transaction.process(false)
99
+ payload = @transaction.send(:payload)
100
+ assert_equal 1164960351, payload[:ref_block_prefix], 'expect a certain ref_block_prefix'
101
+ end
102
+ end
103
+
104
+ # This is a contrived transaction that mirrors the transaction documented
105
+ # by the manual signing example written by xeroc:
106
+ #
107
+ # https://gist.github.com/xeroc/9bda11add796b603d83eb4b41d38532b
108
+ def test_to_bytes
109
+ vote = {
110
+ type: :vote,
111
+ voter: 'xeroc',
112
+ author: 'xeroc',
113
+ permlink: 'piston',
114
+ weight: 10000,
115
+ extensions: [],
116
+ }
117
+
118
+ @transaction.operations << vote
119
+ refute_nil bytes = @transaction.send(:to_bytes)
120
+ hex = hexlify(bytes)
121
+
122
+ # Here, we're going to take apart our contrived serialization so we can
123
+ # verify each substring individually.
124
+
125
+ chain_id = hex[0..63]
126
+ ref_block_num = hex[64..67]
127
+ ref_block_prefix = hex[68..75]
128
+ exp = hex[76..83]
129
+ op_len = hex[84..85]
130
+ op_id = hex[86..87]
131
+ voter = hex[88..99]
132
+ author = hex[100..111]
133
+ permlink = hex[112..125]
134
+ weight = hex[126..129]
135
+ extensions = hex[130..131]
136
+
137
+ hex_segments = {
138
+ chain_id: chain_id, ref_block_num: ref_block_num,
139
+ ref_block_prefix: ref_block_prefix, exp: exp, op_len: op_len,
140
+ op_id: op_id, voter: voter, author: author, permlink: permlink,
141
+ weight: weight, extensions: extensions
142
+ }
143
+
144
+ # This example serialization was documented by xeroc:
145
+ # https://steemit.com/steem/@xeroc/steem-transaction-signing-in-a-nutshell
146
+ example_hex = 'bd8c5fe26f45f179a8570100057865726f63057865726f6306706973746f6e102'
147
+ assert hex.include?(example_hex), 'expect example_hex in our result'
148
+
149
+ # Later correction by xeroc:
150
+ # https://steemit.com/steem/@xeroc/steem-transaction-signing-in-a-nutshell#@xeroc/re-steem-transaction-signing-in-a-nutshell-20160901t151404
151
+ example_hex2 = 'bd8c5fe26f45f179a8570100057865726f63057865726f6306706973746f6e102700'
152
+ assert hex.include?(example_hex2), 'expect example_hex2 in our result'
153
+
154
+ # The only thing that should remain if we remove the second example is the
155
+ # chain_id.
156
+ remaining_hex = hex.gsub example_hex2, ''
157
+ assert_equal Radiator::ChainConfig::NETWORKS_HIVE_CHAIN_ID,
158
+ remaining_hex, 'expect nothing but the chain_id'
159
+
160
+ # Here, we're going to take apart our contrived serialization so we can
161
+ # verify each substring.
162
+
163
+ assert_equal Radiator::ChainConfig::NETWORKS_HIVE_CHAIN_ID,
164
+ hex_segments[:chain_id], 'expect chain_id'
165
+ assert_equal 'bd8c', hex_segments[:ref_block_num], 'expect ref_block_num'
166
+ assert_equal '5fe26f45', hex_segments[:ref_block_prefix], 'expect ref_block_prefix'
167
+ assert_equal 'f179a857', hex_segments[:exp], 'expect exp'
168
+ assert_equal '01', hex_segments[:op_len], 'expect op_len'
169
+ assert_equal '00', hex_segments[:op_id], 'expect op_id'
170
+ assert_equal '057865726f63', hex_segments[:voter], 'expect voter'
171
+ assert_equal '057865726f63', hex_segments[:author], 'expect author'
172
+ assert_equal '06706973746f6e', hex_segments[:permlink], 'expect permlink'
173
+ assert_equal '1027', hex_segments[:weight], 'expect weight'
174
+ assert_equal '00', hex_segments[:extensions], 'expect extensions'
175
+ assert_equal hex, hex_segments.values.join
176
+ end
177
+
178
+ def test_digest
179
+ vote = {
180
+ type: :vote,
181
+ voter: 'xeroc',
182
+ author: 'xeroc',
183
+ permlink: 'piston',
184
+ weight: 10000
185
+ }
186
+
187
+ @transaction.operations << vote
188
+
189
+ refute_nil digest = @transaction.send(:digest)
190
+
191
+ # This is how the example given by @xeroc deals with the signature. It
192
+ # does not include the extensions count.
193
+ #
194
+ # https://gist.github.com/xeroc/9bda11add796b603d83eb4b41d38532b
195
+ example_bytes = @transaction.send(:to_bytes).chop
196
+ example_digest = Digest::SHA256.digest example_bytes
197
+ assert_equal '094f2c1a15ef441014c58f8cdc1a84fcab11bd617b33507167e1798e9f1923d2', hexlify(example_digest),
198
+ 'epect example output from digest'
199
+ refute_equal hexlify(digest), hexlify(example_digest),
200
+ 'did not expect example output to match normal output'
201
+
202
+ assert_equal '0e5dbd979f4f2387c5d5a1b649ef06589630faf7c065dea0da8e592b03da06bc', hexlify(digest)
203
+ 'expect normal output from digest'
204
+ end
205
+
206
+ def test_signature
207
+ vote = {
208
+ type: :vote,
209
+ voter: 'xeroc',
210
+ author: 'xeroc',
211
+ permlink: 'piston',
212
+ weight: 10000
213
+ }
214
+
215
+ @transaction.operations << vote
216
+
217
+ refute_nil _sig_data = @transaction.send(:signature)
218
+ end
219
+
220
+ def test_signature_long_input
221
+ vote = {
222
+ type: :comment,
223
+ author: 'xeroc',
224
+ permlink: 'piston',
225
+ body: 'test' * 900
226
+ }
227
+
228
+ @transaction.operations << vote
229
+
230
+ refute_nil _sig_data = @transaction.send(:signature)
231
+ end
232
+
233
+ # See: https://github.com/steemit/steem-python/blob/master/tests/steem/test_transactions.py#L426
234
+ def test_utf8
235
+ op = {
236
+ type: :comment,
237
+ parent_author: "",
238
+ parent_permlink: "",
239
+ author: "a",
240
+ permlink: "a",
241
+ title: "-",
242
+ body: [*(0..2048)].map { |i| [i].pack('U') }.join.chop,
243
+ json_metadata: {}.to_json
244
+ }
245
+
246
+ @transaction.operations << op
247
+
248
+ refute_nil bytes = @transaction.send(:to_bytes)
249
+ hex = hexlify(bytes)
250
+ hex_segments = seg(hex).merge(
251
+ parent_author: hex[88..89],
252
+ parent_permlink: hex[90..91],
253
+ author: hex[92..95],
254
+ permlink: hex[96..99],
255
+ title: hex[100..103],
256
+ body: hex[104..8043],
257
+ json_metadata: hex[8044..8049]
258
+ )
259
+
260
+ decoded_op_id = "0x#{hex_segments[:op_id]}".to_i(16)
261
+ op_type = "#{op[:type]}_operation".to_sym
262
+ assert_equal Radiator::OperationIds::IDS.find_index(op_type), decoded_op_id
263
+
264
+ assert_equal '01', hex_segments[:op_id], 'expect op_id'
265
+ assert_equal '00', hex_segments[:parent_author], 'expect parent_author'
266
+ assert_equal '00', hex_segments[:parent_permlink], 'expect parent_permlink'
267
+ assert_equal '0161', hex_segments[:author], 'expect author'
268
+ assert_equal '0161', hex_segments[:permlink], 'expect permlink'
269
+ assert_equal '012d', hex_segments[:title], 'expect title'
270
+ assert_equal 7940, hex_segments[:body].size, 'expect body (hex) size'
271
+ assert_equal '027b7d', hex_segments[:json_metadata], 'expect json_metadata'
272
+
273
+ compare = 'f68585abf4dce7c804570101000001610161012dec1f75303030307' +
274
+ '5303030317530303032753030303375303030347530303035753030' +
275
+ '3036753030303762090a7530303062660d753030306575303030667' +
276
+ '5303031307530303131753030313275303031337530303134753030' +
277
+ '3135753030313675303031377530303138753030313975303031617' +
278
+ '5303031627530303163753030316475303031657530303166202122' +
279
+ '232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3' +
280
+ 'e3f404142434445464748494a4b4c4d4e4f50515253545556575859' +
281
+ '5a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747' +
282
+ '5767778797a7b7c7d7e7fc280c281c282c283c284c285c286c287c2' +
283
+ '88c289c28ac28bc28cc28dc28ec28fc290c291c292c293c294c295c' +
284
+ '296c297c298c299c29ac29bc29cc29dc29ec29fc2a0c2a1c2a2c2a3' +
285
+ 'c2a4c2a5c2a6c2a7c2a8c2a9c2aac2abc2acc2adc2aec2afc2b0c2b' +
286
+ '1c2b2c2b3c2b4c2b5c2b6c2b7c2b8c2b9c2bac2bbc2bcc2bdc2bec2' +
287
+ 'bfc380c381c382c383c384c385c386c387c388c389c38ac38bc38cc' +
288
+ '38dc38ec38fc390c391c392c393c394c395c396c397c398c399c39a' +
289
+ 'c39bc39cc39dc39ec39fc3a0c3a1c3a2c3a3c3a4c3a5c3a6c3a7c3a' +
290
+ '8c3a9c3aac3abc3acc3adc3aec3afc3b0c3b1c3b2c3b3c3b4c3b5c3' +
291
+ 'b6c3b7c3b8c3b9c3bac3bbc3bcc3bdc3bec3bfc480c481c482c483c' +
292
+ '484c485c486c487c488c489c48ac48bc48cc48dc48ec48fc490c491' +
293
+ 'c492c493c494c495c496c497c498c499c49ac49bc49cc49dc49ec49' +
294
+ 'fc4a0c4a1c4a2c4a3c4a4c4a5c4a6c4a7c4a8c4a9c4aac4abc4acc4' +
295
+ 'adc4aec4afc4b0c4b1c4b2c4b3c4b4c4b5c4b6c4b7c4b8c4b9c4bac' +
296
+ '4bbc4bcc4bdc4bec4bfc580c581c582c583c584c585c586c587c588' +
297
+ 'c589c58ac58bc58cc58dc58ec58fc590c591c592c593c594c595c59' +
298
+ '6c597c598c599c59ac59bc59cc59dc59ec59fc5a0c5a1c5a2c5a3c5' +
299
+ 'a4c5a5c5a6c5a7c5a8c5a9c5aac5abc5acc5adc5aec5afc5b0c5b1c' +
300
+ '5b2c5b3c5b4c5b5c5b6c5b7c5b8c5b9c5bac5bbc5bcc5bdc5bec5bf' +
301
+ 'c680c681c682c683c684c685c686c687c688c689c68ac68bc68cc68' +
302
+ 'dc68ec68fc690c691c692c693c694c695c696c697c698c699c69ac6' +
303
+ '9bc69cc69dc69ec69fc6a0c6a1c6a2c6a3c6a4c6a5c6a6c6a7c6a8c' +
304
+ '6a9c6aac6abc6acc6adc6aec6afc6b0c6b1c6b2c6b3c6b4c6b5c6b6' +
305
+ 'c6b7c6b8c6b9c6bac6bbc6bcc6bdc6bec6bfc780c781c782c783c78' +
306
+ '4c785c786c787c788c789c78ac78bc78cc78dc78ec78fc790c791c7' +
307
+ '92c793c794c795c796c797c798c799c79ac79bc79cc79dc79ec79fc' +
308
+ '7a0c7a1c7a2c7a3c7a4c7a5c7a6c7a7c7a8c7a9c7aac7abc7acc7ad' +
309
+ 'c7aec7afc7b0c7b1c7b2c7b3c7b4c7b5c7b6c7b7c7b8c7b9c7bac7b' +
310
+ 'bc7bcc7bdc7bec7bfc880c881c882c883c884c885c886c887c888c8' +
311
+ '89c88ac88bc88cc88dc88ec88fc890c891c892c893c894c895c896c' +
312
+ '897c898c899c89ac89bc89cc89dc89ec89fc8a0c8a1c8a2c8a3c8a4' +
313
+ 'c8a5c8a6c8a7c8a8c8a9c8aac8abc8acc8adc8aec8afc8b0c8b1c8b' +
314
+ '2c8b3c8b4c8b5c8b6c8b7c8b8c8b9c8bac8bbc8bcc8bdc8bec8bfc9' +
315
+ '80c981c982c983c984c985c986c987c988c989c98ac98bc98cc98dc' +
316
+ '98ec98fc990c991c992c993c994c995c996c997c998c999c99ac99b' +
317
+ 'c99cc99dc99ec99fc9a0c9a1c9a2c9a3c9a4c9a5c9a6c9a7c9a8c9a' +
318
+ '9c9aac9abc9acc9adc9aec9afc9b0c9b1c9b2c9b3c9b4c9b5c9b6c9' +
319
+ 'b7c9b8c9b9c9bac9bbc9bcc9bdc9bec9bfca80ca81ca82ca83ca84c' +
320
+ 'a85ca86ca87ca88ca89ca8aca8bca8cca8dca8eca8fca90ca91ca92' +
321
+ 'ca93ca94ca95ca96ca97ca98ca99ca9aca9bca9cca9dca9eca9fcaa' +
322
+ '0caa1caa2caa3caa4caa5caa6caa7caa8caa9caaacaabcaaccaadca' +
323
+ 'aecaafcab0cab1cab2cab3cab4cab5cab6cab7cab8cab9cabacabbc' +
324
+ 'abccabdcabecabfcb80cb81cb82cb83cb84cb85cb86cb87cb88cb89' +
325
+ 'cb8acb8bcb8ccb8dcb8ecb8fcb90cb91cb92cb93cb94cb95cb96cb9' +
326
+ '7cb98cb99cb9acb9bcb9ccb9dcb9ecb9fcba0cba1cba2cba3cba4cb' +
327
+ 'a5cba6cba7cba8cba9cbaacbabcbaccbadcbaecbafcbb0cbb1cbb2c' +
328
+ 'bb3cbb4cbb5cbb6cbb7cbb8cbb9cbbacbbbcbbccbbdcbbecbbfcc80' +
329
+ 'cc81cc82cc83cc84cc85cc86cc87cc88cc89cc8acc8bcc8ccc8dcc8' +
330
+ 'ecc8fcc90cc91cc92cc93cc94cc95cc96cc97cc98cc99cc9acc9bcc' +
331
+ '9ccc9dcc9ecc9fcca0cca1cca2cca3cca4cca5cca6cca7cca8cca9c' +
332
+ 'caaccabccacccadccaeccafccb0ccb1ccb2ccb3ccb4ccb5ccb6ccb7' +
333
+ 'ccb8ccb9ccbaccbbccbcccbdccbeccbfcd80cd81cd82cd83cd84cd8' +
334
+ '5cd86cd87cd88cd89cd8acd8bcd8ccd8dcd8ecd8fcd90cd91cd92cd' +
335
+ '93cd94cd95cd96cd97cd98cd99cd9acd9bcd9ccd9dcd9ecd9fcda0c' +
336
+ 'da1cda2cda3cda4cda5cda6cda7cda8cda9cdaacdabcdaccdadcdae' +
337
+ 'cdafcdb0cdb1cdb2cdb3cdb4cdb5cdb6cdb7cdb8cdb9cdbacdbbcdb' +
338
+ 'ccdbdcdbecdbfce80ce81ce82ce83ce84ce85ce86ce87ce88ce89ce' +
339
+ '8ace8bce8cce8dce8ece8fce90ce91ce92ce93ce94ce95ce96ce97c' +
340
+ 'e98ce99ce9ace9bce9cce9dce9ece9fcea0cea1cea2cea3cea4cea5' +
341
+ 'cea6cea7cea8cea9ceaaceabceacceadceaeceafceb0ceb1ceb2ceb' +
342
+ '3ceb4ceb5ceb6ceb7ceb8ceb9cebacebbcebccebdcebecebfcf80cf' +
343
+ '81cf82cf83cf84cf85cf86cf87cf88cf89cf8acf8bcf8ccf8dcf8ec' +
344
+ 'f8fcf90cf91cf92cf93cf94cf95cf96cf97cf98cf99cf9acf9bcf9c' +
345
+ 'cf9dcf9ecf9fcfa0cfa1cfa2cfa3cfa4cfa5cfa6cfa7cfa8cfa9cfa' +
346
+ 'acfabcfaccfadcfaecfafcfb0cfb1cfb2cfb3cfb4cfb5cfb6cfb7cf' +
347
+ 'b8cfb9cfbacfbbcfbccfbdcfbecfbfd080d081d082d083d084d085d' +
348
+ '086d087d088d089d08ad08bd08cd08dd08ed08fd090d091d092d093' +
349
+ 'd094d095d096d097d098d099d09ad09bd09cd09dd09ed09fd0a0d0a' +
350
+ '1d0a2d0a3d0a4d0a5d0a6d0a7d0a8d0a9d0aad0abd0acd0add0aed0' +
351
+ 'afd0b0d0b1d0b2d0b3d0b4d0b5d0b6d0b7d0b8d0b9d0bad0bbd0bcd' +
352
+ '0bdd0bed0bfd180d181d182d183d184d185d186d187d188d189d18a' +
353
+ 'd18bd18cd18dd18ed18fd190d191d192d193d194d195d196d197d19' +
354
+ '8d199d19ad19bd19cd19dd19ed19fd1a0d1a1d1a2d1a3d1a4d1a5d1' +
355
+ 'a6d1a7d1a8d1a9d1aad1abd1acd1add1aed1afd1b0d1b1d1b2d1b3d' +
356
+ '1b4d1b5d1b6d1b7d1b8d1b9d1bad1bbd1bcd1bdd1bed1bfd280d281' +
357
+ 'd282d283d284d285d286d287d288d289d28ad28bd28cd28dd28ed28' +
358
+ 'fd290d291d292d293d294d295d296d297d298d299d29ad29bd29cd2' +
359
+ '9dd29ed29fd2a0d2a1d2a2d2a3d2a4d2a5d2a6d2a7d2a8d2a9d2aad' +
360
+ '2abd2acd2add2aed2afd2b0d2b1d2b2d2b3d2b4d2b5d2b6d2b7d2b8' +
361
+ 'd2b9d2bad2bbd2bcd2bdd2bed2bfd380d381d382d383d384d385d38' +
362
+ '6d387d388d389d38ad38bd38cd38dd38ed38fd390d391d392d393d3' +
363
+ '94d395d396d397d398d399d39ad39bd39cd39dd39ed39fd3a0d3a1d' +
364
+ '3a2d3a3d3a4d3a5d3a6d3a7d3a8d3a9d3aad3abd3acd3add3aed3af' +
365
+ 'd3b0d3b1d3b2d3b3d3b4d3b5d3b6d3b7d3b8d3b9d3bad3bbd3bcd3b' +
366
+ 'dd3bed3bfd480d481d482d483d484d485d486d487d488d489d48ad4' +
367
+ '8bd48cd48dd48ed48fd490d491d492d493d494d495d496d497d498d' +
368
+ '499d49ad49bd49cd49dd49ed49fd4a0d4a1d4a2d4a3d4a4d4a5d4a6' +
369
+ 'd4a7d4a8d4a9d4aad4abd4acd4add4aed4afd4b0d4b1d4b2d4b3d4b' +
370
+ '4d4b5d4b6d4b7d4b8d4b9d4bad4bbd4bcd4bdd4bed4bfd580d581d5' +
371
+ '82d583d584d585d586d587d588d589d58ad58bd58cd58dd58ed58fd' +
372
+ '590d591d592d593d594d595d596d597d598d599d59ad59bd59cd59d' +
373
+ 'd59ed59fd5a0d5a1d5a2d5a3d5a4d5a5d5a6d5a7d5a8d5a9d5aad5a' +
374
+ 'bd5acd5add5aed5afd5b0d5b1d5b2d5b3d5b4d5b5d5b6d5b7d5b8d5' +
375
+ 'b9d5bad5bbd5bcd5bdd5bed5bfd680d681d682d683d684d685d686d' +
376
+ '687d688d689d68ad68bd68cd68dd68ed68fd690d691d692d693d694' +
377
+ 'd695d696d697d698d699d69ad69bd69cd69dd69ed69fd6a0d6a1d6a' +
378
+ '2d6a3d6a4d6a5d6a6d6a7d6a8d6a9d6aad6abd6acd6add6aed6afd6' +
379
+ 'b0d6b1d6b2d6b3d6b4d6b5d6b6d6b7d6b8d6b9d6bad6bbd6bcd6bdd' +
380
+ '6bed6bfd780d781d782d783d784d785d786d787d788d789d78ad78b' +
381
+ 'd78cd78dd78ed78fd790d791d792d793d794d795d796d797d798d79' +
382
+ '9d79ad79bd79cd79dd79ed79fd7a0d7a1d7a2d7a3d7a4d7a5d7a6d7' +
383
+ 'a7d7a8d7a9d7aad7abd7acd7add7aed7afd7b0d7b1d7b2d7b3d7b4d' +
384
+ '7b5d7b6d7b7d7b8d7b9d7bad7bbd7bcd7bdd7bed7bfd880d881d882' +
385
+ 'd883d884d885d886d887d888d889d88ad88bd88cd88dd88ed88fd89' +
386
+ '0d891d892d893d894d895d896d897d898d899d89ad89bd89cd89dd8' +
387
+ '9ed89fd8a0d8a1d8a2d8a3d8a4d8a5d8a6d8a7d8a8d8a9d8aad8abd' +
388
+ '8acd8add8aed8afd8b0d8b1d8b2d8b3d8b4d8b5d8b6d8b7d8b8d8b9' +
389
+ 'd8bad8bbd8bcd8bdd8bed8bfd980d981d982d983d984d985d986d98' +
390
+ '7d988d989d98ad98bd98cd98dd98ed98fd990d991d992d993d994d9' +
391
+ '95d996d997d998d999d99ad99bd99cd99dd99ed99fd9a0d9a1d9a2d' +
392
+ '9a3d9a4d9a5d9a6d9a7d9a8d9a9d9aad9abd9acd9add9aed9afd9b0' +
393
+ 'd9b1d9b2d9b3d9b4d9b5d9b6d9b7d9b8d9b9d9bad9bbd9bcd9bdd9b' +
394
+ 'ed9bfda80da81da82da83da84da85da86da87da88da89da8ada8bda' +
395
+ '8cda8dda8eda8fda90da91da92da93da94da95da96da97da98da99d' +
396
+ 'a9ada9bda9cda9dda9eda9fdaa0daa1daa2daa3daa4daa5daa6daa7' +
397
+ 'daa8daa9daaadaabdaacdaaddaaedaafdab0dab1dab2dab3dab4dab' +
398
+ '5dab6dab7dab8dab9dabadabbdabcdabddabedabfdb80db81db82db' +
399
+ '83db84db85db86db87db88db89db8adb8bdb8cdb8ddb8edb8fdb90d' +
400
+ 'b91db92db93db94db95db96db97db98db99db9adb9bdb9cdb9ddb9e' +
401
+ 'db9fdba0dba1dba2dba3dba4dba5dba6dba7dba8dba9dbaadbabdba' +
402
+ 'cdbaddbaedbafdbb0dbb1dbb2dbb3dbb4dbb5dbb6dbb7dbb8dbb9db' +
403
+ 'badbbbdbbcdbbddbbedbbfdc80dc81dc82dc83dc84dc85dc86dc87d' +
404
+ 'c88dc89dc8adc8bdc8cdc8ddc8edc8fdc90dc91dc92dc93dc94dc95' +
405
+ 'dc96dc97dc98dc99dc9adc9bdc9cdc9ddc9edc9fdca0dca1dca2dca' +
406
+ '3dca4dca5dca6dca7dca8dca9dcaadcabdcacdcaddcaedcafdcb0dc' +
407
+ 'b1dcb2dcb3dcb4dcb5dcb6dcb7dcb8dcb9dcbadcbbdcbcdcbddcbed' +
408
+ 'cbfdd80dd81dd82dd83dd84dd85dd86dd87dd88dd89dd8add8bdd8c' +
409
+ 'dd8ddd8edd8fdd90dd91dd92dd93dd94dd95dd96dd97dd98dd99dd9' +
410
+ 'add9bdd9cdd9ddd9edd9fdda0dda1dda2dda3dda4dda5dda6dda7dd' +
411
+ 'a8dda9ddaaddabddacddadddaeddafddb0ddb1ddb2ddb3ddb4ddb5d' +
412
+ 'db6ddb7ddb8ddb9ddbaddbbddbcddbdddbeddbfde80de81de82de83' +
413
+ 'de84de85de86de87de88de89de8ade8bde8cde8dde8ede8fde90de9' +
414
+ '1de92de93de94de95de96de97de98de99de9ade9bde9cde9dde9ede' +
415
+ '9fdea0dea1dea2dea3dea4dea5dea6dea7dea8dea9deaadeabdeacd' +
416
+ 'eaddeaedeafdeb0deb1deb2deb3deb4deb5deb6deb7deb8deb9deba' +
417
+ 'debbdebcdebddebedebfdf80df81df82df83df84df85df86df87df8' +
418
+ '8df89df8adf8bdf8cdf8ddf8edf8fdf90df91df92df93df94df95df' +
419
+ '96df97df98df99df9adf9bdf9cdf9ddf9edf9fdfa0dfa1dfa2dfa3d' +
420
+ 'fa4dfa5dfa6dfa7dfa8dfa9dfaadfabdfacdfaddfaedfafdfb0dfb1' +
421
+ 'dfb2dfb3dfb4dfb5dfb6dfb7dfb8dfb9dfbadfbbdfbcdfbddfbedfb' +
422
+ 'f0000011f45c8e1ed9289f5ec7d4f6d7ce891a30ede7470e28d4639' +
423
+ '8e0dc15c41c784b1862f132378382230d68b59e3592e72a32f310f8' +
424
+ '8ea4baddb361a3709b664ba7375'
425
+
426
+ skip "Suspect the original compare string might be incorrect."
427
+ op_hex = sub_hex(hex_segments)
428
+ assert compare.include?(op_hex), 'expect final comparison from original test'
429
+ end
430
+
431
+ # See: https://github.com/steemit/steem-python/blob/master/tests/steem/test_transactions.py#L600
432
+ def test_feed_publish
433
+ op = {
434
+ type: :feed_publish,
435
+ publisher: 'xeroc',
436
+ exchange_rate: {
437
+ base: '1.000 HBD',
438
+ quote: '4.123 HIVE'
439
+ }
440
+ }
441
+
442
+ @transaction.operations << op
443
+
444
+ refute_nil bytes = @transaction.send(:to_bytes)
445
+ hex = hexlify(bytes)
446
+ hex_segments = seg(hex).merge(
447
+ publisher: hex[88..99],
448
+ exchange_rate: hex[100..159]
449
+ )
450
+
451
+ decoded_op_id = "0x#{hex_segments[:op_id]}".to_i(16)
452
+ op_type = "#{op[:type]}_operation".to_sym
453
+ assert_equal Radiator::OperationIds::IDS.find_index(op_type), decoded_op_id
454
+
455
+ assert_equal '07', hex_segments[:op_id], 'expect op_id'
456
+ assert_equal '057865726f63', hex_segments[:publisher], 'expect publisher'
457
+ assert_equal 'e80300000000000003484244000000001b10000000000000034849564500', hex_segments[:exchange_rate], 'expect exchange_rate'
458
+
459
+ compare = 'f68585abf4dce7c804570107057865726f63e803000000000' +
460
+ '00003484244000000001b1000000000000003484956450000' +
461
+ '000001203847a02aa76964cacfb41565c23286cc64b18f6bb' +
462
+ '9260832823839b3b90dff18738e1b686ad22f79c42fca73e6' +
463
+ '1bf633505a2a66cac65555b0ac535ca5ee5a61'
464
+
465
+ op_hex = sub_hex(hex_segments)
466
+ assert compare.include?(op_hex), 'expect final comparison from original test'
467
+ end
468
+
469
+ # See: https://github.com/steemit/steem-python/blob/master/tests/steem/test_transactions.py#L650
470
+ def test_account_witness_vote
471
+ op = {
472
+ type: :account_witness_vote,
473
+ account: 'xeroc',
474
+ witness: 'chainsquad',
475
+ approve: true
476
+ }
477
+
478
+ @transaction.operations << op
479
+
480
+ refute_nil bytes = @transaction.send(:to_bytes)
481
+ hex = hexlify(bytes)
482
+ hex_segments = seg(hex).merge(
483
+ account: hex[88..99],
484
+ witness: hex[100..121],
485
+ approve: hex[122..123]
486
+ )
487
+
488
+ decoded_op_id = "0x#{hex_segments[:op_id]}".to_i(16)
489
+ op_type = "#{op[:type]}_operation".to_sym
490
+ assert_equal Radiator::OperationIds::IDS.find_index(op_type), decoded_op_id
491
+
492
+ assert_equal '0c', hex_segments[:op_id], 'expect op_id'
493
+ assert_equal '057865726f63', hex_segments[:account], 'expect account'
494
+ assert_equal '0a636861696e7371756164', hex_segments[:witness], 'expect witness'
495
+ assert_equal '01', hex_segments[:approve], 'expect approve'
496
+
497
+ compare = 'f68585abf4dce7c80457010c057865726f630a636' +
498
+ '861696e73717561640100011f16b43411e11f4739' +
499
+ '4c1624a3c4d3cf4daba700b8690f494e6add7ad9b' +
500
+ 'ac735ce7775d823aa66c160878cb3348e6857c531' +
501
+ '114d229be0202dc0857f8f03a00369'
502
+
503
+ op_hex = sub_hex(hex_segments)
504
+ assert compare.include?(op_hex), 'expect final comparison from original test'
505
+ end
506
+
507
+ # See: https://github.com/steemit/steem-python/blob/master/tests/steem/test_transactions.py#L673
508
+ def test_custom_json
509
+ op = {
510
+ type: :custom_json,
511
+ required_auths: [],
512
+ required_posting_auths: ['xeroc'],
513
+ id: 'follow',
514
+ json: '["reblog", {"account": "xeroc", "author": "chainsquad", "permlink": "streemian-com-to-open-its-doors-and-offer-a-20-discount"}]'
515
+ }
516
+
517
+ @transaction.operations << op
518
+
519
+ refute_nil bytes = @transaction.send(:to_bytes)
520
+ hex = hexlify(bytes)
521
+ hex_segments = seg(hex).merge(
522
+ required_auths: hex[88..89],
523
+ required_posting_auths: hex[90..103],
524
+ id: hex[104..117],
525
+ json: hex[118..373]
526
+ )
527
+
528
+ decoded_op_id = "0x#{hex_segments[:op_id]}".to_i(16)
529
+ op_type = "#{op[:type]}_operation".to_sym
530
+ assert_equal Radiator::OperationIds::IDS.find_index(op_type), decoded_op_id
531
+
532
+ assert_equal '12', hex_segments[:op_id], 'expect op_id'
533
+ assert_equal '00', hex_segments[:required_auths], 'expect required_auths'
534
+ assert_equal '01057865726f63', hex_segments[:required_posting_auths], 'expect required_posting_auths'
535
+ assert_equal '06666f6c6c6f77', hex_segments[:id], 'expect id'
536
+ assert_equal '7f5b227265626c6f67222c207b226163636f756e74223a20227865726f63222c2022617574686f72223a2022636861696e7371756164222c20227065726d6c696e6b223a202273747265656d69616e2d636f6d2d746f2d6f70656e2d6974732d646f6f72732d616e642d6f666665722d612d32302d646973636f756e74227d5d',
537
+ hex_segments[:json], 'expect json'
538
+
539
+ compare = 'f68585abf4dce7c8045701120001057865726f6306666f6c6c' +
540
+ '6f777f5b227265626c6f67222c207b226163636f756e74223a' +
541
+ '20227865726f63222c2022617574686f72223a202263686169' +
542
+ '6e7371756164222c20227065726d6c696e6b223a2022737472' +
543
+ '65656d69616e2d636f6d2d746f2d6f70656e2d6974732d646f' +
544
+ '6f72732d616e642d6f666665722d612d32302d646973636f75' +
545
+ '6e74227d5d00011f0cffad16cfd8ea4b84c06d412e93a9fc10' +
546
+ '0bf2fac5f9a40d37d5773deef048217db79cabbf15ef29452d' +
547
+ 'e4ed1c5face51d998348188d66eb9fc1ccef79a0c0d4'
548
+
549
+ op_hex = sub_hex(hex_segments)
550
+ assert compare.include?(op_hex), 'expect final comparison from original test'
551
+ end
552
+
553
+ # See: https://github.com/steemit/steem-python/blob/master/tests/steem/test_transactions.py#L708
554
+ def test_comment_options
555
+ op = {
556
+ type: :comment_options,
557
+ author: 'xeroc',
558
+ permlink: 'piston',
559
+ max_accepted_payout: '1000000.000 HBD',
560
+ percent_hbd: 10000,
561
+ allow_votes: true,
562
+ allow_curation_rewards: true,
563
+ extensions: []
564
+ }
565
+
566
+ @transaction.operations << op
567
+
568
+ refute_nil bytes = @transaction.send(:to_bytes)
569
+ hex = hexlify(bytes)
570
+ hex_segments = seg(hex).merge(
571
+ author: hex[88..99],
572
+ permlink: hex[100..113],
573
+ max_accepted_payout: hex[114..145],
574
+ percent_hbd: hex[146..149],
575
+ allow_votes: hex[150..151],
576
+ allow_curation_rewards: hex[152..153],
577
+ op_extensions: hex[154..155]
578
+ )
579
+
580
+ decoded_op_id = "0x#{hex_segments[:op_id]}".to_i(16)
581
+ op_type = "#{op[:type]}_operation".to_sym
582
+ assert_equal Radiator::OperationIds::IDS.find_index(op_type), decoded_op_id
583
+
584
+ assert_equal '13', hex_segments[:op_id], 'expect op_id'
585
+ assert_equal '057865726f63', hex_segments[:author], 'expect author'
586
+ assert_equal '06706973746f6e', hex_segments[:permlink], 'expect permlink'
587
+ assert_equal '00ca9a3b000000000348424400000000', hex_segments[:max_accepted_payout], 'expect max_accepted_payout'
588
+ assert_equal '1027', hex_segments[:percent_hbd], 'expect percent_hbd'
589
+ assert_equal '01', hex_segments[:allow_votes], 'expect allow_votes'
590
+ assert_equal '01', hex_segments[:allow_curation_rewards], 'expect allow_curation_rewards'
591
+ assert_equal '00', hex_segments[:op_extensions], 'expect op_extensions'
592
+
593
+ compare = 'f68585abf4dce7c804570113057865726f6306706973746f6e' +
594
+ '00ca9a3b000000000348424400000000102701010000011f20' +
595
+ 'feacc3f917dfa2d6082afb5ab5aab82d7df1428130c7b7eec4' +
596
+ '56d259e59fc54ee582a5a86073508f69ffebea4283f13d1a89' +
597
+ '6243754a4a82fa18077f832225'
598
+
599
+ op_hex = sub_hex(hex_segments)
600
+ assert compare.include?(op_hex), 'expect final comparison from original test'
601
+ end
602
+
603
+ # See: https://github.com/steemit/steem-python/blob/master/tests/steem/test_transactions.py#L738
604
+ def test_comment_options_with_beneficiaries
605
+ op = {
606
+ type: :comment_options,
607
+ author: 'xeroc',
608
+ permlink: 'piston',
609
+ max_accepted_payout: '1000000.000 HBD',
610
+ percent_hbd: 10000,
611
+ allow_replies: true,
612
+ allow_votes: true,
613
+ allow_curation_rewards: true,
614
+ extensions: Radiator::Type::Beneficiaries.new('good-karma' => 2000, 'null' => 5000)
615
+ }
616
+
617
+ @transaction.operations << op
618
+
619
+ refute_nil bytes = @transaction.send(:to_bytes)
620
+ hex = hexlify(bytes)
621
+ hex_segments = seg(hex).merge(
622
+ author: hex[88..99],
623
+ permlink: hex[100..113],
624
+ max_accepted_payout: hex[114..145],
625
+ percent_hbd: hex[146..149],
626
+ allow_replies: hex[150..151],
627
+ allow_votes: hex[152..153],
628
+ allow_curation_rewards: hex[154..155],
629
+ op_extensions: hex[156..199]
630
+ )
631
+
632
+ decoded_op_id = "0x#{hex_segments[:op_id]}".to_i(16)
633
+ op_type = "#{op[:type]}_operation".to_sym
634
+ assert_equal Radiator::OperationIds::IDS.find_index(op_type), decoded_op_id
635
+
636
+ assert_equal '13', hex_segments[:op_id], 'expect op_id'
637
+ assert_equal '057865726f63', hex_segments[:author], 'expect author'
638
+ assert_equal '06706973746f6e', hex_segments[:permlink], 'expect permlink'
639
+ assert_equal '00ca9a3b000000000348424400000000', hex_segments[:max_accepted_payout], 'expect max_accepted_payout'
640
+ assert_equal '1027', hex_segments[:percent_hbd], 'expect percent_hbd'
641
+ assert_equal '01', hex_segments[:allow_replies], 'expect allow_replies'
642
+ assert_equal '01', hex_segments[:allow_votes], 'expect allow_votes'
643
+ assert_equal '01', hex_segments[:allow_curation_rewards], 'expect allow_curation_rewards'
644
+ assert_equal '0100020a676f6f642d6b61726d61d007046e756c6c88',
645
+ hex_segments[:op_extensions], 'expect op_extensions'
646
+
647
+ compare = 'f68585abf4dce7c804570113057865726f6306706973746f6e' +
648
+ '00ca9a3b00000000034842440000000010270101010100020a676f6f64' +
649
+ '2d6b61726d61d007046e756c6c8800011f59634e65' +
650
+ '55fec7c01cb7d4921601c37c250c6746022cc35eaefdd90405' +
651
+ 'd7771b2f65b44e97b7f3159a6d52cb20640502d2503437215f' +
652
+ '0907b2e2213940f34f2c'
653
+
654
+ op_hex = sub_hex(hex_segments)
655
+ assert compare.include?(op_hex), 'expect final comparison from original test'
656
+ end
657
+
658
+ def test_chronicle_comment_options
659
+ op = {
660
+ type: :comment_options,
661
+ max_accepted_payout: '1000000.000 HBD',
662
+ percent_hbd: 10000,
663
+ allow_replies: true,
664
+ allow_votes: true,
665
+ allow_curation_rewards: true,
666
+ beneficiaries: [{"inertia":500}],
667
+ author: "social",
668
+ permlink: "lorem-ipsum4",
669
+ extensions: Radiator::Type::Beneficiaries.new(inertia: 500)
670
+ }
671
+
672
+ @transaction.operations << op
673
+
674
+ refute_nil bytes = @transaction.send(:to_bytes)
675
+ hex = hexlify(bytes)
676
+ hex_segments = seg(hex).merge(
677
+ author: hex[88..101],
678
+ permlink: hex[102..127],
679
+ max_accepted_payout: hex[128..159],
680
+ percent_hbd: hex[160..163],
681
+ allow_replies: hex[164..165],
682
+ allow_votes: hex[166..167],
683
+ allow_curation_rewards: hex[168..169],
684
+ op_extensions: hex[170..193]
685
+ )
686
+
687
+ decoded_op_id = "0x#{hex_segments[:op_id]}".to_i(16)
688
+ op_type = "#{op[:type]}_operation".to_sym
689
+ assert_equal Radiator::OperationIds::IDS.find_index(op_type), decoded_op_id
690
+
691
+ assert_equal '13', hex_segments[:op_id], 'expect op_id'
692
+ assert_equal '06736f6369616c', hex_segments[:author], 'expect author'
693
+ assert_equal '0c6c6f72656d2d697073756d34', hex_segments[:permlink], 'expect permlink'
694
+ assert_equal '00ca9a3b000000000348424400000000', hex_segments[:max_accepted_payout], 'expect max_accepted_payout'
695
+ assert_equal '1027', hex_segments[:percent_hbd], 'expect percent_hbd'
696
+ assert_equal '01', hex_segments[:allow_replies], 'expect allow_replies'
697
+ assert_equal '01', hex_segments[:allow_votes], 'expect allow_votes'
698
+ assert_equal '01', hex_segments[:allow_curation_rewards], 'expect allow_curation_rewards'
699
+ assert_equal '01000107696e6572746961f4', hex_segments[:op_extensions], 'expect op_extensions'
700
+ end
701
+
702
+ def test_operations_assignment
703
+ @transaction.operations = [{type: :vote}]
704
+
705
+ assert_equal Operation, @transaction.operations.first.class
706
+ end
707
+
708
+ def test_expiration_initialize
709
+ vcr_cassette('expiration_initialize') do
710
+ exp = Time.now.utc
711
+ tx = Transaction.new(expiration: exp)
712
+
713
+ assert_equal exp, tx.expiration
714
+ end
715
+ end
716
+
717
+ def test_expiration_initialize_nil
718
+ vcr_cassette('transaction_expiration_initialize_nil') do
719
+ tx = Transaction.new
720
+
721
+ assert_nil tx.expiration
722
+ end
723
+ end
724
+
725
+ def test_payload_persists_until_reprepared
726
+ @transaction.send :prepare
727
+ expected_payload = @transaction.send :payload
728
+ assert_equal expected_payload, @transaction.send(:payload)
729
+ @transaction.send :prepare
730
+ refute_equal expected_payload, @transaction.send(:payload)
731
+ end
732
+ private
733
+ def seg(hex)
734
+ seg = {
735
+ chain_id: hex[0..63], ref_block_num: hex[64..67],
736
+ ref_block_prefix: hex[68..75], exp: hex[76..83], op_len: hex[84..85],
737
+ op_id: hex[86..87], extensions: hex[(hex.size - 2)..hex.size]
738
+ }
739
+
740
+ seg.tap do |s|
741
+ assert_equal Radiator::ChainConfig::NETWORKS_HIVE_CHAIN_ID, s[:chain_id], 'expect chain_id'
742
+ assert_equal 'bd8c', s[:ref_block_num], 'expect ref_block_num'
743
+ assert_equal '5fe26f45', s[:ref_block_prefix], 'expect ref_block_prefix'
744
+ assert_equal 'f179a857', s[:exp], 'expect exp'
745
+ assert_equal '01', s[:op_len], 'expect op_len'
746
+ assert_equal '00', s[:extensions], 'expect extensions'
747
+ end
748
+ end
749
+
750
+ def sub_hex(segments)
751
+ exclude = %i(chain_id ref_block_num ref_block_prefix exp op_len op_id extensions)
752
+ segments.map { |k, v| v unless exclude.include? k }.compact.join
753
+ end
754
+ end
755
+ end