Class: Nanook::Node

Inherits:
Object
  • Object
show all
Includes:
Util
Defined in:
lib/nanook/node.rb

Overview

The Nanook::Node class contains methods to manage your nano node and query its data of the nano network.

Your node is constantly syncing data with other nodes on the network. When your node first starts up after being built, its database will be empty and it will begin synchronizing and downloading data of the nano ledger to its local database. The ledger is the central record of all accounts and transactions. Some of the methods in this class query your node's database formed from the nano ledger, and so the responses are determined by the completeness of your node's database.

You can determine how synchronized your node is with the nano ledger with the #sync_progress method.

Initializing

Initialize this class through the convenient #node method:

node = Nanook.new.node

Or compose the longhand way like this:

rpc_conn = Nanook::Rpc.new
node = Nanook::Node.new(rpc_conn)

Constant Summary

Constants included from Util

Util::STEP

Instance Method Summary collapse

Constructor Details

#initialize(rpc) ⇒ Node

Returns a new instance of Node.



33
34
35
# File 'lib/nanook/node.rb', line 33

def initialize(rpc)
  @rpc = rpc
end

Instance Method Details

#account_countInteger Also known as: frontier_count

The number of accounts in the nano ledger–essentially all accounts with open blocks. An open block is the type of block written to the nano ledger when an account receives its first payment (see WalletAccount#receive). All accounts that respond true to Account#exists? have open blocks in the ledger.

Returns:

  • (Integer)

    number of accounts with open blocks.



44
45
46
# File 'lib/nanook/node.rb', line 44

def 
  rpc(:frontier_count, _access: :count)
end

#block_countHash{Symbol=>Integer}

The count of all blocks downloaded to the node, and blocks still to be synchronized by the node.

Example:

{
  count: 100,
  unchecked: 10,
  cemented: 25
}

Returns:

  • (Hash{Symbol=>Integer})

    number of blocks and unchecked synchronizing blocks



62
63
64
# File 'lib/nanook/node.rb', line 62

def block_count
  rpc(:block_count, _coerce: Hash)
end

#bootstrap(address:, port:) ⇒ Boolean

Initialize bootstrap to a specific IP address and port.

Returns:

  • (Boolean)

    indicating if the action was successful



76
77
78
# File 'lib/nanook/node.rb', line 76

def bootstrap(address:, port:)
  rpc(:bootstrap, address: address, port: port).key?(:success)
end

#bootstrap_any(account: nil) ⇒ Boolean

Initialize multi-connection bootstrap to random peers

Parameters:

  • account (Nanook::Account) (defaults to: nil)

    False by default. Manually force closing of all current bootstraps

Returns:

  • (Boolean)

    indicating if the action was successful



85
86
87
88
89
90
91
# File 'lib/nanook/node.rb', line 85

def bootstrap_any(account: nil)
  params = {
    account: 
  }.compact

  rpc(:bootstrap_any, params).key?(:success)
end

#bootstrap_lazy(hash, force: false) ⇒ Hash{Symbol=>Boolean}

Initialize lazy bootstrap with given block hash. Response includes whether new election was started and whether a new lazy key_inserted was successful.

Example:

node.bootstrap_lazy

Example response:

{
  "started": true,
  "key_inserted": false
}

Parameters:

  • hash (String)
  • force (Boolean) (defaults to: false)

    False by default. Manually force closing of all current bootstraps

Returns:

  • (Hash{Symbol=>Boolean})

    indicating if the action was successful



112
113
114
115
116
117
# File 'lib/nanook/node.rb', line 112

def bootstrap_lazy(hash, force: false)
  response = rpc(:bootstrap_lazy, hash: hash, force: force)
  values = response.map { |k, v| [k, v == 1] }

  Hash[values]
end

#change_receive_minimum(minimum, unit: Nanook.default_unit) ⇒ Boolean

Sets the receive minimum for wallets on the node. The value is in Nano by default. To specify an amount in raw, pass the argument unit: :raw.

Example:

.change_receive_minimum(0.01) # true

Parameters:

  • minimum

    Amount to set as the receive minimum

  • unit (defaults to: Nanook.default_unit)

    optional. Specify raw if you want to set the amount in raw. (See Nanook::Account#balance)

Returns:

  • (Boolean)

    true if the action was successful

Raises:



354
355
356
357
358
359
360
# File 'lib/nanook/node.rb', line 354

def change_receive_minimum(minimum, unit: Nanook.default_unit)
  validate_unit!(unit)

  minimum = NANO_to_raw(minimum) if unit == :nano

  rpc(:receive_minimum_set, amount: minimum).key?(:success)
end

#confirmation_quorum(unit: Nanook.default_unit) ⇒ Hash{Symbol=>String|Integer}

Returns information about node elections settings and observed network state:

  • `quorum_delta`: delta tally required to rollback block

  • `online_weight_quorum_percent`: percentage of online weight for delta

  • `online_weight_minimum`: minimum online weight to confirm block

  • `online_stake_total`: currently observed online total weight

  • `peers_stake_total`: known peers total weight

  • `peers_stake_required`: effective stake needed from directly connected peers for quorum

Example:

node.confirmation_quorum

Example response:

{
  quorum_delta: 43216377.43025059,
  online_weight_quorum_percent: 50,
  online_weight_minimum: 60000000.0,
  online_stake_total: 86432754.86050119,
  peers_stake_total: 84672338.52479072,
  peers_stake_required: 60000000.0
}

Returns:

  • (Hash{Symbol=>String|Integer})

Raises:



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/nanook/node.rb', line 145

def confirmation_quorum(unit: Nanook.default_unit)
  validate_unit!(unit)

  response = rpc(:confirmation_quorum, _coerce: Hash)

  return response unless unit == :nano

  response[:quorum_delta] = raw_to_NANO(response[:quorum_delta])
  response[:online_weight_minimum] = raw_to_NANO(response[:online_weight_minimum])
  response[:online_stake_total] = raw_to_NANO(response[:online_stake_total])
  response[:peers_stake_total] = raw_to_NANO(response[:peers_stake_total])
  response[:peers_stake_required] = raw_to_NANO(response[:peers_stake_required])

  response.compact
end

#difficulty(include_trend: false) ⇒ Hash{Symbol=>String|Float|Array}

Note: This RPC call is deprecated as of v22 of the node software. docs.nano.org/releases/release-v22-0/

Returns the difficulty values (16 hexadecimal digits string, 64 bit) for the minimum required on the network (network_minimum) as well as the current active difficulty seen on the network (network_current, 5 minute trended average of adjusted difficulty seen on confirmed transactions) which can be used to perform rework for better prioritization of transaction processing. A multiplier of the network_current from the base difficulty of network_minimum is also provided for comparison.

Example:

node.difficulty(include_trend: true)

Example response:

{
  network_minimum: "ffffffc000000000",
  network_current: "ffffffc1816766f2",
  multiplier: 1.024089858417128,
  difficulty_trend: [
    1.156096135149775,
    1.190133894573061,
    1.135567138563921,
    1.000000000000000,
  ]
}

Parameters:

  • include_trend (Boolean) (defaults to: false)

    false by default. Also returns the trend of difficulty seen on the network as a list of multipliers. Sampling occurs every 16 to 36 seconds. The list is ordered such that the first value is the most recent sample.

Returns:

  • (Hash{Symbol=>String|Float|Array})


196
197
198
199
200
201
202
# File 'lib/nanook/node.rb', line 196

def difficulty(include_trend: false)
  rpc(:active_difficulty, include_trend: include_trend, _coerce: Hash).tap do |response|
    response[:multiplier] = response[:multiplier].to_f

    response[:difficulty_trend].map!(&:to_f) if response.key?(:difficulty_trend)
  end
end

#keepalive(address:, port:) ⇒ Boolean

Tells the node to send a keepalive packet to a specific IP address and port.

Returns:

  • (Boolean)

    indicating if the action was successful



69
70
71
# File 'lib/nanook/node.rb', line 69

def keepalive(address:, port:)
  rpc(:keepalive, address: address, port: port).key?(:started)
end

#peersHash{Symbol=>Hash{Symbol=>Integer|String}}

Returns peers information.

Example response:

{
  :"[::ffff:104.131.102.132]:7075" => {
    protocol_version: 20,
    node_id: "node_1y7j5rdqhg99uyab1145gu3yur1ax35a3b6qr417yt8cd6n86uiw3d4whty3",
    type: "udp"
  },
  :"[::ffff:104.131.114.102]:7075" => { ... }
}

Returns:

  • (Hash{Symbol=>Hash{Symbol=>Integer|String}})


224
225
226
# File 'lib/nanook/node.rb', line 224

def peers
  rpc(:peers, peer_details: true, _access: :peers, _coerce: Hash)
end

#receive_minimum(unit: Nanook.default_unit) ⇒ Integer|Float

Returns receive minimum for wallets on the node.

Example:

.receive_minimum # => 0.01

Parameters:

  • unit (Symbol) (defaults to: Nanook.default_unit)

    default is Nanook.default_unit. Must be one of UNITS. Represents the unit that the balances will be returned in. Note: this method interprets :nano as NANO, which is technically Mnano. See What are Nano's Units

Returns:

  • (Integer|Float)

    the receive minimum

Raises:



371
372
373
374
375
376
377
378
379
# File 'lib/nanook/node.rb', line 371

def receive_minimum(unit: Nanook.default_unit)
  validate_unit!(unit)

  amount = rpc(:receive_minimum, _access: :amount)

  return amount unless unit == :nano

  raw_to_NANO(amount)
end

#representatives(unit: Nanook.default_unit) ⇒ Hash{Nanook::Account=>Float|Integer}

All representatives and their voting weight.

Example:

node.representatives

Example response:

{
  Nanook::Account: 3822372327060170000000000000000000000,
  Nanook::Account: 30999999999999999999999999000000,
  Nanook::Account: 0
}

Returns:

  • (Hash{Nanook::Account=>Float|Integer})

    known representatives and their voting weight

Raises:



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/nanook/node.rb', line 244

def representatives(unit: Nanook.default_unit)
  validate_unit!(unit)

  response = rpc(:representatives, _access: :representatives, _coerce: Hash)

  r = response.map do |, weight|
    weight = raw_to_NANO(weight) if unit == :nano

    [(), weight]
  end

  Hash[r]
end

#representatives_onlineNanook::Account

All online representatives that have voted recently and their weight.

Example:

node.representatives_online # => [Nanook::Account, ...]

Returns:



265
266
267
268
269
# File 'lib/nanook/node.rb', line 265

def representatives_online
  rpc(:representatives_online, _access: :representatives, _coerce: Array).map do |representative|
    (representative)
  end
end

#search_pendingBoolean

Tells the node to look for any account in all available wallets.

Example:

node.search_pending #=> true

Returns:

  • (Boolean)

    indicates if the action was successful



277
278
279
# File 'lib/nanook/node.rb', line 277

def search_pending
  rpc(:search_pending_all).key?(:success)
end

#stopBoolean

Safely shuts down the node.

Returns:

  • (Boolean)

    indicating if action was successful



284
285
286
# File 'lib/nanook/node.rb', line 284

def stop
  rpc(:stop).key?(:success)
end

#sync_progressFloat

The percentage completeness of the synchronization process for your node as it downloads the nano ledger. Note, it's normal for your progress to not ever reach 100. The closer to 100, the more complete your node's data is, and so the query methods in this class become more reliable.

Returns:

  • (Float)

    the percentage completeness of the synchronization process for your node



326
327
328
329
330
331
332
333
334
# File 'lib/nanook/node.rb', line 326

def sync_progress
  response = rpc(:block_count, _coerce: Hash)

  count = response[:count]
  unchecked = response[:unchecked]
  total = count + unchecked

  count.to_f * 100 / total.to_f
end

#synchronizing_blocks(limit: 1000, unit: Nanook.default_unit) ⇒ Hash{Symbol=>String} Also known as: unchecked

Returns information about the synchronizing blocks for this node.

Parameters:

  • limit (Integer) (defaults to: 1000)

    number of synchronizing blocks to return

  • unit (Symbol) (defaults to: Nanook.default_unit)

    default is Nanook.default_unit. Must be one of UNITS. Represents the unit that the balances will be returned in. Note: this method interprets :nano as NANO, which is technically Mnano. See What are Nano's Units

Returns:

  • (Hash{Symbol=>String})

    information about the synchronizing blocks for this node

Raises:



293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/nanook/node.rb', line 293

def synchronizing_blocks(limit: 1000, unit: Nanook.default_unit)
  validate_unit!(unit)

  params = {
    count: limit,
    json_block: true,
    _access: :blocks,
    _coerce: Hash
  }

  response = rpc(:unchecked, params).map do |block, info|
    info[:account] = (info[:account])
    info[:link_as_account] = (info[:link_as_account])
    info[:representative] = (info[:representative])
    info[:previous] = as_block(info[:previous])
    info[:link] = as_block(info[:link])
    info[:balance] = raw_to_NANO(info[:balance]) if unit == :nano

    [as_block(block), info]
  end

  Hash[response]
end

#to_sString Also known as: inspect

Returns:

  • (String)


205
206
207
# File 'lib/nanook/node.rb', line 205

def to_s
  self.class.name
end

#uptimeInteger

Returns node uptime in seconds

Returns:

  • (Integer)

    seconds of uptime



339
340
341
# File 'lib/nanook/node.rb', line 339

def uptime
  rpc(:uptime, _access: :seconds, _coerce: Hash)
end

#versionHash{Symbol=>Integer|String} Also known as: info

Returns version information for this node.

Returns:

  • (Hash{Symbol=>Integer|String})

    version information for this node



382
383
384
# File 'lib/nanook/node.rb', line 382

def version
  rpc(:version, _coerce: Hash)
end