nanook 2.5.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +99 -0
- data/README.md +135 -85
- data/bin/console +4 -3
- data/lib/nanook.rb +76 -20
- data/lib/nanook/account.rb +232 -164
- data/lib/nanook/block.rb +343 -150
- data/lib/nanook/errors.rb +10 -0
- data/lib/nanook/node.rb +164 -132
- data/lib/nanook/private_key.rb +115 -0
- data/lib/nanook/public_key.rb +55 -0
- data/lib/nanook/rpc.rb +104 -44
- data/lib/nanook/util.rb +67 -18
- data/lib/nanook/version.rb +3 -1
- data/lib/nanook/wallet.rb +348 -161
- data/lib/nanook/wallet_account.rb +148 -88
- data/lib/nanook/work_peer.rb +14 -7
- metadata +20 -18
- data/lib/nanook/error.rb +0 -5
- data/lib/nanook/key.rb +0 -46
data/lib/nanook/block.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'util'
|
2
4
|
|
5
|
+
class Nanook
|
3
6
|
# The <tt>Nanook::Block</tt> class contains methods to discover
|
4
7
|
# publicly-available information about blocks on the nano network.
|
5
8
|
#
|
@@ -17,21 +20,38 @@ class Nanook
|
|
17
20
|
# rpc_conn = Nanook::Rpc.new
|
18
21
|
# block = Nanook::Block.new(rpc_conn, "FBF8B0E...")
|
19
22
|
class Block
|
23
|
+
include Nanook::Util
|
20
24
|
|
21
25
|
def initialize(rpc, block)
|
22
26
|
@rpc = rpc
|
23
|
-
@block = block
|
24
|
-
block_required! # All methods expect a block
|
27
|
+
@block = block.to_s
|
25
28
|
end
|
26
29
|
|
27
|
-
# Returns the
|
30
|
+
# Returns the block hash id.
|
28
31
|
#
|
29
32
|
# ==== Example:
|
30
|
-
# block.account # => Nanook::Account
|
31
33
|
#
|
32
|
-
#
|
33
|
-
|
34
|
-
|
34
|
+
# block.id #=> "FBF8B0E..."
|
35
|
+
#
|
36
|
+
# @return [String] the block hash id
|
37
|
+
def id
|
38
|
+
@block
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param other [Nanook::Block] block to compare
|
42
|
+
# @return [Boolean] true if blocks are equal
|
43
|
+
def ==(other)
|
44
|
+
other.class == self.class &&
|
45
|
+
other.id == id
|
46
|
+
end
|
47
|
+
alias eql? ==
|
48
|
+
|
49
|
+
# The hash value is used along with #eql? by the Hash class to determine if two objects
|
50
|
+
# reference the same hash key.
|
51
|
+
#
|
52
|
+
# @return [Integer]
|
53
|
+
def hash
|
54
|
+
id.hash
|
35
55
|
end
|
36
56
|
|
37
57
|
# Stop generating work for a block.
|
@@ -59,58 +79,36 @@ class Nanook
|
|
59
79
|
#
|
60
80
|
# ==== Example reponse:
|
61
81
|
#
|
62
|
-
# [
|
63
|
-
# "36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E",
|
64
|
-
# "FBF8B0E6623A31AB528EBD839EEAA91CAFD25C12294C46754E45FD017F7939EB"
|
65
|
-
# ]
|
82
|
+
# [Nanook::Block, ...]
|
66
83
|
#
|
67
84
|
# @param limit [Integer] maximum number of block hashes to return (default is 1000)
|
68
85
|
# @param offset [Integer] return the account chain block hashes offset by the specified number of blocks (default is 0)
|
69
86
|
def chain(limit: 1000, offset: 0)
|
70
|
-
|
71
|
-
|
87
|
+
params = {
|
88
|
+
count: limit,
|
89
|
+
offset: offset,
|
90
|
+
_access: :blocks,
|
91
|
+
_coerce: Array
|
92
|
+
}
|
93
|
+
|
94
|
+
rpc(:chain, :block, params).map do |block|
|
95
|
+
as_block(block)
|
96
|
+
end
|
72
97
|
end
|
73
|
-
|
98
|
+
alias ancestors chain
|
74
99
|
|
75
100
|
# Request confirmation for a block from online representative nodes.
|
76
101
|
# Will return immediately with a boolean to indicate if the request for
|
77
102
|
# confirmation was successful. Note that this boolean does not indicate
|
78
|
-
# the confirmation status of the block.
|
79
|
-
# appear in {Nanook::Node#confirmation_history} within a short amount of
|
80
|
-
# time, or you can use the convenience method {Nanook::Block#confirmed_recently?}
|
103
|
+
# the confirmation status of the block.
|
81
104
|
#
|
82
105
|
# ==== Example:
|
83
106
|
# block.confirm # => true
|
84
107
|
#
|
85
108
|
# @return [Boolean] if the confirmation request was sent successful
|
86
109
|
def confirm
|
87
|
-
rpc(:block_confirm, :hash
|
88
|
-
end
|
89
|
-
|
90
|
-
# This call is for internal diagnostics/debug purposes only. Do not
|
91
|
-
# rely on this interface being stable and do not use in a production system.
|
92
|
-
#
|
93
|
-
# Check if the block appears in the list of recently confirmed blocks by
|
94
|
-
# online representatives. The full list of blocks can be queried for with {Nanook::Node#confirmation_history}.
|
95
|
-
#
|
96
|
-
# This method can work in conjunction with {Nanook::Block#confirm},
|
97
|
-
# whereby you can send any block (old or new) out to online representatives to
|
98
|
-
# confirm. The confirmation process can take up to a couple of minutes.
|
99
|
-
#
|
100
|
-
# The method returning +false+ can indicate that the block is still in the process of being
|
101
|
-
# confirmed and that you should call the method again soon, or that it
|
102
|
-
# was confirmed earlier than the list available in {Nanook::Node#confirmation_history},
|
103
|
-
# or that it was not confirmed.
|
104
|
-
#
|
105
|
-
# ==== Example:
|
106
|
-
# block.confirmed_recently? # => true
|
107
|
-
#
|
108
|
-
# @return [Boolean] +true+ if the block has been recently confirmed by
|
109
|
-
# online representatives.
|
110
|
-
def confirmed_recently?
|
111
|
-
@rpc.call(:confirmation_history)[:confirmations].map{|h| h[:hash]}.include?(@block)
|
110
|
+
rpc(:block_confirm, :hash, _access: :started) == 1
|
112
111
|
end
|
113
|
-
alias_method :recently_confirmed?, :confirmed_recently?
|
114
112
|
|
115
113
|
# Generate work for a block.
|
116
114
|
#
|
@@ -122,42 +120,7 @@ class Nanook
|
|
122
120
|
# When +false+, the node will only generate work locally (default is +false+)
|
123
121
|
# @return [String] the work id of the work completed.
|
124
122
|
def generate_work(use_peers: false)
|
125
|
-
rpc(:work_generate, :hash, use_peers: use_peers
|
126
|
-
end
|
127
|
-
|
128
|
-
# Returns Array of Hashes containing information about a chain of
|
129
|
-
# send/receive blocks, starting from this block.
|
130
|
-
#
|
131
|
-
# ==== Example:
|
132
|
-
#
|
133
|
-
# block.history(limit: 1)
|
134
|
-
#
|
135
|
-
# ==== Example response:
|
136
|
-
#
|
137
|
-
# [
|
138
|
-
# {
|
139
|
-
# :account=>"nano_3x7cjioqahgs5ppheys6prpqtb4rdknked83chf97bot1unrbdkaux37t31b",
|
140
|
-
# :amount=>539834279601145558517940224,
|
141
|
-
# :hash=>"36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E",
|
142
|
-
# :type=>"send"
|
143
|
-
# }
|
144
|
-
# ]
|
145
|
-
#
|
146
|
-
# @param limit [Integer] maximum number of send/receive block hashes
|
147
|
-
# to return in the chain (default is 1000)
|
148
|
-
def history(limit: 1000)
|
149
|
-
rpc(:history, :hash, count: limit)[:history]
|
150
|
-
end
|
151
|
-
|
152
|
-
# Returns the block hash id.
|
153
|
-
#
|
154
|
-
# ==== Example:
|
155
|
-
#
|
156
|
-
# block.id #=> "FBF8B0E..."
|
157
|
-
#
|
158
|
-
# @return [String] the block hash id
|
159
|
-
def id
|
160
|
-
@block
|
123
|
+
rpc(:work_generate, :hash, use_peers: use_peers, _access: :work)
|
161
124
|
end
|
162
125
|
|
163
126
|
# Returns a Hash of information about the block.
|
@@ -170,65 +133,84 @@ class Nanook
|
|
170
133
|
# ==== Example response:
|
171
134
|
#
|
172
135
|
# {
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
179
|
-
# :
|
136
|
+
# "account": Nanook::Account,
|
137
|
+
# "amount": 34.2,
|
138
|
+
# "balance": 2.3
|
139
|
+
# "height": 58,
|
140
|
+
# "local_timestamp": Time,
|
141
|
+
# "confirmed": true,
|
142
|
+
# "type": "send",
|
143
|
+
# "account": Nanook::Account,
|
144
|
+
# "previous": Nanook::Block,
|
145
|
+
# "representative": Nanook::Account,
|
146
|
+
# "link": Nanook::Block,
|
147
|
+
# "link_as_account": Nanook::Account,
|
148
|
+
# "signature": "82D41BC16F313E4B2243D14DFFA2FB04679C540C2095FEE7EAE0F2F26880AD56DD48D87A7CC5DD760C5B2D76EE2C205506AA557BF00B60D8DEE312EC7343A501",
|
149
|
+
# "work": "8a142e07a10996d5"
|
180
150
|
# }
|
181
151
|
#
|
182
152
|
# @param allow_unchecked [Boolean] (default is +false+). If +true+,
|
183
153
|
# information can be returned about blocks that are unchecked (unverified).
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
154
|
+
# @raise [Nanook::NanoUnitError] if `unit` is invalid
|
155
|
+
# @raise [Nanook::NodeRpcError] if block is not found on the node.
|
156
|
+
def info(allow_unchecked: false, unit: Nanook.default_unit)
|
157
|
+
validate_unit!(unit)
|
158
|
+
|
159
|
+
# Params for both `unchecked_get` and `block_info` calls
|
160
|
+
params = {
|
161
|
+
json_block: true,
|
162
|
+
_coerce: Hash
|
163
|
+
}
|
164
|
+
|
165
|
+
begin
|
166
|
+
response = rpc(:block_info, :hash, params)
|
167
|
+
response.merge!(confirmed: true)
|
168
|
+
rescue Nanook::NodeRpcError => e
|
169
|
+
raise e unless allow_unchecked
|
170
|
+
|
171
|
+
response = rpc(:unchecked_get, :hash, params)
|
172
|
+
response.merge!(confirmed: false)
|
191
173
|
end
|
192
174
|
|
193
|
-
response
|
194
|
-
_parse_info_response(response)
|
175
|
+
parse_info_response(response, unit)
|
195
176
|
end
|
196
177
|
|
197
178
|
# ==== Example:
|
198
179
|
#
|
199
|
-
# block.
|
180
|
+
# block.valid_work?("2bf29ef00786a6bc") # => true
|
200
181
|
#
|
201
182
|
# @param work [String] the work id to check is valid
|
202
183
|
# @return [Boolean] signalling if work is valid for the block
|
203
|
-
def
|
184
|
+
def valid_work?(work)
|
204
185
|
response = rpc(:work_validate, :hash, work: work)
|
205
|
-
|
186
|
+
response[:valid_all] == 1 || response[:valid_receive] == 1
|
206
187
|
end
|
207
188
|
|
208
189
|
# Republish blocks starting at this block up the account chain
|
209
190
|
# back to the nano network.
|
210
191
|
#
|
211
|
-
# @return [Array<
|
192
|
+
# @return [Array<Nanook::Block>] blocks that were republished
|
212
193
|
#
|
213
194
|
# ==== Example:
|
214
195
|
#
|
215
|
-
# block.republish
|
216
|
-
|
217
|
-
# ==== Example response:
|
218
|
-
#
|
219
|
-
# ["36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E"]
|
220
|
-
def republish(destinations:nil, sources:nil)
|
196
|
+
# block.republish # => [Nanook::Block, ...]
|
197
|
+
def republish(destinations: nil, sources: nil)
|
221
198
|
if !destinations.nil? && !sources.nil?
|
222
|
-
raise ArgumentError
|
199
|
+
raise ArgumentError, 'You must provide either destinations or sources but not both'
|
223
200
|
end
|
224
201
|
|
225
|
-
|
226
|
-
|
202
|
+
params = {
|
203
|
+
_access: :blocks,
|
204
|
+
_coerce: Array
|
205
|
+
}
|
206
|
+
|
227
207
|
params[:destinations] = destinations unless destinations.nil?
|
228
208
|
params[:sources] = sources unless sources.nil?
|
229
|
-
params[:count] = 1
|
209
|
+
params[:count] = 1 if destinations || sources
|
230
210
|
|
231
|
-
rpc(:republish, :hash, params)
|
211
|
+
rpc(:republish, :hash, params).map do |block|
|
212
|
+
as_block(block)
|
213
|
+
end
|
232
214
|
end
|
233
215
|
|
234
216
|
# ==== Example:
|
@@ -237,24 +219,9 @@ class Nanook
|
|
237
219
|
#
|
238
220
|
# @return [Boolean] signalling if the block is a pending block.
|
239
221
|
def pending?
|
240
|
-
|
241
|
-
!response.empty? && response[:exists] == 1
|
222
|
+
rpc(:pending_exists, :hash, _access: :exists) == 1
|
242
223
|
end
|
243
224
|
|
244
|
-
# Publish the block to the nano network.
|
245
|
-
#
|
246
|
-
# Note, if block has previously been published, use #republish instead.
|
247
|
-
#
|
248
|
-
# ==== Examples:
|
249
|
-
#
|
250
|
-
# block.publish # => "FBF8B0E..."
|
251
|
-
#
|
252
|
-
# @return [String] the block hash, or false.
|
253
|
-
def publish
|
254
|
-
rpc(:process, :block)[:hash] || false
|
255
|
-
end
|
256
|
-
alias_method :process, :publish
|
257
|
-
|
258
225
|
# Returns an Array of block hashes in the account chain ending at
|
259
226
|
# this block.
|
260
227
|
#
|
@@ -262,51 +229,277 @@ class Nanook
|
|
262
229
|
#
|
263
230
|
# ==== Example:
|
264
231
|
#
|
265
|
-
# block.successors
|
266
|
-
#
|
267
|
-
# ==== Example response:
|
268
|
-
#
|
269
|
-
# ["36A0FB717368BA8CF8D255B63DC207771EABC6C6FFC22A7F455EC2209464897E"]
|
232
|
+
# block.successors # => [Nanook::Block, .. ]
|
270
233
|
#
|
271
234
|
# @param limit [Integer] maximum number of send/receive block hashes
|
272
235
|
# to return in the chain (default is 1000)
|
273
236
|
# @param offset [Integer] return the account chain block hashes offset
|
274
237
|
# by the specified number of blocks (default is 0)
|
275
|
-
# @return [Array<
|
238
|
+
# @return [Array<Nanook::Block>] blocks in the account chain ending at this block
|
276
239
|
def successors(limit: 1000, offset: 0)
|
277
|
-
|
278
|
-
|
240
|
+
params = {
|
241
|
+
count: limit,
|
242
|
+
offset: offset,
|
243
|
+
_access: :blocks,
|
244
|
+
_coerce: Array
|
245
|
+
}
|
246
|
+
|
247
|
+
rpc(:successors, :block, params).map do |block|
|
248
|
+
as_block(block)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# Returns the {Nanook::Account} of the block representative.
|
253
|
+
#
|
254
|
+
# ==== Example:
|
255
|
+
# block.representative # => Nanook::Account
|
256
|
+
#
|
257
|
+
# @return [Nanook::Account] representative account of the block. Can be nil.
|
258
|
+
def representative
|
259
|
+
memoized_info[:representative]
|
260
|
+
end
|
261
|
+
|
262
|
+
# Returns the {Nanook::Account} of the block.
|
263
|
+
#
|
264
|
+
# ==== Example:
|
265
|
+
# block.account # => Nanook::Account
|
266
|
+
#
|
267
|
+
# @return [Nanook::Account] the account of the block. Can be nil.
|
268
|
+
def account
|
269
|
+
memoized_info[:account]
|
270
|
+
end
|
271
|
+
|
272
|
+
# Returns the amount of the block.
|
273
|
+
#
|
274
|
+
# ==== Example:
|
275
|
+
# block.amount # => 3.01
|
276
|
+
#
|
277
|
+
# @param unit (see Nanook::Account#balance)
|
278
|
+
# @raise [Nanook::NanoUnitError] if `unit` is invalid
|
279
|
+
# @return [Float]
|
280
|
+
def amount(unit: Nanook.default_unit)
|
281
|
+
validate_unit!(unit)
|
282
|
+
|
283
|
+
amount = memoized_info[:amount]
|
284
|
+
return amount unless unit == :nano
|
285
|
+
|
286
|
+
raw_to_NANO(amount)
|
287
|
+
end
|
288
|
+
|
289
|
+
# Returns the balance of the account at the time the block was created.
|
290
|
+
#
|
291
|
+
# ==== Example:
|
292
|
+
# block.balance # => 3.01
|
293
|
+
#
|
294
|
+
# @param unit (see Nanook::Account#balance)
|
295
|
+
# @raise [Nanook::NanoUnitError] if `unit` is invalid
|
296
|
+
# @return [Float]
|
297
|
+
def balance(unit: Nanook.default_unit)
|
298
|
+
validate_unit!(unit)
|
299
|
+
|
300
|
+
balance = memoized_info[:balance]
|
301
|
+
return balance unless unit == :nano
|
302
|
+
|
303
|
+
raw_to_NANO(balance)
|
304
|
+
end
|
305
|
+
|
306
|
+
# Returns true if block is confirmed.
|
307
|
+
#
|
308
|
+
# ==== Example:
|
309
|
+
# block.confirmed # => true
|
310
|
+
#
|
311
|
+
# @return [Boolean]
|
312
|
+
def confirmed?
|
313
|
+
memoized_info[:confirmed]
|
314
|
+
end
|
315
|
+
alias checked? confirmed?
|
316
|
+
|
317
|
+
# Returns true if block is unconfirmed.
|
318
|
+
#
|
319
|
+
# ==== Example:
|
320
|
+
# block.unconfirmed? # => true
|
321
|
+
#
|
322
|
+
# @return [Boolean]
|
323
|
+
def unconfirmed?
|
324
|
+
!confirmed?
|
325
|
+
end
|
326
|
+
alias unchecked? unconfirmed?
|
327
|
+
|
328
|
+
# Returns true if block exists in the node's ledger. This will return
|
329
|
+
# false for blocks that exist on the nano ledger but have not yet
|
330
|
+
# synchronized to the node.
|
331
|
+
#
|
332
|
+
# ==== Example:
|
333
|
+
#
|
334
|
+
# block.exists? # => false
|
335
|
+
# block.exists?(allow_unchecked: true) # => true
|
336
|
+
#
|
337
|
+
# @param allow_unchecked [Boolean] defaults to +false+
|
338
|
+
# @return [Boolean]
|
339
|
+
def exists?(allow_unchecked: false)
|
340
|
+
begin
|
341
|
+
allow_unchecked ? memoized_info : info
|
342
|
+
rescue Nanook::NodeRpcError
|
343
|
+
return false
|
344
|
+
end
|
345
|
+
|
346
|
+
true
|
347
|
+
end
|
348
|
+
|
349
|
+
# Returns the height of the block.
|
350
|
+
#
|
351
|
+
# ==== Example:
|
352
|
+
# block.height # => 5
|
353
|
+
#
|
354
|
+
# @return [Integer]
|
355
|
+
def height
|
356
|
+
memoized_info[:height]
|
357
|
+
end
|
358
|
+
|
359
|
+
# Returns the block work.
|
360
|
+
#
|
361
|
+
# ==== Example:
|
362
|
+
# block.work # => "8a142e07a10996d5"
|
363
|
+
#
|
364
|
+
# @return [String]
|
365
|
+
def work
|
366
|
+
memoized_info[:work]
|
279
367
|
end
|
280
368
|
|
281
|
-
|
282
|
-
|
369
|
+
# Returns the block signature.
|
370
|
+
#
|
371
|
+
# ==== Example:
|
372
|
+
# block.signature # => "82D41BC16F313E4B2243D14DFFA2FB04679C540C2095FEE7EAE0F2F26880AD56DD48D87A7CC5DD760C5B2D76EE2C205506AA557BF00B60D8DEE312EC7343A501"
|
373
|
+
#
|
374
|
+
# @return [String]
|
375
|
+
def signature
|
376
|
+
memoized_info[:signature]
|
283
377
|
end
|
284
378
|
|
379
|
+
# Returns the timestamp of when the node saw the block.
|
380
|
+
#
|
381
|
+
# ==== Example:
|
382
|
+
# block.timestamp # => 2018-05-30 16:41:48 UTC
|
383
|
+
#
|
384
|
+
# @return [Time] Time in UTC of when the node saw the block. Can be nil.
|
385
|
+
def timestamp
|
386
|
+
memoized_info[:local_timestamp]
|
387
|
+
end
|
388
|
+
|
389
|
+
# Returns the {Nanook::Block} of the previous block in the chain.
|
390
|
+
#
|
391
|
+
# ==== Example:
|
392
|
+
# block.previous # => Nanook::Block
|
393
|
+
#
|
394
|
+
# @return [Nanook::Block] previous block in the chain. Can be nil.
|
395
|
+
def previous
|
396
|
+
memoized_info[:previous]
|
397
|
+
end
|
398
|
+
|
399
|
+
# Returns the type of the block. One of "open", "send", "receive", "change", "epoch".
|
400
|
+
#
|
401
|
+
# ==== Example:
|
402
|
+
# block.type # => "open"
|
403
|
+
#
|
404
|
+
# @return [String] type of block. Returns nil for unconfirmed blocks.
|
405
|
+
def type
|
406
|
+
memoized_info[:type]
|
407
|
+
end
|
408
|
+
|
409
|
+
# Returns true if block is type "send".
|
410
|
+
#
|
411
|
+
# ==== Example:
|
412
|
+
# block.send? # => true
|
413
|
+
#
|
414
|
+
# @return [Boolean]
|
415
|
+
def send?
|
416
|
+
type == 'send'
|
417
|
+
end
|
418
|
+
|
419
|
+
# Returns true if block is type "open".
|
420
|
+
#
|
421
|
+
# ==== Example:
|
422
|
+
# block.open? # => true
|
423
|
+
#
|
424
|
+
# @return [Boolean]
|
425
|
+
def open?
|
426
|
+
type == 'open'
|
427
|
+
end
|
428
|
+
|
429
|
+
# Returns true if block is type "receive".
|
430
|
+
#
|
431
|
+
# ==== Example:
|
432
|
+
# block.receive? # => true
|
433
|
+
#
|
434
|
+
# @return [Boolean]
|
435
|
+
def receive?
|
436
|
+
type == 'receive'
|
437
|
+
end
|
438
|
+
|
439
|
+
# Returns true if block is type "change" (change of representative).
|
440
|
+
#
|
441
|
+
# ==== Example:
|
442
|
+
# block.change? # => true
|
443
|
+
#
|
444
|
+
# @return [Boolean]
|
445
|
+
def change?
|
446
|
+
type == 'change'
|
447
|
+
end
|
448
|
+
|
449
|
+
# Returns true if block is type "epoch".
|
450
|
+
#
|
451
|
+
# ==== Example:
|
452
|
+
# block.epoch? # => true
|
453
|
+
#
|
454
|
+
# @return [Boolean]
|
455
|
+
def epoch?
|
456
|
+
type == 'epoch'
|
457
|
+
end
|
458
|
+
|
459
|
+
# @return [String]
|
460
|
+
def to_s
|
461
|
+
"#{self.class.name}(id: \"#{short_id}\")"
|
462
|
+
end
|
463
|
+
alias inspect to_s
|
464
|
+
|
285
465
|
private
|
286
466
|
|
287
467
|
# Some RPC calls expect the param that represents the block to be named
|
288
468
|
# "hash", and others "block".
|
289
469
|
# The param_name argument allows us to specify which it should be for this call.
|
290
|
-
def rpc(action, param_name, params={})
|
291
|
-
p =
|
470
|
+
def rpc(action, param_name, params = {})
|
471
|
+
p = { param_name.to_sym => @block }
|
292
472
|
@rpc.call(action, p.merge(params))
|
293
473
|
end
|
294
474
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
end
|
475
|
+
# Memoize the `#info` response as we can refer to it for other methods (`type`, `#open?`, `#send?` etc.)
|
476
|
+
def memoized_info
|
477
|
+
@memoized_info ||= info(allow_unchecked: true, unit: :raw)
|
299
478
|
end
|
300
479
|
|
301
|
-
def
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
480
|
+
def parse_info_response(response, unit)
|
481
|
+
response.merge!(id: id)
|
482
|
+
contents = response.delete(:contents)
|
483
|
+
response.merge!(contents) if contents
|
484
|
+
|
485
|
+
response.delete(:block_account) # duplicate of contents.account
|
486
|
+
response[:type] = response.delete(:subtype) # rename key
|
487
|
+
response[:last_modified_at] = response.delete(:modified_timestamp) # rename key
|
488
|
+
|
489
|
+
response[:account] = as_account(response[:account]) if response[:account]
|
490
|
+
response[:representative] = as_account(response[:representative]) if response[:representative]
|
491
|
+
response[:previous] = as_block(response[:previous]) if response[:previous]
|
492
|
+
response[:link] = as_block(response[:link]) if response[:link]
|
493
|
+
response[:link_as_account] = as_account(response[:link_as_account]) if response[:link_as_account]
|
494
|
+
response[:local_timestamp] = as_time(response[:local_timestamp])
|
495
|
+
response[:last_modified_at] = as_time(response[:last_modified_at])
|
496
|
+
|
497
|
+
if unit == :nano
|
498
|
+
response[:amount] = raw_to_NANO(response[:amount])
|
499
|
+
response[:balance] = raw_to_NANO(response[:balance])
|
306
500
|
end
|
307
501
|
|
308
|
-
response
|
502
|
+
response.compact
|
309
503
|
end
|
310
|
-
|
311
504
|
end
|
312
505
|
end
|