radiator 0.4.4 → 0.4.8.pre.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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 '0000000000000000000000000000000000000000000000000000000000000000',
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 '0000000000000000000000000000000000000000000000000000000000000000',
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 'ccbcb7d64444356654febe83b8010ca50d99edd0389d273b63746ecaf21adb92', 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 '582176b1daf89984bc8b4fdcb24ff1433d1eb114a8c4bf20fb22ad580d035889', 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 SBD',
438
+ quote: '4.123 STEEM'
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 'e80300000000000003534244000000001b1000000000000003535445454d', hex_segments[:exchange_rate], 'expect exchange_rate'
458
+
459
+ compare = 'f68585abf4dce7c804570107057865726f63e803000000000' +
460
+ '00003534244000000001b1000000000000003535445454d00' +
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 SBD',
560
+ percent_steem_dollars: 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_steem_dollars: 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 '00ca9a3b000000000353424400000000', hex_segments[:max_accepted_payout], 'expect max_accepted_payout'
588
+ assert_equal '1027', hex_segments[:percent_steem_dollars], 'expect percent_steem_dollars'
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
+ '00ca9a3b000000000353424400000000102701010000011f20' +
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 SBD',
610
+ percent_steem_dollars: 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_steem_dollars: 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 '00ca9a3b000000000353424400000000', hex_segments[:max_accepted_payout], 'expect max_accepted_payout'
640
+ assert_equal '1027', hex_segments[:percent_steem_dollars], 'expect percent_steem_dollars'
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
+ '00ca9a3b00000000035342440000000010270101010100020a676f6f64' +
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 SBD',
662
+ percent_steem_dollars: 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_steem_dollars: 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 '00ca9a3b000000000353424400000000', hex_segments[:max_accepted_payout], 'expect max_accepted_payout'
695
+ assert_equal '1027', hex_segments[:percent_steem_dollars], 'expect percent_steem_dollars'
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 '0' * 64, 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