From ae7e7ccb1751475e6a412463f7096b45faa2485b Mon Sep 17 00:00:00 2001 From: Conny Brunnkvist Date: Thu, 28 May 2026 12:29:20 +0700 Subject: [PATCH] docs: Standardize markdown block spacing --- docs/commands/command-line-interface.md | 4 + docs/commands/rpc-protocol.md | 653 +++++++++++++++++- docs/core-development/overview.md | 1 - .../understanding-the-code.md | 31 +- docs/glossary.md | 49 ++ docs/index.md | 65 +- docs/integration-guides/advanced.md | 6 +- docs/integration-guides/build-options.md | 19 +- docs/integration-guides/index.md | 3 - docs/integration-guides/ipc-integration.md | 4 + docs/integration-guides/key-management.md | 49 +- docs/integration-guides/the-basics.md | 11 +- docs/integration-guides/websockets.md | 8 +- docs/integration-guides/work-generation.md | 5 +- docs/node-implementation/blocks.md | 1 + docs/node-implementation/work.md | 1 - docs/protocol-design/attack-vectors.md | 1 + docs/protocol-design/blocks.md | 4 +- .../protocol-design/distribution-and-units.md | 5 +- docs/protocol-design/introduction.md | 1 + docs/protocol-design/ledger.md | 1 + docs/protocol-design/networking.md | 4 + docs/protocol-design/orv-consensus.md | 1 + .../signing-hashing-and-key-derivation.md | 2 + docs/releases/network-upgrades.md | 5 + docs/releases/node-releases.md | 4 + docs/releases/release-v19-0.md | 8 + docs/releases/release-v20-0.md | 10 +- docs/releases/release-v21-0.md | 8 + docs/releases/release-v21-3.md | 1 - docs/releases/release-v22-0.md | 1 - docs/releases/release-v22-1.md | 2 +- docs/releases/release-v23-1.md | 1 + docs/releases/release-v23-3.md | 1 + docs/releases/release-v24-0.md | 1 + docs/releases/release-v25-0.md | 8 + docs/releases/release-v27-0.md | 8 + docs/releases/release-v28-0.md | 4 + docs/releases/release-v28-1.md | 1 - docs/releases/release-v28-2.md | 1 + docs/running-a-node/beta-network.md | 10 +- docs/running-a-node/configuration.md | 7 + docs/running-a-node/docker-management.md | 3 + docs/running-a-node/ledger-management.md | 7 + docs/running-a-node/logging-tracing.md | 21 +- docs/running-a-node/node-setup.md | 18 +- docs/running-a-node/overview.md | 5 + docs/running-a-node/test-network.md | 7 +- docs/running-a-node/troubleshooting.md | 18 +- .../voting-as-a-representative.md | 4 +- docs/running-a-node/wallet-setup.md | 27 +- ...fig-node-option-node-enable-voting-true.md | 1 + .../config-node-option-rpc-enable-true.md | 1 + docs/snippets/hardware-recommendations.md | 2 + .../known-issue-macos-too-many-open-files.md | 3 - docs/snippets/release-details-v22-1.md | 3 +- docs/snippets/release-details-v23-1.md | 3 +- docs/snippets/release-details-v23-3.md | 3 +- docs/snippets/release-details-v26-1.md | 2 +- docs/snippets/unconfirmed-information.md | 2 +- .../warning-only-official-builds-supported.md | 1 + .../warning-unsupported-configuration.md | 1 + docs/what-is-nano/overview.md | 4 + docs/whitepaper/english.md | 1 + scripts/format_markdown.py | 135 ++++ 65 files changed, 1189 insertions(+), 93 deletions(-) create mode 100755 scripts/format_markdown.py diff --git a/docs/commands/command-line-interface.md b/docs/commands/command-line-interface.md index 698b3fbb4..d0b781025 100644 --- a/docs/commands/command-line-interface.md +++ b/docs/commands/command-line-interface.md @@ -3,6 +3,7 @@ description: Reference for the CLI commands available for the nano node # Command Line Interface ## nano_node commands + | Command | Description | |---------|-------------| | `--account_create --wallet=` | Insert next deterministic key into `` | @@ -41,11 +42,13 @@ description: Reference for the CLI commands available for the nano node | `--wallet_representative_set`
`--wallet=`
  `--account=` | Set `` as default representative for ``. | ## Launch Options + The node is typically run like this: ```bash ./nano_node --daemon [--launch_options] ``` + !!! note "Intended for developer use" These options are only for developer use so please understand the impacts before use. @@ -88,6 +91,7 @@ The node is typically run like this: | `--disable_wallet_bootstrap` | Turn off use of wallet-based bootstrap. | ## Debug commands + | Command | Description | |---------|-------------| | `--debug_account_count` | Display the number of accounts. | diff --git a/docs/commands/rpc-protocol.md b/docs/commands/rpc-protocol.md index 937ebb20e..d7c4cd3f8 100644 --- a/docs/commands/rpc-protocol.md +++ b/docs/commands/rpc-protocol.md @@ -20,11 +20,13 @@ The RPC protocol accepts JSON HTTP POST requests. The following are RPC commands --- ### account_balance + Returns how many RAW is owned and how many have not yet been received by **account** --8<-- "deprecation-info-pending.md" **Request:** + ```json { "action": "account_balance", @@ -33,6 +35,7 @@ Returns how many RAW is owned and how many have not yet been received by **accou ``` **Response:** + ```json { "balance": "10000", @@ -48,9 +51,11 @@ Boolean, true by default. Results in `balance` only including blocks on this acc --- ### account_block_count + Get number of blocks for a specific **account** **Request:** + ```json { "action": "account_block_count", @@ -59,6 +64,7 @@ Get number of blocks for a specific **account** ``` **Response:** + ```json { "block_count" : "19" @@ -68,9 +74,11 @@ Get number of blocks for a specific **account** --- ### account_get + Get account number for the **public key** **Request:** + ```json { "action": "account_get", @@ -79,6 +87,7 @@ Get account number for the **public key** ``` **Response:** + ```json { "account" : "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx" @@ -94,6 +103,7 @@ Reports send/receive information for an account. Returns only **send & receive** --8<-- "warning-includes-unconfirmed.md" **Request:** + ```json { "action": "account_history", @@ -103,6 +113,7 @@ Reports send/receive information for an account. Returns only **send & receive** ``` **Response:** + ```json { "account": "nano_1ipx847tk8o46pwxt5qjdbncjqcbwcc1rrmqnkztrfjy5k7z4imsrata9est", @@ -135,6 +146,7 @@ If the `count` limit results in stopping before the end of the account chain, th --- ### account_info + Returns frontier, open block, change representative block, balance, last modified timestamp from local database & block count for **account**. Only works for accounts that have received their first transaction and have an entry on the ledger, will return "Account not found" otherwise. To open an account, use [receive](#receive). --8<-- "unconfirmed-information.md" @@ -143,6 +155,7 @@ Returns frontier, open block, change representative block, balance, last modifie If you need only details for confirmed blocks, use the `include_confirmed` option below and referenced the `confirmed_*` fields added in to the response. **Request:** + ```json { "action": "account_info", @@ -151,6 +164,7 @@ Returns frontier, open block, change representative block, balance, last modifie ``` **Response:** + ```json { "frontier": "FF84533A571D953A596EA401FD41743AC85D04F406E76FDE4408EAED50B473C5", @@ -181,6 +195,7 @@ Boolean, false by default. Adds new return fields with prefix of `confirmed_` fo --8<-- "deprecation-info-pending.md" **Request:** + ```json { "action": "account_info", @@ -193,6 +208,7 @@ Boolean, false by default. Adds new return fields with prefix of `confirmed_` fo ``` **Response:** + ```json { "frontier": "80A6745762493FA21A22718ABFA4F635656A707B48B3324198AC7F3938DE6D4F", @@ -220,6 +236,7 @@ _version 9.0+_ Booleans, false by default. Additionally returns representative, voting weight, pending/receivable balance for account **Request:** + ```json { "action": "account_info", @@ -231,6 +248,7 @@ Booleans, false by default. Additionally returns representative, voting weight, ``` **Response:** + ```json { "frontier": "FF84533A571D953A596EA401FD41743AC85D04F406E76FDE4408EAED50B473C5", @@ -252,16 +270,20 @@ Booleans, false by default. Additionally returns representative, voting weight, --- ### account_key + Get the public key for **account** **Request:** + ```json { "action": "account_key", "account" : "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx" } ``` + **Response:** + ```json { "key": "3068BB1CA04525BB0E416C485FE6A67FD52540227D267CC8B6E8DA958A7FA039" @@ -271,16 +293,20 @@ Get the public key for **account** --- ### account_representative + Returns the representative for **account** **Request:** + ```json { "action": "account_representative", "account": "nano_39a73oy5ungrhxy5z5oao1xso4zo7dmgpjd4u74xcrx3r1w6rtazuouw6qfi" } ``` + **Response:** + ```json { "representative" : "nano_16u1uufyoig8777y6r8iqjtrw8sg8maqrm36zzcm95jmbd9i9aj5i8abr8u5" @@ -290,16 +316,20 @@ Returns the representative for **account** --- ### account_weight + Returns the voting weight for **account** **Request:** + ```json { "action": "account_weight", "account": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" } ``` + **Response:** + ```json { "weight": "10000" @@ -309,6 +339,7 @@ Returns the voting weight for **account** --- ### accounts_balances + Returns how many RAW is owned and how many have not yet been received by **accounts list** --8<-- "unconfirmed-information.md" @@ -317,13 +348,16 @@ Returns how many RAW is owned and how many have not yet been received by **accou --8<-- "deprecation-info-pending.md" **Request:** + ```json { "action": "accounts_balances", "accounts": ["nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3", "nano_3i1aq1cchnmbn9x5rsbap8b15akfh7wj7pwskuzi7ahz8oq6cobd99d4r3b7"] } ``` + **Response:** + ```json { "balances" : { @@ -350,6 +384,7 @@ Boolean, true by default. Results in `balance` only including blocks on the prov With _version 25.0+_, `accounts_balances` response errors come in a different entry, named as `errors`. This fixes the breaking change added in V24.0. Please notice that when an account is not found in the ledger, no error is returned anymore. It now returns a zero balance and zero as receivable. + ```json { "balances": { @@ -369,16 +404,20 @@ Boolean, true by default. Results in `balance` only including blocks on the prov } } ``` + If all requested entries result in errors, no entry will be added in the response for `balances`. Similarly, if there are no errors, no entry will be added for `errors`. Request: + ```json { "action": "accounts_balances", "accounts": ["nano_36uccgpjzhjsdbj44wm1y5hyz8gefx3wjpp1jircxt84nopxkxti5bzq1rnz"] } ``` + Response: + ```json { "errors": { @@ -386,9 +425,11 @@ Boolean, true by default. Results in `balance` only including blocks on the prov } } ``` + In _version 24.0+_, `accounts_balances` response errors are returned per account entry in `balances` object. If an account does not exist, zero balance and zero receivables should be returned, but V24.0 has a bug: unopened accounts with receivables return an error instead of the receivables. + ```json { "balances": { @@ -404,22 +445,25 @@ Boolean, true by default. Results in `balance` only including blocks on the prov } ``` - --- ### accounts_frontiers + Returns a list of pairs of account and block hash representing the head block for **accounts list** --8<-- "warning-includes-unconfirmed.md" **Request:** + ```json { "action": "accounts_frontiers", "accounts": ["nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3", "nano_3i1aq1cchnmbn9x5rsbap8b15akfh7wj7pwskuzi7ahz8oq6cobd99d4r3b7"] } ``` + **Response:** + ```json { "frontiers" : { @@ -431,6 +475,7 @@ Returns a list of pairs of account and block hash representing the head block fo !!! info "Error handling" With _version 25.0+_, `accounts_frontiers` response errors come in a different entry, named `errors`. + ```json { "frontiers": { @@ -442,16 +487,20 @@ Returns a list of pairs of account and block hash representing the head block fo } } ``` + If all requested entries result in errors, no entry will be added in the response for `frontiers`. Similarly, if there are no errors, no entry will be added for `errors`. Request: + ```json { "action": "accounts_frontiers", "accounts": ["nano_1hrts7hcoozxccnffoq9hqhngnn9jz783usapejm57ejtqcyz9dpso1bibuy"] } ``` + Response: + ```json { "errors": { @@ -459,8 +508,10 @@ Returns a list of pairs of account and block hash representing the head block fo } } ``` + In _version 24.0+_, `accounts_frontiers` response errors were returned per account entry in the `frontiers` object. + ```json { "frontiers": { @@ -480,6 +531,7 @@ _since V24.0, use [accounts_pending](#accounts_pending) for V23.3 and below_ Returns a list of confirmed block hashes which have not yet been received by these **accounts** **Request:** + ```json { "action": "accounts_receivable", @@ -487,7 +539,9 @@ Returns a list of confirmed block hashes which have not yet been received by the "count": "1" } ``` + **Response:** + ```json { "blocks" : { @@ -496,11 +550,13 @@ Returns a list of confirmed block hashes which have not yet been received by the } } ``` + **Optional "threshold"** _version 8.0+_ Number (128 bit, decimal). Returns a list of receivable block hashes with amount more or equal to **threshold** **Request:** + ```json { "action": "accounts_receivable", @@ -509,7 +565,9 @@ Number (128 bit, decimal). Returns a list of receivable block hashes with amount "threshold": "1000000000000000000000000" } ``` + **Response:** + ```json { "blocks" : { @@ -522,11 +580,13 @@ Number (128 bit, decimal). Returns a list of receivable block hashes with amount } } ``` + **Optional "source"** _version 9.0+_ Boolean, false by default. Returns a list of receivable block hashes with amount and source accounts **Request:** + ```json { "action": "accounts_receivable", @@ -535,7 +595,9 @@ Boolean, false by default. Returns a list of receivable block hashes with amount "source": "true" } ``` + **Response:** + ```json { "blocks" : { @@ -554,12 +616,14 @@ Boolean, false by default. Returns a list of receivable block hashes with amount } } ``` + **Optional "include_active"** _version 15.0+_ Boolean, false by default. Include active (not confirmed) blocks **Request:** + ```json { "action": "accounts_receivable", @@ -582,16 +646,20 @@ Boolean, true by default (_version 22.0+_), previously false by default. Only re --- ### accounts_representatives + Returns the representatives for given **accounts** **Request:** + ```json { "action": "accounts_representatives", "accounts": ["nano_16u1uufyoig8777y6r8iqjtrw8sg8maqrm36zzcm95jmbd9i9aj5i8abr8u5","nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3"] } ``` + **Response:** + ```json { "representatives" : { @@ -603,6 +671,7 @@ Returns the representatives for given **accounts** !!! info "Error handling" With _version 25.0+_, `accounts_representatives` response errors come in a different entry, named `errors`. + ```json { "representatives": { @@ -614,16 +683,20 @@ Returns the representatives for given **accounts** } } ``` + If all requested entries result in errors, no entry will be added in the response for `representatives`. Similarly, if there are no errors, no entry will be added for `errors`. Request: + ```json { "action": "accounts_representatives", "accounts": ["nano_1hrts7hcoozxccnffoq9hqhngnn9jz783usapejm57ejtqcyz9dpso1bibuy"] } ``` + Response: + ```json { "errors": { @@ -631,8 +704,10 @@ Returns the representatives for given **accounts** } } ``` + In _version 24.0+_, `accounts_representatives` response errors were returned per account entry in the `representatives` object. + ```json { "representatives": { @@ -646,15 +721,19 @@ Returns the representatives for given **accounts** --- ### available_supply + Returns how many raw are in the public supply **Request:** + ```json { "action": "available_supply" } ``` + **Response:** + ```json { "available": "133248061996216572282917317807824970865" @@ -664,16 +743,20 @@ Returns how many raw are in the public supply --- ### block_account + Returns the account containing block **Request:** + ```json { "action": "block_account", "hash": "023B94B7D27B311666C8636954FE17F1FD2EAA97A8BAC27DE5084FBBD5C6B02C" } ``` + **Response:** + ```json { "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3" @@ -683,17 +766,21 @@ Returns the account containing block --- ### block_confirm + _version 12.2+_ Request confirmation for **block** from known online representative nodes. Check results with [confirmation history](#confirmation_history). **Request:** + ```json { "action": "block_confirm", "hash": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } ``` + **Response:** + ```json { "started": "1" @@ -705,15 +792,19 @@ Request confirmation for **block** from known online representative nodes. Check --- ### block_count + Reports the number of blocks in the ledger and unchecked synchronizing blocks **Request:** + ```json { "action": "block_count" } ``` + **Response:** + ```json { "count": "1000", @@ -721,6 +812,7 @@ Reports the number of blocks in the ledger and unchecked synchronizing blocks "cemented": "25" } ``` + **Note:** If the node is running the RocksDB backend the unchecked count may only be estimate. **Optional "include_cemented"** @@ -733,13 +825,14 @@ Default "true". If "true", "cemented" in the response will contain the number of --- ### block_create + _enable_control required, version 9.0+_ Creates a json representations of new block based on input data & signed with **private key** or **account** in **wallet**. Use for offline signing. Using the optional `json_block` is recommended since v19.0. --8<-- "warning-enable-control.md" - **Request sample for state block:** + ```json { "action": "block_create", @@ -752,6 +845,7 @@ Creates a json representations of new block based on input data & signed with ** "previous": "F47B23107E5F34B2CE06F562B5C435DF72A533251CB414C51B2B62A8F63A00E4" } ``` + Parameters for state block: * `balance`: **final** balance for account after block creation, formatted in 'raw' units using a decimal integer. If balance is less than previous, block is considered as send subtype! @@ -790,6 +884,7 @@ If difficulty and work values are both not given, RPC processor tries to calcula **Examples** **Response sample for above request**: + ```json { "hash": "FF0144381CFF0B2C079A115E7ADA7E96F43FD219446E7524C48D1CC9900C4F17", @@ -811,10 +906,12 @@ If difficulty and work values are both not given, RPC processor tries to calcula --- ### block_hash + _version 13.0+_ Returning block hash for given **block** content. Using the optional `json_block` is recommended since v19.0. **Request:** + ```json { "action": "block_hash", @@ -832,7 +929,9 @@ Returning block hash for given **block** content. Using the optional `json_block } } ``` + **Response:** + ```json { "hash": "FF0144381CFF0B2C079A115E7ADA7E96F43FD219446E7524C48D1CC9900C4F17" @@ -847,6 +946,7 @@ Default "false". If "true", "block" must contain a JSON subtree instead of a JSO --- ### block_info + Retrieves a json representation of the block in `contents` along with: * _since version 18.0_: `block_account`, transaction `amount`, block `balance`, block `height` in account chain, block local modification `timestamp` @@ -856,6 +956,7 @@ Retrieves a json representation of the block in `contents` along with: Using the optional `json_block` is recommended since v19.0. **Request:** + ```json { "action": "block_info", @@ -863,7 +964,9 @@ Using the optional `json_block` is recommended since v19.0. "hash": "87434F8041869A01C8F6F263B87972D7BA443A72E0A97D7A3FD0CCC2358FD6F9" } ``` + **Response:** + ```json { "block_account": "nano_1ipx847tk8o46pwxt5qjdbncjqcbwcc1rrmqnkztrfjy5k7z4imsrata9est", @@ -895,19 +998,19 @@ Note: The `Balance` in contents is a uint128. However, it will be a hex-encoded _version 19.0+_ Default "false". If "true", "contents" will contain a JSON subtree instead of a JSON string. - **Optional `include_linked_account`** _version 28.0+_ (bool): When set to `true`, the response will include a new field `linked_account`, which returns the linked account associated with the block (or "0" if no linked account exists/was found e.g. due to pruning). - --- ### blocks + Retrieves a json representations of **blocks**. Using the optional `json_block` is recommended since v19.0. **Request:** + ```json { "action": "blocks", @@ -915,7 +1018,9 @@ Retrieves a json representations of **blocks**. Using the optional `json_block` "hashes": ["87434F8041869A01C8F6F263B87972D7BA443A72E0A97D7A3FD0CCC2358FD6F9"] } ``` + **Response:** + ```json { "blocks": { @@ -942,6 +1047,7 @@ Default "false". If "true", "contents" will contain a JSON subtree instead of a --- ### blocks_info + Retrieves a json representations of `blocks` in `contents` along with: * _since version 18.0_: `block_account`, transaction `amount`, block `balance`, block `height` in account chain, block local modification `timestamp` @@ -951,6 +1057,7 @@ Retrieves a json representations of `blocks` in `contents` along with: Using the optional `json_block` is recommended since v19.0. **Request:** + ```json { "action": "blocks_info", @@ -958,7 +1065,9 @@ Using the optional `json_block` is recommended since v19.0. "hashes": ["87434F8041869A01C8F6F263B87972D7BA443A72E0A97D7A3FD0CCC2358FD6F9"] } ``` + **Response:** + ```json { "blocks": { @@ -986,6 +1095,7 @@ Using the optional `json_block` is recommended since v19.0. } } ``` + **Optional `include_linked_account`** _version 28.0+_ @@ -999,6 +1109,7 @@ Booleans, false by default. Additionally checks if block is pending, returns sou --8<-- "deprecation-info-pending.md" **Request:** + ```json { "action": "blocks_info", @@ -1007,7 +1118,9 @@ Booleans, false by default. Additionally checks if block is pending, returns sou "source": "true" } ``` + **Response:** + ```json { "blocks" : { @@ -1024,12 +1137,14 @@ Booleans, false by default. Additionally checks if block is pending, returns sou } } ``` + **Optional "receive_hash"** _version 24.0+_ Boolean, default false. If "true", displays the hash of the send block's corresponding receive (if any). Returns 0 for non-send blocks, and for receivable blocks that do not yet have a corresponding receive. **Request:** + ```json { "action": "blocks_info", @@ -1039,6 +1154,7 @@ Boolean, default false. If "true", displays the hash of the send block's corresp ``` **Response** + ```json { "blocks": { @@ -1069,6 +1185,7 @@ _version 19.0+_ Default "false". If "true", an additional "blocks_not_found" is provided in the response, containing a list of the block hashes that were not found in the local database. Previously to this version an error would be produced if any block was not found. **Request:** + ```json { "action": "blocks_info", @@ -1078,6 +1195,7 @@ Default "false". If "true", an additional "blocks_not_found" is provided in the ``` **Response:** + ```json { "blocks" : { @@ -1102,9 +1220,11 @@ Default "false". If "true", an additional "blocks_not_found" is provided in the --- ### bootstrap + Initialize bootstrap to specific **IP address** and **port**. Not compatible with launch flag [--disable_legacy_bootstrap](/commands/command-line-interface/#-disable_legacy_bootstrap) **Request:** + ```json { "action": "bootstrap", @@ -1112,7 +1232,9 @@ Initialize bootstrap to specific **IP address** and **port**. Not compatible wit "port": "7075" } ``` + **Response:** + ```json { "success": "" @@ -1130,20 +1252,25 @@ String, empty by default. Set specific ID for new bootstrap attempt for better t --- ### bootstrap_any + Initialize multi-connection bootstrap to random peers. Not compatible with launch flag [--disable_legacy_bootstrap](/commands/command-line-interface/#-disable_legacy_bootstrap) **Request:** + ```json { "action": "bootstrap_any" } ``` + **Response:** + ```json { "success": "" } ``` + **Optional "force"** _version 20.0+_ Boolean, false by default. Manually force closing of all current bootstraps @@ -1159,25 +1286,30 @@ String, empty by default. Public address for targeting a specific account on boo --- ### bootstrap_lazy + _enable_control required, version 17.0+_ Initialize lazy bootstrap with given block **hash**. Not compatible with launch flag [--disable_lazy_bootstrap](/commands/command-line-interface/#-disable_lazy_bootstrap). As of _version 22.0_, response includes whether new election was `started` and whether a new lazy `key_inserted` was successful. --8<-- "warning-enable-control.md" **Request:** + ```json { "action": "bootstrap_lazy", "hash": "FF0144381CFF0B2C079A115E7ADA7E96F43FD219446E7524C48D1CC9900C4F17" } ``` + **Response:** + ```json { "started": "1", "key_inserted": "0" } ``` + **Optional "force"** Boolean, false by default. Manually force closing of all current bootstraps @@ -1189,12 +1321,14 @@ String, empty by default. Set specific ID for new bootstrap attempt for better t --- ### bootstrap_priorities + _enable_control required, version 28.0+_ Dumps info about priority and blocking sets to aid in debugging any potential problems --8<-- "warning-enable-control.md" **Request:** + ```json { "action": "bootstrap_priorities" @@ -1204,12 +1338,14 @@ Dumps info about priority and blocking sets to aid in debugging any potential pr --- ### bootstrap_reset + _enable_control required, version 28.0+_ Resets ascending bootstrap state - both priority and blocking sets are cleared. --8<-- "warning-enable-control.md" **Request:** + ```json { "action": "bootstrap_reset" @@ -1219,6 +1355,7 @@ Resets ascending bootstrap state - both priority and blocking sets are cleared. --- ### bootstrap_status + _version 17.0+_ --8<-- "warning-debug-only-command.md" @@ -1226,13 +1363,16 @@ _version 17.0+_ Returning status of current bootstrap attempt **Request:** + ```json { "action": "bootstrap_status" } ``` + **Response:** _versions 21.0+_ + ```json { "bootstrap_threads": "2", @@ -1283,6 +1423,7 @@ _versions 21.0+_ ``` ??? abstract "Response V17.0-V20.0" + ```json { "clients": "0", @@ -1312,9 +1453,11 @@ _versions 21.0+_ --- ### chain + Returns a consecutive list of block hashes in the account chain starting at **block** back to **count** (direction from frontier back to open block, from newer blocks to older). Will list all blocks back to the open block of this chain when count is set to "-1". The requested block hash is included in the answer. **Request:** + ```json { "action": "chain", @@ -1322,7 +1465,9 @@ Returns a consecutive list of block hashes in the account chain starting at **bl "count": "1" } ``` + **Response:** + ```json { "blocks": [ @@ -1330,6 +1475,7 @@ Returns a consecutive list of block hashes in the account chain starting at **bl ] } ``` + **Optional "offset"** _version 18.0+_ @@ -1343,6 +1489,7 @@ Boolean, false by default. Returns a list of block hashes in the account chain s --- ### confirmation_active + _version 16.0+_ Returns list of active elections qualified roots (excluding stopped & aborted elections); since V21, also includes the number of unconfirmed and confirmed active elections. Find info about specific qualified root with [confirmation_info](#confirmation_info) @@ -1352,14 +1499,16 @@ Returns list of active elections qualified roots (excluding stopped & aborted el * First account block (open): account public key + `0000000000000000000000000000000000000000000000000000000000000000` * Other blocks: previous hash + previous hash - **Request:** + ```json { "action": "confirmation_active" } ``` + **Response:** + ```json { "confirmations": [ @@ -1377,6 +1526,7 @@ Number, 0 by default. Returns only active elections with equal or higher announc --- ### confirmation_history + _version 12.0+_ --8<-- "warning-debug-only-command.md" @@ -1387,12 +1537,15 @@ Returns hash, tally weight, election duration (in milliseconds), election confir With version 19.0+ `confirmation_history_size` can be managed in the configuration file to adjust the number of elections to be kept in history and returned by this call. Due to timings inside the node, the default 2048 limit will return all confirmations up to traffic levels of approximately 56 confirmations/sec. To properly track levels above this, increase this value or use the confirmation subscription through the [websocket](/integration-guides/websockets) instead. **Request:** + ```json { "action": "confirmation_history" } ``` + **Response:** + ```json { "confirmation_stats": { @@ -1423,9 +1576,11 @@ With version 19.0+ `confirmation_history_size` can be managed in the configurati ] } ``` + **Optional "hash"** Valid block hash, filters return for only the provided hash. If there is no confirmation available for that hash anymore, the following return can be expected: + ```json { "confirmation_stats": { @@ -1436,6 +1591,7 @@ Valid block hash, filters return for only the provided hash. If there is no conf ``` If the block is unknown on the node, the following error will be returned: + ```"error": "Invalid block hash"``` --- @@ -1453,14 +1609,17 @@ Returns info about an unconfirmed active election by **root**. Including announc **Request:** ```json + { "action": "confirmation_info", "json_block": "true", "root": "EE125B1B1D85D3C24636B3590E1642D9F21B166C0C6CD99C9C6087A1224A0C44EE125B1B1D85D3C24636B3590E1642D9F21B166C0C6CD99C9C6087A1224A0C44" } + ``` **Response:** ```json + { "announcements": "2", "voters": "29", @@ -1484,6 +1643,7 @@ Returns info about an unconfirmed active election by **root**. Including announc } } } + ``` **Optional "contents"** @@ -1501,15 +1661,18 @@ Boolean, false by default. Returns list of votes representatives & its weights f **Request:** ```json + { "action": "confirmation_info", "json_block": "true", "root": "EE125B1B1D85D3C24636B3590E1642D9F21B166C0C6CD99C9C6087A1224A0C44EE125B1B1D85D3C24636B3590E1642D9F21B166C0C6CD99C9C6087A1224A0C44", "representatives": "true" } + ``` **Response:** ```json + { "announcements": "5", "last_winner": "B94C505029F04BC057A0486ADA8BD07981B4A8736AE6581F2E98C6D18498146F", @@ -1537,6 +1700,7 @@ Boolean, false by default. Returns list of votes representatives & its weights f } } } + ``` --- @@ -1555,12 +1719,15 @@ Returns information about node elections settings & observed network state: **Request:** ```json + { "action": "confirmation_quorum" } + ``` **Response:** ```json + { "quorum_delta": "41469707173777717318245825935516662250", "online_weight_quorum_percent": "50", @@ -1569,6 +1736,7 @@ Returns information about node elections settings & observed network state: "peers_stake_total": "69026910610720098597176027400951402360", "trended_stake_total": "81939414347555434636491651871033324568" } + ``` **Optional "peer_details"** @@ -1596,14 +1764,17 @@ Returns a list of open database transactions which are equal or greater than the **Request:** ```json + { "action": "database_txn_tracker", "min_read_time" : "1000", "min_write_time" : "0" } + ``` **Response on Windows/Debug:** ```json + { "txn_tracking": [ { @@ -1635,6 +1806,7 @@ Returns a list of open database transactions which are equal or greater than the ... // other threads ] } + ``` --- @@ -1645,19 +1817,23 @@ Returns a list of pairs of delegator accounts and balances given a representativ **Request:** ```json + { "action": "delegators", "account": "nano_1111111111111111111111111111111111111111111111111117353trpda" } + ``` **Response:** ```json + { "delegators": { "nano_13bqhi1cdqq8yb9szneoc38qk899d58i5rcrgdk5mkdm86hekpoez3zxw5sd": "500000000000000000000000000000000000", "nano_17k6ug685154an8gri9whhe5kb5z1mf5w6y39gokc1657sh95fegm8ht1zpn": "961647970820730000000000000000000000" } } + ``` **Optional parameters:** @@ -1675,16 +1851,20 @@ Get number of delegators for a specific representative **account** **Request:** ```json + { "action": "delegators_count", "account": "nano_1111111111111111111111111111111111111111111111111117353trpda" } + ``` **Response:** ```json + { "count": "2" } + ``` --- @@ -1694,19 +1874,23 @@ Derive deterministic keypair from **seed** based on **index** **Request:** ```json + { "action": "deterministic_key", "seed": "0000000000000000000000000000000000000000000000000000000000000000", "index": "0" } + ``` **Response:** ```json + { "private": "9F0E444C69F77A49BD0BE89DB92C38FE713E0963165CCA12FAF5712D7657120F", "public": "C008B814A7D269A1FA3C6528B19201A24D797912DB9996FF02A1FF356E45552B", "account": "nano_3i1aq1cchnmbn9x5rsbap8b15akfh7wj7pwskuzi7ahz8oq6cobd99d4r3b7" } + ``` --- @@ -1720,12 +1904,15 @@ Values in `max_election_age` and `average_election_age` are in milliseconds. **Request:** ```json + { "action": "election_statistics" } + ``` **Response sample:** ```json + { "normal": "152", "priority": "1", @@ -1736,6 +1923,7 @@ Values in `max_election_age` and `average_election_age` are in milliseconds. "max_election_age": "5493", "average_election_age": "421" } + ``` --- @@ -1751,17 +1939,21 @@ Upgrade network to new **epoch** with epoch signer private **key**. This spawns **Request:** ```json + { "action": "epoch_upgrade", "epoch": "1", "key": "0000000000000000000000000000000000000000000000000000000000000000" } + ``` **Response:** ```json + { "started": "1" } + ``` **Optional "count"** Number. Determines limit of number of accounts to upgrade. @@ -1777,15 +1969,19 @@ Reports the number of accounts in the ledger **Request:** ```json + { "action": "frontier_count" } + ``` **Response:** ```json + { "count": "920471" } + ``` --- @@ -1795,19 +1991,23 @@ Returns a list of pairs of account and block hash representing the head block st **Request:** ```json + { "action": "frontiers", "account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp", "count": "1" } + ``` **Response:** ```json + { "frontiers" : { "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } } + ``` --- @@ -1820,17 +2020,21 @@ Tells the node to send a keepalive packet to **address**:**port** **Request:** ```json + { "action": "keepalive", "address": "::ffff:192.169.0.1", "port": "1024" } + ``` **Response:** ```json + { "started": "1" } + ``` --- @@ -1840,17 +2044,21 @@ Generates an **adhoc random keypair** **Request:** ```json + { "action": "key_create" } + ``` **Response:** ```json + { "private": "781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3", "public": "3068BB1CA04525BB0E416C485FE6A67FD52540227D267CC8B6E8DA958A7FA039", "account": "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx" } + ``` --- @@ -1860,18 +2068,22 @@ Derive public key and account number from **private key** **Request:** ```json + { "action": "key_expand", "key": "781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3" } + ``` **Response:** ```json + { "private": "781186FB9EF17DB6E3D1056550D9FAE5D5BBADA6A6BC370E4CBB938B1DC71DA3", "public": "3068BB1CA04525BB0E416C485FE6A67FD52540227D267CC8B6E8DA958A7FA039", "account": "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3sxwjym5rx" } + ``` --- @@ -1886,14 +2098,17 @@ Returns frontier, open block, change representative block, balance, last modifie **Request:** ```json + { "action": "ledger", "account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp", "count": "1" } + ``` **Response:** ```json + { "accounts": { "nano_11119gbh8hb4hj1duf7fdtfyf5s75okzxdgupgpgm1bj78ex3kgy7frt3s9n": { @@ -1906,12 +2121,14 @@ Returns frontier, open block, change representative block, balance, last modifie } } } + ``` **Optional "representative", "weight", "receivable"** Booleans, false by default. Additionally returns representative, voting weight, receivable balance for each account **Request:** ```json + { "action": "ledger", "account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp", @@ -1920,9 +2137,11 @@ Booleans, false by default. Additionally returns representative, voting weight, "weight": "true", "receivable": "true" } + ``` **Response:** ```json + { "accounts": { "nano_11119gbh8hb4hj1duf7fdtfyf5s75okzxdgupgpgm1bj78ex3kgy7frt3s9n": { @@ -1939,6 +2158,7 @@ Booleans, false by default. Additionally returns representative, voting weight, } } } + ``` **Optional "modified_since"** _version 11.0+_ @@ -1966,18 +2186,22 @@ _version 20.0 will generate the node_id with `node_` prefix, earlier versions wi **Request:** ```json + { "action": "node_id" } + ``` **Response:** ```json + { "private": "2AD75C9DC20EA497E41722290C4DC966ECC4D6C75CAA4E447961F918FD73D8C7", "public": "78B11E1777B8E7DF9090004376C3EDE008E84680A497C0805F68CA5928626E1C", "as_account": "nano_1y7j5rdqhg99uyab1145gu3yur1ax35a3b6qr417yt8cd6n86uiw3d4whty3", "node_id": "node_1y7j5rdqhg99uyab1145gu3yur1ax35a3b6qr417yt8cd6n86uiw3d4whty3" } + ``` --- @@ -1987,27 +2211,33 @@ Returns a list of pairs of online peer IPv6:port and its node protocol network v **Request:** ```json + { "action": "peers" } + ``` **Response version 8.0+:** ```json + { "peers": { "[::ffff:172.17.0.1]:32841": "16" } } + ``` **Response before version 8.0:** ```json + { "peers": [ "[::ffff:172.17.0.1]:32841" ] } + ``` **Optional "peer_details"** @@ -2023,10 +2253,12 @@ _version 20.0 will generate the node_id with `node_` prefix, earlier versions wi "action": "peers", "peer_details": "true" } + ``` **Response:** ```json + { "peers": { "[::ffff:172.17.0.1]:7075": { @@ -2036,6 +2268,7 @@ _version 20.0 will generate the node_id with `node_` prefix, earlier versions wi } } } + ``` --- @@ -2048,15 +2281,19 @@ Scans all accounts, checks for unconfirmed blocks in account chains, and then qu **Request** ```json + { "action": "populate_backlog" } + ``` **Response** ```json + { "success": "" } + ``` --- @@ -2070,6 +2307,7 @@ Note: after v25.0, it is possible that the block processing queue can internally **Request:** ```json + { "action": "process", "json_block": "true", @@ -2086,12 +2324,15 @@ Note: after v25.0, it is possible that the block processing queue can internally "work": "000bc55b014e807d" } } + ``` **Response:** ```json + { "hash": "E2FB233EF4554077A7BF1AA85851D5BF0B36965D2B0FB504B2BC778AB89917D3" } + ``` **Optional "force"** _version 13.1+_ @@ -2129,17 +2370,21 @@ Returns a list of block hashes which have not yet been received by this account. **Request:** ```json + { "action": "receivable", "account": "nano_1111111111111111111111111111111111111111111111111117353trpda", "count": "1" } + ``` **Response:** ```json + { "blocks": [ "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" ] } + ``` **Optional "count"** Number. Determines limit of number of blocks to return. @@ -2150,20 +2395,24 @@ Number (128 bit, decimal). Returns a list of receivable block hashes with amount **Request:** ```json + { "action": "receivable", "account": "nano_1111111111111111111111111111111111111111111111111117353trpda", "count": "1", "threshold": "1000000000000000000000000" } + ``` **Response:** ```json + { "blocks" : { "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F": "6000000000000000000000000000000" } } + ``` **Optional "source"** _version 9.0+_ @@ -2171,15 +2420,18 @@ Boolean, false by default. Returns a list of receivable block hashes with amount **Request:** ```json + { "action": "receivable", "account": "nano_1111111111111111111111111111111111111111111111111117353trpda", "count": "1", "source": "true" } + ``` **Response:** ```json + { "blocks" : { "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F": { @@ -2188,6 +2440,7 @@ Boolean, false by default. Returns a list of receivable block hashes with amount } } } + ``` **Optional "include_active"** @@ -2196,12 +2449,14 @@ Boolean, false by default. Include active blocks without finished confirmations **Request:** ```json + { "action": "receivable", "account": "nano_1111111111111111111111111111111111111111111111111117353trpda", "count": "1", "include_active": "true" } + ``` **Optional "min_version"** @@ -2233,16 +2488,20 @@ Check whether block is receivable by **hash** **Request:** ```json + { "action": "receivable_exists", "hash": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "exists" : "1" } + ``` **Optional "include_active"** @@ -2252,11 +2511,13 @@ Boolean, false by default. Include active blocks without finished confirmations **Request:** ```json + { "action": "receivable_exists", "hash": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "include_active": "true" } + ``` **Optional "include_only_confirmed"** @@ -2271,12 +2532,15 @@ Returns a list of pairs of representative and its voting weight **Request:** ```json + { "action": "representatives" } + ``` **Response:** ```json + { "representatives": { "nano_1111111111111111111111111111111111111111111111111117353trpda": "3822372327060170000000000000000000000", @@ -2284,6 +2548,7 @@ Returns a list of pairs of representative and its voting weight "nano_114nk4rwjctu6n6tr6g6ps61g1w3hdpjxfas4xj1tq6i8jyomc5d858xr1xi": "0" } } + ``` **Optional "count"** @@ -2304,12 +2569,15 @@ Returns a list of online representative accounts that have voted recently **Request:** ```json + { "action": "representatives_online" } + ``` **Response:** ```json + { "representatives": [ "nano_1111111111111111111111111111111111111111111111111117353trpda", @@ -2317,11 +2585,13 @@ Returns a list of online representative accounts that have voted recently "nano_114nk4rwjctu6n6tr6g6ps61g1w3hdpjxfas4xj1tq6i8jyomc5d858xr1xi" ] } + ``` _versions 11.2–17.1_ Returns a list of pairs of online representative accounts that have voted recently and empty strings **Response:** ```json + { "representatives" : { "nano_1111111111111111111111111111111111111111111111111117353trpda": "", @@ -2329,6 +2599,7 @@ Returns a list of pairs of online representative accounts that have voted recent "nano_114nk4rwjctu6n6tr6g6ps61g1w3hdpjxfas4xj1tq6i8jyomc5d858xr1xi": "" } } + ``` **Optional "weight"** @@ -2336,6 +2607,7 @@ _version 17.0+_ Boolean, false by default. Returns voting weight for each representative. **Response:** ```json + { "representatives": { "nano_114nk4rwjctu6n6tr6g6ps61g1w3hdpjxfas4xj1tq6i8jyomc5d858xr1xi": { @@ -2343,6 +2615,7 @@ Boolean, false by default. Returns voting weight for each representative. } } } + ``` **Optional "accounts"** @@ -2350,18 +2623,22 @@ Array of accounts. Returned list is filtered for only these accounts. **Request:** ```json + { "action": "representatives_online", "accounts": ["nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p", "nano_1111111111111111111111111111111111111111111111111117353trpda"] } + ``` **Response:** ```json + { "representatives": [ "nano_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p" ] } + ``` --- @@ -2371,13 +2648,16 @@ Rebroadcast blocks starting at **hash** to the network **Request:** ```json + { "action": "republish", "hash": "991CF190094C00F0B68E2E5F75F6BEE95A2E0BD93CEAA4A6734DB9F19B728948" } + ``` **Response:** ```json + { "success": "", "blocks": [ @@ -2385,6 +2665,7 @@ Rebroadcast blocks starting at **hash** to the network "A170D51B94E00371ACE76E35AC81DC9405D5D04D4CEBC399AEACE07AE05DD293" ] } + ``` **Optional "sources"** @@ -2394,15 +2675,18 @@ Boolean, false by default. Additionally rebroadcast source chain blocks for rece **Request:** ```json + { "action": "republish", "hash": "90D0C16AC92DD35814E84BFBCC739A039615D0A42A76EF44ADAEF1D99E9F8A35", "count": "1", "sources": "2" } + ``` **Response:** ```json + { "blocks": [ "991CF190094C00F0B68E2E5F75F6BEE95A2E0BD93CEAA4A6734DB9F19B728948", @@ -2410,6 +2694,7 @@ Boolean, false by default. Additionally rebroadcast source chain blocks for rece "90D0C16AC92DD35814E84BFBCC739A039615D0A42A76EF44ADAEF1D99E9F8A35" ] } + ``` **Optional "destinations"** @@ -2419,15 +2704,18 @@ Boolean, false by default. Additionally rebroadcast destination chain blocks fro **Request:** ```json + { "action": "republish", "hash": "A170D51B94E00371ACE76E35AC81DC9405D5D04D4CEBC399AEACE07AE05DD293", "count": "1", "destinations": "2" } + ``` **Response:** ```json + { "blocks": [ "A170D51B94E00371ACE76E35AC81DC9405D5D04D4CEBC399AEACE07AE05DD293", @@ -2435,6 +2723,7 @@ Boolean, false by default. Additionally rebroadcast destination chain blocks fro "18563C814A54535B7C12BF76A0E23291BA3769536634AB90AD0305776A533E8E" ] } + ``` --- @@ -2445,6 +2734,7 @@ Signing provided **block** with private **key** or key of **account** from **wal **Request with private key:** ```json + { "action": "sign", "json_block": "true", @@ -2461,10 +2751,12 @@ Signing provided **block** with private **key** or key of **account** from **wal "work": "000bc55b014e807d" } } + ``` **Request with account from wallet:** ```json + { "action": "sign", "json_block": "true", @@ -2482,9 +2774,11 @@ Signing provided **block** with private **key** or key of **account** from **wal "work": "000bc55b014e807d" } } + ``` **Response:** ```json + { "signature": "2A71F3877033F5966735F260E906BFCB7FA82CDD543BCD1224F180F85A96FC26CB3F0E4180E662332A0DFE4EE6A0F798A71C401011E635604E532383EC08C70D", "block": { @@ -2499,6 +2793,7 @@ Signing provided **block** with private **key** or key of **account** from **wal "work": "000bc55b014e807d" } } + ``` **Optional "json_block"** @@ -2512,16 +2807,20 @@ _Requires configuration changes. Set "rpc.enable_sign_hash" to "true"_ **Request:** ```json + { "action": "sign", "hash": "E2FB233EF4554077A7BF1AA85851D5BF0B36965D2B0FB504B2BC778AB89917D3" } + ``` **Response:** ```json + { "signature": "2A71F3877033F5966735F260E906BFCB7FA82CDD543BCD1224F180F85A96FC26CB3F0E4180E662332A0DFE4EE6A0F798A71C401011E635604E532383EC08C70D" } + ``` --- @@ -2532,14 +2831,17 @@ For configuration and other details, please see [Statistics from RPC](/running-a **Request counters:** ```json + { "action": "stats", "type": "counters" } + ``` **Counters response:** ```json + { "type": "counters", "created": "2018.03.29 01:46:36", @@ -2561,20 +2863,24 @@ For configuration and other details, please see [Statistics from RPC](/running-a ... ] } + ``` _version 18.0+ also returns "stat_duration_seconds": the number of seconds since startup or since the last "stats_clear" call_ **Request samples:** ```json + { "action": "stats", "type": "samples" } + ``` **Samples response:** ```json + { "type": "samples", "created": "2018.03.29 01:47:08", @@ -2596,20 +2902,24 @@ _version 18.0+ also returns "stat_duration_seconds": the number of seconds since ... ] } + ``` _version 18.0+_ NOTE: This call is for debug purposes only and is unstable as returned objects may be frequently changed. **Request objects:** ```json + { "action": "stats", "type": "objects" } + ``` **Objects response:** ```json + { "node": { "ledger": { @@ -2631,6 +2941,7 @@ NOTE: This call is for debug purposes only and is unstable as returned objects m ... } } + ``` _version 22.0+_ @@ -2638,15 +2949,18 @@ NOTE: This call is for debug purposes only and is unstable as returned objects m **Request database:** ```json + { "action": "stats", "type": "database" } + ``` **Database response:** **LMDB:** ```json + { "branch_pages": "0", "depth": "1", @@ -2655,9 +2969,11 @@ NOTE: This call is for debug purposes only and is unstable as returned objects m "overflow_pages": "0", "page_size": "4096" } + ``` **RocksDB:** ```json + { "cur-size-all-mem-tables": "74063072", "size-all-mem-tables": "487744504", @@ -2670,6 +2986,7 @@ NOTE: This call is for debug purposes only and is unstable as returned objects m "block-cache-capacity": "318767104", "block-cache-usage": "150310696" } + ``` --- @@ -2681,15 +2998,19 @@ Clears all collected statistics. The "stat_duration_seconds" value in the "stats **Request:** ```json + { "action": "stats_clear" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -2702,15 +3023,19 @@ Method to safely shutdown node **Request:** ```json + { "action": "stop" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -2720,19 +3045,23 @@ Returns a list of block hashes in the account chain starting at **block** up to **Request:** ```json + { "action": "successors", "block": "991CF190094C00F0B68E2E5F75F6BEE95A2E0BD93CEAA4A6734DB9F19B728948", "count": "1" } + ``` **Response:** ```json + { "blocks" : [ "991CF190094C00F0B68E2E5F75F6BEE95A2E0BD93CEAA4A6734DB9F19B728948" ] } + ``` **Optional "offset"** @@ -2752,12 +3081,15 @@ Return metrics from other nodes on the network. By default, returns a summarized [Networking - node telemetry](/protocol-design/networking#node-telemetry) contains more detailed information on the protocol implementation of telemetry. **Request:** ```json + { "action": "telemetry" } + ``` **Response:** ```json + { "block_count": "214104509", "cemented_count": "214104509", @@ -2783,6 +3115,7 @@ Return metrics from other nodes on the network. By default, returns a summarized "node_id": "node_3odec59q6i9qarh5txyrxmu3aqhfzm54mxoxgtumwpzyq6obxqktdzcxkfag", "signature": "067523993D0B4C07525DF4C5AA814FBCC40875F868C2A04A85AC288F75E152763196B7DCB11240921F6D8BA92E3E9F094D8F2F9D8B0970114CDAD48838372100" } + ``` This contains a summarized view of the network with 10% of lower/upper bound results removed to reduce the effect of outliers. Returned values are calculated as follows: @@ -2816,14 +3149,17 @@ When setting raw to true metrics from all nodes are displayed. It additionally c **Request:** ```json + { "action": "telemetry", "raw" : "true" } + ``` **Response:** ```json + { "metrics": [ { @@ -2845,16 +3181,19 @@ When setting raw to true metrics from all nodes are displayed. It additionally c ... ] } + ``` **Optional "address" & "port"** Get metrics from a specific peer. It accepts both ipv4 and ipv6 addresses ```json + { "action": "telemetry", "address": "246.125.123.456", "port": "7075" } + ``` !!!tip "Requesting telemetry data from the local node" @@ -2867,16 +3206,20 @@ Check whether **account** is a valid account number using checksum **Request:** ```json + { "action": "validate_account_number", "account": "nano_1111111111111111111111111111111111111111111111111117353trpda" } + ``` **Response:** ```json + { "valid" : "1" } + ``` --- @@ -2888,12 +3231,15 @@ _RPC Version always returns "1" as of 01/11/2018_ **Request:** ```json + { "action": "version" } + ``` **Response:** ```json + { "rpc_version": "1", "store_version": "14", @@ -2904,6 +3250,7 @@ _RPC Version always returns "1" as of 01/11/2018_ "network_identifier": "991CF190094C00F0B68E2E5F75F6BEE95A2E0BD93CEAA4A6734DB9F19B728948", // since v20.0 "build_info": "Build Info \" version \" \"\" \"BOOST \" BUILT \"\"" // since v20.0 } + ``` --- @@ -2914,14 +3261,17 @@ Returns a list of pairs of unchecked block hashes and their json representation **Request:** ```json + { "action": "unchecked", "json_block": "true", "count": "1", } + ``` **Response:** ```json + { "blocks": { "87434F8041869A01C8F6F263B87972D7BA443A72E0A97D7A3FD0CCC2358FD6F9": { @@ -2937,6 +3287,7 @@ Returns a list of pairs of unchecked block hashes and their json representation } } } + ``` --- @@ -2949,15 +3300,19 @@ Clear unchecked synchronizing blocks **Request:** ```json + { "action": "unchecked_clear" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -2968,14 +3323,17 @@ Retrieves a json representation of unchecked synchronizing block by **hash**. Us **Request:** ```json + { "action": "unchecked_get", "json_block": "true", "hash": "19BF0C268C2D9AED1A8C02E40961B67EA56B1681DE274CD0C50F3DD972F0655C" } + ``` **Response:** ```json + { "modified_timestamp": "1565856525", "contents": { @@ -2990,6 +3348,7 @@ Retrieves a json representation of unchecked synchronizing block by **hash**. Us "work": "0dfb32653e189699" } } + ``` **Optional "json_block"** @@ -3006,15 +3365,18 @@ Retrieves unchecked database keys, blocks hashes & a json representations of unc **Request:** ```json + { "action": "unchecked_keys", "json_block": "true", "key": "19BF0C268C2D9AED1A8C02E40961B67EA56B1681DE274CD0C50F3DD972F0655C", "count": "1" } + ``` **Response:** ```json + { "unchecked": [ { @@ -3035,6 +3397,7 @@ Retrieves unchecked database keys, blocks hashes & a json representations of unc } ] } + ``` **Optional "json_block"** @@ -3054,20 +3417,24 @@ Returns the total receivable balance for unopened accounts in the local database **Request:** ```json + { "action": "unopened", "account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp", "count": "1" } + ``` **Response:** ```json + { "accounts": { "nano_1111111111111111111111111111111111111111111111111111hifc8npp": "207034077034226183413773082289554618448" } } + ``` **Optional "threshold"** @@ -3081,15 +3448,19 @@ Return node uptime in seconds **Request:** ```json + { "action": "uptime" } + ``` **Response:** ```json + { "seconds": "6000" } + ``` --- @@ -3102,16 +3473,20 @@ Stop generating **work** for block **Request:** ```json + { "action": "work_cancel", "hash": "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -3124,19 +3499,23 @@ Generates **work** for block. **hash** is the frontier of the account or in the **Request:** ```json + { "action": "work_generate", "hash": "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2" } + ``` **Response:** ```json + { "work": "2b3d689bbcb21dca", "difficulty": "fffffff93c41ec94", // of the resulting work "multiplier": "1.182623871097636", // since v19.0, calculated from default base difficulty "hash": "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2" // since v20.0 } + ``` **Optional "use_peers"** @@ -3193,17 +3572,21 @@ Add specific **IP address** and **port** as work peer for node until restart **Request:** ```json + { "action": "work_peer_add", "address": "::ffff:172.17.0.1", "port": "7076" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -3215,17 +3598,21 @@ _enable_control required, version 8.0+_ **Request:** ```json + { "action": "work_peers" } + ``` **Response:** ```json + { "work_peers": [ "::ffff:172.17.0.1:7076" ] } + ``` --- @@ -3238,15 +3625,19 @@ Clear work peers node list until restart **Request:** ```json + { "action": "work_peers_clear" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -3266,29 +3657,35 @@ Check whether **work** is valid for block. Provides two values: **valid_all** is **Request:** ```json + { "action": "work_validate", "work": "2bf29ef00786a6bc", "hash": "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2" } + ``` **Response since v21.0:** ```json + { "valid_all": "1", "valid_receive": "1", "difficulty": "fffffff93c41ec94", "multiplier": "1.182623871097636" // calculated from the default base difficulty } + ``` ??? abstract "Response up to v20.0" ```json + { "valid": "1", "difficulty": "fffffff93c41ec94", // since v19.0 "multiplier": "9.4609" // since v19.0 } + ``` **Optional "difficulty"** @@ -3298,15 +3695,18 @@ Difficulty value (16 hexadecimal digits string, 64 bit). Uses **difficulty** val **Request with given "difficulty"** ```json + { "action": "work_validate", "difficulty": "ffffffffffffffff", "work": "2bf29ef00786a6bc", "hash": "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2" } + ``` **Response with given "difficulty:** ```json + { "valid": "0", "valid_all": "1", // since v21.0 @@ -3314,6 +3714,7 @@ Difficulty value (16 hexadecimal digits string, 64 bit). Uses **difficulty** val "difficulty": "fffffff93c41ec94", "multiplier": "1.182623871097636" } + ``` **Optional "multiplier"** @@ -3344,17 +3745,21 @@ Creates a new account, insert next deterministic key in **wallet** **Request:** ```json + { "action": "account_create", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "account": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" } + ``` **Optional "index"** @@ -3363,11 +3768,13 @@ unset by default. Indicates which index to create account for starting with 0 **Request:** ```json + { "action": "account_create", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "index": "1" } + ``` **Optional "work"** @@ -3377,11 +3784,13 @@ Boolean, true by default. Setting false disables work generation after creating **Request:** ```json + { "action": "account_create", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "work": "false" } + ``` --- @@ -3391,18 +3800,22 @@ Lists all the accounts inside **wallet** **Request:** ```json + { "action": "account_list", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "accounts": [ "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" ] } + ``` --- @@ -3415,6 +3828,7 @@ Moves **accounts** from **source** to **wallet** **Request:** ```json + { "action": "account_move", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", @@ -3423,12 +3837,15 @@ Moves **accounts** from **source** to **wallet** "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" ] } + ``` **Response:** ```json + { "moved" : "1" } + ``` --- @@ -3441,17 +3858,21 @@ Remove **account** from **wallet** **Request:** ```json + { "action": "account_remove", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "account": "nano_39a73oy5ungrhxy5z5oao1xso4zo7dmgpjd4u74xcrx3r1w6rtazuouw6qfi" } + ``` **Response:** ```json + { "removed": "1" } + ``` --- @@ -3464,18 +3885,22 @@ Sets the representative for **account** in **wallet** **Request:** ```json + { "action": "account_representative_set", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "account": "nano_39a73oy5ungrhxy5z5oao1xso4zo7dmgpjd4u74xcrx3r1w6rtazuouw6qfi", "representative": "nano_16u1uufyoig8777y6r8iqjtrw8sg8maqrm36zzcm95jmbd9i9aj5i8abr8u5" } + ``` **Response:** ```json + { "block": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Optional "work"** @@ -3492,20 +3917,24 @@ Creates new accounts, insert next deterministic keys in **wallet** up to **count **Request:** ```json + { "action": "accounts_create", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "count": "2" } + ``` **Response:** ```json + { "accounts": [ "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000", "nano_1e5aqegc1jb7qe964u4adzmcezyo6o146zb8hm6dft8tkp79za3s00000000" ] } + ``` **Optional enabling work generation** _version 11.2+_ @@ -3513,12 +3942,14 @@ Boolean, false by default. Enables work generation after creating accounts **Request:** ```json + { "action": "accounts_create", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "count": "2", "work": "true" } + ``` ***Note:*** Before version 11.2 work generation was enabled by default, if you want to disable work generation for previous versions, use "work": "false" @@ -3537,17 +3968,21 @@ Changes the password for **wallet** to **password** **Request:** ```json + { "action": "password_change", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "password": "test" } + ``` **Response:** ```json + { "changed" : "1" } + ``` --- @@ -3557,17 +3992,21 @@ Enters the **password** in to **wallet** to unlock it **Request:** ```json + { "action": "password_enter", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "password": "test" } + ``` **Response:** ```json + { "valid": "1" } + ``` --- @@ -3577,16 +4016,20 @@ Checks whether the password entered for **wallet** is valid **Request:** ```json + { "action": "password_valid", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "valid" : "1" } + ``` --- @@ -3599,18 +4042,22 @@ Receive receivable **block** for **account** in **wallet**. If receiving the blo **Request:** ```json + { "action": "receive", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "account": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000", "block": "53EAA25CE28FA0E6D55EA9704B32604A736966255948594D55CBB05267CECD48" } + ``` **Response:** ```json + { "block": "EE5286AB32F580AB65FD84A69E107C69FBEB571DEC4D99297E19E3FA5529547B" } + ``` **Optional "work"** @@ -3627,15 +4074,19 @@ Returns receive minimum for node wallet **Request:** ```json + { "action": "receive_minimum" } + ``` **Response:** ```json + { "amount": "1000000000000000000000000" } + ``` --- @@ -3648,16 +4099,20 @@ Set **amount** as new receive minimum for node wallet until restart **Request:** ```json + { "action": "receive_minimum_set", "amount": "1000000000000000000000000000000" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -3679,16 +4134,20 @@ Tells the node to look for receivable blocks for any account in **wallet** **Request:** ```json + { "action": "search_receivable", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "started": "1" } + ``` --- @@ -3709,15 +4168,19 @@ Tells the node to look for receivable blocks for any account in all available wa **Request:** ```json + { "action": "search_receivable_all" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -3733,6 +4196,7 @@ Send **amount** from **source** in **wallet** to **destination** **Request:** ```json + { "action": "send", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", @@ -3741,12 +4205,15 @@ Send **amount** from **source** in **wallet** to **destination** "amount": "1000000", "id": "your-unique-id" } + ``` **Response:** ```json + { "block": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` Proof of Work is precomputed for **one** transaction in the background when you are using the node wallet to track accounts. If it has been a while since your last transaction it will send instantly, the next one will need to wait for Proof of Work to be generated. @@ -3765,6 +4232,7 @@ Using the same id for requests with different parameters (wallet, source, destin **Request:** ```json + { "action": "send", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", @@ -3773,12 +4241,15 @@ Using the same id for requests with different parameters (wallet, source, destin "amount": "1000000", "id": "7081e2b8fec9146e" } + ``` **Response:** ```json + { "block": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` Sending the request again will yield the same block, and will not affect the ledger. @@ -3790,6 +4261,7 @@ Work value (16 hexadecimal digits string, 64 bit). Uses **work** value for block **Request:** ```json + { "action": "send", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", @@ -3798,6 +4270,7 @@ Work value (16 hexadecimal digits string, 64 bit). Uses **work** value for block "amount": "1000000", "work": "2bf29ef00786a6bc" } + ``` --- @@ -3815,17 +4288,21 @@ Add an adhoc private key **key** to **wallet** **Request:** ```json + { "action": "wallet_add", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "key": "34F0A37AAD20F4A260F0A5B3CB3D7FB50673212263E58A380BC10474BB039CE4" } + ``` **Response:** ```json + { "account": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" } + ``` **Optional disabling work generation** @@ -3834,12 +4311,14 @@ Boolean, false by default. Disables work generation after adding account **Request:** ```json + { "action": "wallet_add", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "key": "34F0A37AAD20F4A260F0A5B3CB3D7FB50673212263E58A380BC10474BB039CE4", "work": "false" } + ``` --- @@ -3852,6 +4331,7 @@ Add watch-only **accounts** to **wallet** **Request:** ```json + { "action": "wallet_add_watch", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", @@ -3860,12 +4340,15 @@ Add watch-only **accounts** to **wallet** "nano_111111111111111111111111111111111111111111111111111000000000" ] } + ``` **Response:** ```json + { "success" : "" } + ``` --- @@ -3879,13 +4362,16 @@ Returns how many raw is owned and how many have not yet been received by all acc **Request:** ```json + { "action": "wallet_balances", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "balances" : { "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000": { @@ -3895,6 +4381,7 @@ Returns how many raw is owned and how many have not yet been received by all acc } } } + ``` **Optional "threshold"** @@ -3912,19 +4399,23 @@ Changes seed for **wallet** to **seed**. ***Notes:*** Clear all deterministic a **Request:** ```json + { "action": "wallet_change_seed", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "seed": "74F2B37AAD20F4A260F0A5B3CB3D7FB51673212263E58A380BC10474BB039CEE" } + ``` **Response:** ```json + { "success" : "", "last_restored_account": "nano_1mhdfre3zczr86mp44jd3xft1g1jg66jwkjtjqixmh6eajfexxti7nxcot9c", "restored_count": "1" } + ``` **Optional "count"** @@ -3939,17 +4430,21 @@ Check whether **wallet** contains **account** **Request:** ```json + { "action": "wallet_contains", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "account": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" } + ``` **Response:** ```json + { "exists": "1" } + ``` --- @@ -3962,15 +4457,19 @@ Creates a new random wallet id **Request:** ```json + { "action": "wallet_create" } + ``` **Response:** ```json + { "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Optional "seed"** @@ -3987,16 +4486,20 @@ Destroys **wallet** and all contained accounts **Request:** ```json + { "action": "wallet_destroy", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "destroyed": "1" } + ``` --- @@ -4006,16 +4509,20 @@ Return a json representation of **wallet** **Request:** ```json + { "action": "wallet_export", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "json" : "{\"0000000000000000000000000000000000000000000000000000000000000000\": \"0000000000000000000000000000000000000000000000000000000000000001\"}" } + ``` --- @@ -4025,18 +4532,22 @@ Returns a list of pairs of account and block hash representing the head block st **Request:** ```json + { "action": "wallet_frontiers", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "frontiers": { "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } } + ``` --- @@ -4049,13 +4560,16 @@ Reports send/receive information for accounts in wallet. Change blocks are skipp **Request:** ```json + { "action": "wallet_history", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "history": [ @@ -4077,6 +4591,7 @@ Reports send/receive information for accounts in wallet. Change blocks are skipp } ] } + ``` **Optional "modified_since"** @@ -4102,13 +4617,16 @@ Given a **wallet** id, from all of the accounts in the wallet, returns: **Request:** ```json + { "action": "wallet_info", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "balance": "10000", "pending": "10000", @@ -4120,6 +4638,7 @@ Given a **wallet** id, from all of the accounts in the wallet, returns: "accounts_block_count": "14", "accounts_cemented_block_count": "13" } + ``` --- @@ -4136,13 +4655,16 @@ Returns frontier, open block, change representative block, balance, last modifie **Request:** ```json + { "action": "wallet_ledger", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "accounts": { "nano_11119gbh8hb4hj1duf7fdtfyf5s75okzxdgupgpgm1bj78ex3kgy7frt3s9n": { @@ -4155,6 +4677,7 @@ Returns frontier, open block, change representative block, balance, last modifie } } } + ``` **Optional "representative", "weight", "receivable"** @@ -4162,6 +4685,7 @@ Booleans, false by default. Additionally returns representative, voting weight, **Request:** ```json + { "action": "wallet_ledger", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", @@ -4169,9 +4693,11 @@ Booleans, false by default. Additionally returns representative, voting weight, "weight": "true", "receivable": "true" } + ``` **Response:** ```json + { "accounts": { "nano_11119gbh8hb4hj1duf7fdtfyf5s75okzxdgupgpgm1bj78ex3kgy7frt3s9n": { @@ -4188,6 +4714,7 @@ Booleans, false by default. Additionally returns representative, voting weight, } } } + ``` **Optional "modified_since"** @@ -4203,16 +4730,20 @@ Locks **wallet** **Request:** ```json + { "action": "wallet_lock", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "locked": "1" } + ``` --- @@ -4222,16 +4753,20 @@ Checks whether **wallet** is locked **Request:** ```json + { "action": "wallet_locked", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "locked": "0" } + ``` --- @@ -4252,20 +4787,24 @@ Returns a list of block hashes which have not yet been received by accounts in t **Request:** ```json + { "action": "wallet_receivable", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "count": "1" } + ``` **Response:** ```json + { "blocks": { "nano_1111111111111111111111111111111111111111111111111117353trpda": ["142A538F36833D1CC78B94E11C766F75818F8B940771335C6C1B8AB880C5BB1D"], "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3": ["4C1FEEF0BEA7F50BE35489A1233FE002B212DEA554B55B1B470D78BD8F210C74"] } } + ``` **Optional "threshold"** @@ -4273,15 +4812,18 @@ Number (128 bit, decimal). Returns a list of receivable block hashes with amount **Request:** ```json + { "action": "wallet_receivable", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "count": "1", "threshold": "1000000000000000000000000" } + ``` **Response:** ```json + { "blocks": { "nano_1111111111111111111111111111111111111111111111111117353trpda": { @@ -4292,6 +4834,7 @@ Number (128 bit, decimal). Returns a list of receivable block hashes with amount } } } + ``` **Optional "source"** @@ -4300,15 +4843,18 @@ Boolean, false by default. Returns a list of receivable block hashes with amount **Request:** ```json + { "action": "wallet_receivable", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "count": "1", "source": "true" } + ``` **Response:** ```json + { "blocks": { "nano_1111111111111111111111111111111111111111111111111117353trpda": { @@ -4325,6 +4871,7 @@ Boolean, false by default. Returns a list of receivable block hashes with amount } } } + ``` **Optional "include_active"** @@ -4333,12 +4880,14 @@ Boolean, false by default. Include active blocks without finished confirmations **Request:** ```json + { "action": "wallet_receivable", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "count": "1", "include_active": "true" } + ``` **Optional "min_version"** @@ -4358,16 +4907,20 @@ Returns the default representative for **wallet** **Request:** ```json + { "action": "wallet_representative", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "representative": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" } + ``` --- @@ -4380,17 +4933,21 @@ Sets the default **representative** for **wallet** _(used only for new accounts, **Request:** ```json + { "action": "wallet_representative_set", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "representative": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" } + ``` **Response:** ```json + { "set": "1" } + ``` **Optional "update_existing_accounts"** @@ -4408,14 +4965,17 @@ Rebroadcast blocks for accounts from **wallet** starting at frontier down to **c **Request:** ```json + { "action": "wallet_republish", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "count": "2" } + ``` **Response:** ```json + { "blocks": [ "991CF190094C00F0B68E2E5F75F6BEE95A2E0BD93CEAA4A6734DB9F19B728948", @@ -4423,6 +4983,7 @@ Rebroadcast blocks for accounts from **wallet** starting at frontier down to **c "90D0C16AC92DD35814E84BFBCC739A039615D0A42A76EF44ADAEF1D99E9F8A35" ] } + ``` --- @@ -4435,18 +4996,22 @@ Returns a list of pairs of account and work from **wallet** **Request:** ```json + { "action": "wallet_work_get", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "works": { "nano_1111111111111111111111111111111111111111111111111111hifc8npp": "432e5cf728c90f4f" } } + ``` --- @@ -4459,17 +5024,21 @@ Retrieves work for **account** in **wallet** **Request:** ```json + { "action": "work_get", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp" } + ``` **Response:** ```json + { "work": "432e5cf728c90f4f" } + ``` --- @@ -4482,18 +5051,22 @@ Set **work** for **account** in **wallet** **Request:** ```json + { "action": "work_set", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F", "account": "nano_1111111111111111111111111111111111111111111111111111hifc8npp", "work": "0000000000000000" } + ``` **Response:** ```json + { "success": "" } + ``` --- @@ -4507,16 +5080,20 @@ Convert `nano` amount (10^30 raw) into `raw` (10^0) **Request:** ```json + { "action": "nano_to_raw", "amount": "1" } + ``` **Response:** ```json + { "amount": "1000000000000000000000000000000" } + ``` ### raw_to_nano @@ -4524,16 +5101,20 @@ Convert `raw` amount (10^0) into `nano` (10^30 raw) **Request:** ```json + { "action": "raw_to_nano", "amount": "1000000000000000000000000000000" } + ``` **Response:** ```json + { "amount": "1" } + ``` --- @@ -4562,13 +5143,16 @@ Returns the difficulty values (16 hexadecimal digits string, 64 bit) and related **Request:** ```json + { "action": "active_difficulty" } + ``` **Response:** ```json + { "deprecated": "1", "network_minimum": "fffffff800000000", @@ -4577,6 +5161,7 @@ Returns the difficulty values (16 hexadecimal digits string, 64 bit) and related "network_receive_current": "fffffe0000000000", // since V21.2 "multiplier": "1" } + ``` **Optional "include_trend"** @@ -4586,14 +5171,17 @@ Note: Before v20, the sampling period was between 16 and 36 seconds. **Request:** ```json + { "action": "active_difficulty", "include_trend": "true" } + ``` **Response:** ```json + { ..., "difficulty_trend": [ @@ -4605,6 +5193,7 @@ Note: Before v20, the sampling period was between 16 and 36 seconds. "1.000000000000000" ] } + ``` --- @@ -4629,16 +5218,20 @@ Divide a raw amount down by the krai ratio. **Request:** ```json + { "action": "krai_from_raw", "amount": "1000000000000000000000000000" } + ``` **Response:** ```json + { "amount": "1" } + ``` --- @@ -4651,16 +5244,20 @@ Multiply an krai amount by the krai ratio. **Request:** ```json + { "action": "krai_to_raw", "amount": "1" } + ``` **Response:** ```json + { "amount": "1000000000000000000000000000" } + ``` --- @@ -4673,16 +5270,20 @@ Divide a raw amount down by the Mrai ratio. **Request:** ```json + { "action": "mrai_from_raw", "amount": "1000000000000000000000000000000" } + ``` **Response:** ```json + { "amount": "1" } + ``` --- @@ -4695,16 +5296,20 @@ Multiply an Mrai amount by the Mrai ratio. **Request:** ```json + { "action": "mrai_to_raw", "amount": "1" } + ``` **Response:** ```json + { "amount": "1000000000000000000000000000000" } + ``` --- @@ -4721,15 +5326,19 @@ Removing node ID (restart required to take effect) **Request:** ```json + { "action": "node_id_delete" } + ``` **Response:** ```json + { "deprecated": "1" } + ``` --- @@ -4742,16 +5351,20 @@ Divide a raw amount down by the rai ratio. **Request:** ```json + { "action": "rai_from_raw", "amount": "1000000000000000000000000" } + ``` **Response:** ```json + { "amount": "1" } + ``` --- @@ -4764,16 +5377,20 @@ Multiply an rai amount by the rai ratio. **Request:** ```json + { "action": "rai_to_raw", "amount": "1" } + ``` **Response:** ```json + { "amount": "1000000000000000000000000" } + ``` --- @@ -4804,15 +5421,19 @@ Returns the hash of the block which is having the confirmation height set for, e **Request:** ```json + { "action": "confirmation_height_currently_processing" } + ``` **Response:** ```json + { "hash": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` --- @@ -4822,12 +5443,15 @@ Reports the number of blocks in the ledger by type (send, receive, open, change, **Request:** ```json + { "action": "block_count_type" } + ``` **Response:** ```json + { "send": "5016664", "receive": "4081228", @@ -4837,6 +5461,7 @@ Reports the number of blocks in the ledger by type (send, receive, open, change, "state_v1": "10653709", "state": "14870246" } + ``` --- @@ -4846,16 +5471,20 @@ Begin a new payment session. Searches wallet for an account that's marked as ava **Request:** ```json + { "action": "payment_begin", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "account" : "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000" } + ``` --- @@ -4865,16 +5494,20 @@ End a payment session. Marks the account as available for use in a payment sess **Request:** ```json + { "action": "payment_end", "account": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000", "wallet": "FFFD1BAEC8EC20814BBB9059B393051AAA8380F9B5A2E6B2489A277D81789EEE" } + ``` **Response:** ```json + { } + ``` --- @@ -4884,16 +5517,20 @@ Marks all accounts in wallet as available for being used as a payment session. **Request:** ```json + { "action": "payment_init", "wallet": "000D1BAEC8EC208142C99059B393051BAC8380F9B5A2E6B2489A277D81789F3F" } + ``` **Response:** ```json + { "status": "Ready" } + ``` --- @@ -4903,17 +5540,21 @@ Wait for payment of 'amount' to arrive in 'account' or until 'timeout' milliseco **Request:** ```json + { "action": "payment_wait", "account": "nano_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpi00000000", "amount": "1", "timeout": "1000" } + ``` **Response:** ```json + { "deprecated": "1", "status" : "success" } -``` + +``` diff --git a/docs/core-development/overview.md b/docs/core-development/overview.md index 6513d3d7f..7cc22111c 100644 --- a/docs/core-development/overview.md +++ b/docs/core-development/overview.md @@ -16,7 +16,6 @@ It is recommended to have an understanding of how the nano protocol is designed - Participate in the community through [Discord](https://chat.nano.org) - Start perusing the code in the repositories below and don't be afraid to ask questions - ## Code repositories The Nano Foundation manages the [`nanocurrency`](https://github.com/nanocurrency) GitHub Organization account which includes various repositories for nano tools and implementations. Below is a partial list of the most common repositories referenced. diff --git a/docs/core-development/understanding-the-code.md b/docs/core-development/understanding-the-code.md index 8967dfa04..d8b7230a7 100644 --- a/docs/core-development/understanding-the-code.md +++ b/docs/core-development/understanding-the-code.md @@ -34,6 +34,7 @@ All executables have `nano_` prefix and projects have a `main` function inside ` The googletest (gtest) framework is used to validate a variety of functionality in the node, we do not currently use gmock in the codebase. ### Running tests + The dev network is forced for locally run tests, this lowers work and other settings to make it simpler to test. Build with `cmake -DNANO_TEST=ON ..` See docs.nano.org for more information. There may be intermittent failures, if so add them here https://github.com/nanocurrency/nano-node/issues/1121 and fix if possible. @@ -47,12 +48,14 @@ See docs.nano.org for more information. There may be intermittent failures, if s **load_test** – This creates a dynamic number of nodes, sends blocks from 1 of the nodes (primary) and waits until all other nodes have the same number of blocks. This does not normally need to be modified but is run as part CI at the end. **rpc_test** – All RPC tests go here. There is some boilerplate to follow which creates an `ipc_server` for the node which mimics out of process rpc commands communicating with it. Care must be taken when creating write transactions as they are not allowed on io-threads (https://github.com/nanocurrency/nano-node/pull/1264). To make sure this is adhered to when calling the RPC commands, there is an RAII object `scoped_io_thread_name_change` which changes the current thread (normally the main one) to be `io`, and restores it when the object goes out of scope. For instance + ``` ... scoped_thread_name_io.reset (); node.process (state_block); scoped_thread_name_io.renew (); ``` + **slow_test** – Any core tests which are not suitable for CI because they take a long time (> a few seconds) should go here. There is a desire to make this file run once per night, but until then should be periodically run by developers. ### Work/Sig verification modifying for tests @@ -71,7 +74,9 @@ The fuzzer uses libfuzzer which inputs arbitrary data continuously trying to fin There aren’t currently tests for specific CLIs so it’s recommended to abstract the functionality so that it can be tested in `core_test`. ### Testing implementation details + Sometimes it is necessary to be able to change something about a class only for a test. Rather than make this the class interface public just for tests, the specific tests can be added as friends to the class, this is done like so for a test named like so TEST (node, example); + ``` class my_class { @@ -80,9 +85,11 @@ private: friend class node_example_Test; }; ``` + The test itself needs to be wrapped with the nano { } namespace for this to work correctly, if the class itself is in the nano namespace which is normally the case. ### Additional pre-release testing + - Run tests with TSAN/ASAN/Valgrind. All errors should be fixed before launch unless these are determined to be test related or false positives. We currently have some errors with using coroutines. There are blacklist files for the sanitizers which remove some errors caused by lmdb & rocksdb. --- @@ -147,6 +154,7 @@ The wallets database uses the wallets_store which only has an LMDB backend. `nano::lmdb::store::do_upgrades ()` is where LMDB database upgrades are done. For instance `void nano::lmdb::store::upgrade_v21_to_v22 ()` combines all block databases into a single one. Raw mdb functions are normally required as `block_store::get ()` and other functions normally can’t be used because they are updated to the latest db spec. The RocksDB upgrades were introduced by V25.0. It follows a similar approach implemented for LMDB. There were in the past multiple upgrades during a release when a beta build went out and a subsequent upgrade was desired. Previously a ledger reset was done and the version was re-used but this was deemed too inconvenient. ### write_database_queue + This was introduced to reduce LMDB write lock contention between the block processor and the confirmation height processor. As during bootstrapping or high TPS the block processor can hold onto the lock up to 5s (by default), before the lock is held by the blockprocessor it signals that it is about to get the LMDB lock, the confirmation height processor can make use of this information and continue processing where it would otherwise be stalled. Ongoing pruning also makes use of this. --- @@ -178,6 +186,7 @@ The biggest bottleneck for node start-up is caused by setting up the ledger cach Some classes use `node_initialized_latch.wait ();` The latch was added in https://github.com/nanocurrency/nano-node/pull/2042 this is to prevent some of the issues in the node constructor initializer list where the `node` object is passed and a child constructor is wants to use a node member which is not yet initialized. This makes it resume operation once the latch is incremented at the beginning of the `node` constructor. ### Initial output + When the node is run it prints out some information about the database used, compiler etc. An example of appending to the output is here: https://github.com/nanocurrency/nano-node/pull/2807 --- @@ -227,6 +236,7 @@ In `nano/lib/memory.hpp` a `nano::make_shared` function is defined which checks ## Libraries and submodules ### Boost + We use the Boost library where possible, such as coroutine, filesystem, endian converter, lexical_cast, multi_index_container etc. If there is a static/dynamic Boost library which is not used, there are generally no issues in adding it. Just make sure the build scripts and documentation are updated. **nano/boost** @@ -241,9 +251,11 @@ This is a small library which has no dependency to anything in the nano core, wh Any functionality which is shared between test projects and may also use gtest library. There is also `nano/node/testing.cpp` which has no gtest dependency because it is also used in CLI commands too. ### `nano/lib` vs. `nano/secure` + The`nano/lib` library was originally intended to be used by other programs wanting some of the nano functionality, but those specific external C functions were removed and it has now become the place to put all commonly used code. As such anything which doesn’t depend on the node should go here, and the `secure` library is now mostly for ledger specific things. ### git submodules + We have a variety of submodules https://docs.nano.org/node-implementation/contributing/?h=+submodule#about-the-code-base third party dependencies are to be kept as minimal as possible in order to keep build times lean, but if there is a suitable one it can be added a submodule. --- @@ -263,23 +275,29 @@ We have a variety of submodules https://docs.nano.org/node-implementation/contri To confirm a block a sufficient number of votes which are taken from `confirm_ack` messages are tallied up. If the tally is above the delta inside `nano::election::have_quorum ()` it returns true and the block is considered confirmed. `confirm_ack` messages can either contain the whole block or a hash (vote by hash). `confirm_req` message header as well as `confirm_ack` indicate what the type of the contents is in the header, either `not_a_block` which means dealing with block hashes or the block type. `nano/node/common.cpp` contains these messages (among others) and (de)serializing functions. ### voting + The vote generator `nano::vote_generator::vote_generator` is responsible for collecting hashes that need a vote generated, combining them into a single `vote by hash` message, signing the package with the representative key and publishing the votes to the network. A maximum of `nano::network::confirm_ack_hashes_max` hashes can be combined into a single vote `confirm_ack` message, this provides a decent tradeoff between optimizing vote signatures and reducing bandwidth. While the process is running it waits for `config.vote_generator_delay` time in order to pack more hashes into a single vote message. If there are more than `config.vote_generator_threshold` after waiting then it will wait for one additional `config.vote_generator_delay` before broadcasting the message. This allows for fast vote publishing at lower rates while enabling more hashes to be combined together at higher rates. ### vote_processor + Votes are signed by the representative and the vote processor schedules checking these votes through the `signature_checker` inside `nano::vote_processor::verify_votes ()`. Once a vote signature has been verified, the hashes within the vote packet are passed to active_elections where they are either added to an active election or added to the inactive votes cache if an election does not exist. ### active_transactions + The active transactions class handles election management and prioritization. When a block is processed and `nano::active_transactions::insert` called, a new election is started for the block hash if one does not already exist. In addition to starting elections there is a 500ms `request_loop` that handles election management. This process assists with moving elections through the different transition states as well as moving elections to a prioritized status if there is a backlog of elections. During the requst loop the current network difficulty is updated through `update_active_multiplier` which takes the top `prioritized_cutoff` number of active elections that have not been confirmed and samples their difficulty multiplier. Finally, the active transactions class also handles frontiers that have not been confirmed. Most commonly this is from bootstrapping, where the frontier of an account is added to the active elections and vote requests are sent to other nodes to confirm the frontier and thereby the rest of the account and ancestors through confirmation height processing. ### confirmation_solicitor + During the `request_loop` of the active transactions process, any election that is in the `active` state for more than 5 seconds will request votes from Principle Representative nodes that it has not seen a vote from yet. These requests are added to the `confirmation_solicitor` which aggregates the hashes up to `nano::network::confirm_req_hashes_max` into a single `confirm_req` message and publishes it to select PR nodes that have not voted. This helps fill any gaps in network communication failures where a vote may have been dropped which helps reach quorum on the highest priority elections. ### request_aggregator + The request aggregator is responsible for collecting vote requests `confirm_req` messages from other nodes and finding the optimal responses. A local vote cache is used for recently generated votes, if the block hash in the request exists in the cache then a cached vote is returned, if the hash does not exist then the hash is added to the vote generator and a new vote is generated and published to the requesting node. The request aggregator also handles publishing forks if the request is for a competing fork. If the local node has a different winning hash it will publish a vote for the winning hash instead of the requested hash in addition to sending the requesting node the winning block as well. ### election + An election is created when a new block is processed. The primary purpose of the election class is to tally the vote weight and ensure consensus between any competing forks. In order to efficiently move an election through the process it can have several states. Initially `passive` where it is waiting for votes from other nodes, then after 5 seconds if it has not been confirmed it will transition to `active` where vote requests to other nodes are made. After `active_request_count_min` rounds of requesting votes are complete if the election is still not confirmed it moves to `broadcasting` where it will publish the block to PR nodes that have not voted in an attempt to ensure the block has been propagated throughout the network. Under low load the `active` and `broadcasting` states are rarely used as all elections are complete within the `passive` window. Every vote that is added to the election triggers a check for whether quorum has been reached on the election. Quorum requires that the winning hash has `node.online_reps.delta` more weight than any competing forks. If quorum is reached the election is marked confirmed, transitions to the `confirmed` state and is added to the confirmation height procesor which updates the ledger. @@ -303,6 +321,7 @@ Instead of confirming every block in every account-chain one-by-one, the optimis See [here](https://github.com/nanocurrency/nano-node/pull/4111) for more details. ### Confirmation height processor + When a block is confirmed `void nano::node::process_confirmed ()` the block is added to the confirmation height processor. This begins the process of cementing it and all of its dependents, once this occurs these blocks can never be rolled back. There are 2 confirmation height algorithms bounded and unbounded. Originally only the unbounded one existed, this would store the block hash for the original block confirmed, all its previous blocks, and recurse the bottom most receive block to the source and repeat the process. If this hit something like the binance chain or (any long chain) it could use a lot of memory (unbounded amount). So this brought about the bounded confirmation height processor algorithm which starts at the very bottom of the account chains but does the same recursion when a receive block is hit. This limits the amount of block hashes needing to be stored in memory to be able to cement the bottom most blocks. Checkpoints are used if there are a lot of accounts which need to be traversed to reach which exceeds the maximum amount of memory . It does mean in certain cases the same iteration will need to be done more than once but this should be a rare case only during initial cementing. Once the uncemented count (block count – cemented count) is less than 16K the unbounded processor is used. As mentioned above this instead starts from the top (original confirmed block) and works downwards and saves all the blocks hit (not just hash) which means they don’t need to be re-read during writing later. This does use a lot more memory though which is why this is limited to a certain number of blocks, once the unbounded cutoff is exceeded the bounded processor resumes. @@ -310,11 +329,13 @@ Once the uncemented count (block count – cemented count) is less than 16K the Both algorithms operate with a read transaction first which reduces write lock held time as it can do a lot of iterating. This does mean that there can be some inconsistency by the time the writing is done, but this shouldn’t be an issue because once a block is confirmed by the network it will stay confirmed by `debug_assert` checks are added to catch any programming mistakes. While it is more effort to maintain 2 algorithms the unbounded one largely existed before so it made sense to re-use it, given the performance improvements in almost cemented ledgers. ### Frontiers confirmation + `nano/node/frontiers_confirmation.cpp` contains code which starts at the beginning of the accounts database (`nano::blockstore_partial::accounts_begin`) and iterates in ascending order and prioritises accounts based on the number of uncemented blocks (stores up to 100k) and requests confirmation for a limited number of these accounts. When the cemented count is above the hardcoded bootstrap weights this is limited to the number of optimistic elections which is 50 in this case so it is expected to be quite slow in this case. Accounts in wallets are also checked. --- ## Telemetry + nano/node/telemetry.cpp contains the logic for telemetry processing. This sets up an ongoing telemetry request round (every 60 seconds on the live network) where a telemetry_req message is sent to every peer. There is an `alarm` timeout of about 10 seconds in which we require the response (telemetry_ack) to be received otherwise it is rejected. Any calls to get_metrics_* return a cached result. To add a new definition to the telemetry_ack message this can be used as a guide which added the `active_multiplier`: https://github.com/nanocurrency/nano-node/pull/2728 `telemetry_ack` messages are signed and are backwards compatible with older nodes (from v22 onwards). Those nodes will verify the whole message including any extra unknown data which is appended at the end is just ignored. To prevent ddosing by `telemetry_req` messages, nodes ignore messages received within that 60second (on live) boundary. This is done in `void nano::bootstrap_server::receive_header_action ()` @@ -323,9 +344,11 @@ nano/node/telemetry.cpp contains the logic for telemetry processing. This sets u ## Stats ### Counters + The `stats` object is used to keep a count of events that have happened, this is a useful idiom for checking values in tests and is aggregated in the stats->counts RPC. There are main stat types and then details for that type. A simple example of adding new details and incrementing the stats can be seen here: https://github.com/nanocurrency/nano-node/pull/2515 Adding a type for a stat is a similar procedure just using the `nano::stat::type` enumerator. ### Objects + Most classes which have a member variable of container of multiple items (map, vector, list etc..) should have a function with a prototype of: `std::unique_ptr collect_container_info (my_class & my_class, std::string const & name);` And then call this in an owning object which should itself be called recursively until it reaches the `node` object `collect_container_info`. They are typically not made as part of the class itself because it’s a very specialised function which is only called as part of the stats->object RPC, like so: @@ -334,17 +357,21 @@ And then call this in an owning object which should itself be called recursively --- ## Pruning + Pruning occurs periodically inside `nano::node::ongoing_ledger_pruning ()`. Pruning currently requires a full ledger to be bootstrapped and when an account frontier is confirmed it can then be pruned. The hashes of the pruned blocks are put into the pruned database so that we know to ignore any of these old blocks should the node bootstrap them again. Pending blocks cannot be pruned currently. --- ## Config files + TOML config files are used, previously we used json files but TOML config files have the benefit of providing comments inside. There are no versions or upgrades done here, instead any defaults not explicitly overridden in the toml file get updated implicitly. There are few config files: ### config-node.toml + This is actually called `daemonconfig.cpp` in the code base, but it wraps a `node_config` object. ### Other config files + `config-rpc.toml` & `config-wallet.toml` contain settings which can be modified by the user to override the defaults. The most common ones are enabling rpc/websocket & rocksdb. The `nano/node/node_rpc_config.cpp` are the rpc settings for the node. @@ -386,11 +413,11 @@ This is used by both blocks/votes and creates (total threads / 2) to perform sig Peers are written to disk periodically. This was added in https://github.com/nanocurrency/nano-node/pull/1608 If the node has not been run in a long time (1 week), the peers list is cleared and the preconfigured peers list is used, this was added in https://github.com/nanocurrency/nano-node/pull/2506 - - Do not use the `node` object or include `node.hpp` in new core source files unless necessary, instead include the dependencies that it requires. We are still in the process of removing this idiom from other files because it adds circular dependencies, potentially ordering bugs and increases the build time. - Take care not to have nested `tx_begin_write ()`, it is quite easy to forget about this in tests, it will just cause a deadlock. To solve it, limit the scope: - Pass `std::shared_ptr` parameters by reference where possible, https://github.com/nanocurrency/nano-node/pull/3029 - Be cautious with random DB reads, they are much slower than sequential reads. This PR sped up the delegators by a factor of 100 RPC by removing the block_get call needed in the loop. https://github.com/nanocurrency/nano-node/pull/2283 + ``` { // Limit scope auto transaction = store->tx_begin_write (); @@ -399,9 +426,11 @@ If the node has not been run in a long time (1 week), the peers list is cleared … auto transaction = store->tx_begin_write (); ``` + or if it’s a single write can create a temporary just for that use: `block_put (store.tx_begin_write (), block);` Be cautious with callback lifetimes with asynchronous callbacks, such as the worker, alarm and asio. The following issue was because of them: + ``` int x = 4; worker.push_back ([&x]() { diff --git a/docs/glossary.md b/docs/glossary.md index 53eff142d..34f981cbe 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -4,146 +4,193 @@ description: A glossary of common terms used within the nano documentation and n # Glossary #### account + Refers to an address (starts with `xrb_` or `nano_` which are interchangeable) that you control the private keys of. An address is a reinterpretation of the 256-bit public key using BASE32 encoding and a checksum. Previously supported `xrb-` or `nano-` prefixes are deprecated. #### active transaction + A newly downloaded block to the node which enters into the voting process. #### ad hoc accounts + Accounts not derived from a private seed which can be held in the node wallet through the wallet ID. These accounts are only recommended for use with advanced systems. #### announcement rounds + A repeating half-second cycle on the node during which votes are collected for active transactions in attempt to reach quorum. #### Block + A single Nano transaction. All new transactions (e.g. sends, receives, representative changes, etc) on the Nano Protocol are communicated via state blocks (since node V11). The account's entire state, including the balance after each transaction, is recorded in each block. Transaction amounts are interpreted as the difference in balance between consecutive blocks. Before V11, each transaction type (open, send, receive, change) had its own legacy block type. #### block hash + A 64 character, uppercase hexadecimal string (0-9A-F) value representing a unique block on an account. #### Block height + A local integer value that represents the order of a block in an account chain. For example, the 15th block in an account would have a block height of 15. Related to (but different from) [confirmation height](#confirmation-height). #### Block Lattice + The Block Lattice is a data-structure in which individual accounts control their own blockchain. This allows transactions to be added quickly without conflict and sent to the network for confirmation. #### Blocks Per Second (BPS) + The transmission rate of [unconfirmed](#confirmation) blocks (transactions) on the network. #### bootstrap network + A sub-network established between peers via Transmission Control Protocol (TCP) for managing bulk transmission of blocks. This is used on initial bootstrapping of peers and when out-of-sync peers attempt to fill large gaps in their ledgers. This is available within all Nano networks (main, beta and test networks). #### bootstrapping + During initial sync, the nano\_node requests old transactions to independently verify and populate its local ledger database. Bootstrapping will also occur when the nano\_node becomes out of sync with the network. #### burn + When a 'burn' takes place, funds are sent to a specifc address that no one can access. Because no one can ever access funds sent to a burn address, it reduces the [circulating supply](#circulating-supply). #### circulating supply + 133,248,297.920938463463374607431768211455 Nano. This is the supply that resulted after [burns](#burn) were made from the [genesis](#genesis) account, landing account and faucet account, following original distribution. Actual circulating supply is lower due to lost keys and sends to burn accounts. The original supply minus any amounts sent to the burn account can be found using the [available_supply](/commands/rpc-protocol/#available_supply) RPC. #### Cementing + When a specific node marks a [confirmed](#confirmation) transaction as locally irreversible by setting the [account's](#account) [confirmation height](#confirmation-height) (in the node database) to the now higher [block height](#block-height) of the confirmed transaction. Cementing is a node-level operation. #### Confirmation + When a block (transaction) gathers enough votes from the network to pass [quorum](#quorum). Note that confirmed sends are irreversible (i.e. fully-settled), but the receiver must publish a corresponding receive block before they will be able to spend the [receivable](#receivable) funds. Confirmation is a network-level decision. #### Confirmation Height + A number stored in the local node database that represents the highest (most recent) [confirmed](#confirmation) block in an account chain. Related to (but different from) [block height](#block-height). #### Confirmations Per Second (CPS) + The rate of [confirmed](#confirmation) [blocks](#blocks). #### election #### frontier + The most recent block added to the account chain. Also called the head block. Can be either confirmed or unconfirmed. #### genesis + The first [account](#account) to be created, containing the maximum amount of Nano to ever exist. From here the funds were sent to other wallets; for distribution or to be [burned](#burn). #### head block + See [frontier](#frontier). #### inbound send + A block with funds being transferred to an [account](#account) owned by a [wallet](#wallet) on your node. #### legacy blocks + Blocks on an account chain before the first v1 block (which is often the v1 epoch block but can be other types). The first v1 block and all subsequent blocks are stateful blocks. #### live network + A sub-network established between peers via Transmission Control Protocol (TCP) for communicating newly published blocks, votes and other non-bootstrap related traffic. This is available within all Nano networks (main, beta and test networks). In versions prior to V19, this was done via User Datagram Protocol (UDP). UDP was retained as a fallback for peer connection for versions 19 and 20. In V21 it was deprecated, and in V25 it was fully removed. #### node version + The version used to identify a unique release build of the node. Each node version is tied to a single [protocol version](#protocol-version), but they are updated independently. #### online voting weight + Also called online stake, it is a trended value. The node samples online representative weights every 5 minutes across a rolling 2 week period. The online voting weight value is the median of those samples. #### peers + Nodes connected over the public internet to share Nano network data. #### pending + See [receivable](#receivable) #### Private Key + See [wallet](#wallet). #### Public Key + A public key is derived from a [private key](#private-key) using the ED25519 elliptic curve algorithm. An address is a representation of the public key, see [account](#account) for more info. #### Open Representative Voting (ORV) + A consensus mechanism unique to Nano which involves accounts delegating their balance as [voting weight](#voting-weight) to [Representatives](#representative). The Representatives [vote](#voting) themselves on the validity of transactions published to the network using the voting weight delegated to them. These votes are shared with their directly connected peers and they also rebroadcast votes seen from [Principal Representatives](#principal-representative). Votes are tallied and once [quorum](#quorum) is reached on a published block, it is considered confirmed by the network. #### Proof-of-Work (PoW) + A Proof-of-Work is a piece of data which satisfies certain requirements and is difficult (costly, time-consuming) to produce, but easy for others to verify. In some systems this data is a central part of the security model used to protect against double-spends and other types of attacks, but with Nano it is only used to increase economic costs of spamming the network. #### Principal Representative + A Nano account with >= 0.1% of the [online voting weight](#online-voting-weight) delegated to it. When configured on a node which is voting, the votes it produces will be rebroadcasted by other nodes to who receive them, helping the network reach consensus more quickly. #### protocol version + The version used to identify the set of protocol rules nodes are required to follow in order to properly communicate with peers. Nodes running older protocol versions are periodically de-peered on the network to keep communication efficient - see [Active Releases](/releases/node-releases/#active-releases) and [Inactive Releases](/releases/node-releases/#inactive-releases) for the latest versions allowed to peer with one another. #### qualified root + The concatenation of the root and previous attributes of a block. For the first block on an account, this would be is the account public key following by 32 zero bytes. For the second or higher block on an account, this would be the previous field repeated twice (root + previous, where root == previous). #### quorum + When the delta between the two successive blocks of a root is > 67% of the online voting weight. #### receivable + A transaction state where a block sending funds was published and confirmed by the network, but a matching block receiving those funds has not yet been confirmed. #### Representative + A Nano account with > 0 voting weight, but < 0.1% of the [online voting weight](#online-voting-weight), delegated to it. Unlike [Principal Representatives](#principal-representative), when configured on a node which is voting, the votes it produces and sends to directly connected peers won't be rebroadcasted by those peers. #### root + If the block is the first block on the account, the root is the account public key. Otherwise it is the previous hash included in the block. The root of a block can never be zero. #### seed + A 256-bit random value usually represented to the user as a 64 character hexidecimal (0-9 and A-F) value. Private keys are derived from a seed. #### Transactions Per Second (TPS) + Historically, TPS was a per-node measurement that represented a node's perception of the rate of transactions on the network ([BPS](#blocks-per-second-bps)). This measurement was found to be inaccurate due to peering and propagation differences between nodes, so [CPS](#confirmations-per-second-cps) is now the preferred term for describing overall Nano network scalability. It's also important to note that while Nano sends do not require a corresponding receive to be [confirmed](#confirmation), a receive block must be confirmed before received funds can be sent again (see [receivable](#receivable)). #### unchecked (blocks) + Blocks (transactions) that have been downloaded but not yet processed by the Nano node. The node software downloads all blocks from other nodes as unchecked, processes them and adds to block count, confirms the [frontier](#frontier) blocks for each account, and then marks them as [cemented](#cementing). #### unopened account + An account address that does not have a first block on it (which must be a block to receive Nano sent from another account, cannot be a block only changing the Representative). #### unpocketed + See [receivable](#receivable). #### vote-by-hash + Allows representatives to only include the hash of a block in each vote to save bandwidth. Before vote-by-hash was activated the entire block contents were required. #### voting + Each node configured with a [Representative](#representative) votes on every block by appending their Representative signature and a sequence number to the hash. These will be sent out to directly connected peers and if the vote originates from a [Principal Representative](#principal-representative), it will subsequently be rebroadcasted by nodes to their peers. #### voting weight + The amount of weight delegated to a [Representative](#representative). #### wallet + A wallet is an organizational object in a nano\_node that holds a single seed from which multiple accounts are deterministically derived via a 32-bit unsigned integer index starting at 0. Private keys are derived from the seed and index as follows: (`||` means concatenation; `blake2b` is a [highly optimized cryptographic hash function](/protocol-design/signing-hashing-and-key-derivation/#hashing-algorithm-blake2)) $$ @@ -151,7 +198,9 @@ k_{private} = blake2b(\text{seed} || \text{index}) $$ #### WALLET_ID + A 256-bit random value name/identifier for a specific wallet in the local nano\_node database. The WALLET\_ID **is not** stored anywhere in the network and is only used in the local nano\_node. Even though a WALLET\_ID looks identical to a seed, do not confuse the WALLET\_ID with a seed; funds cannot be restored with a WALLET\_ID. Do not backup the WALLET\_ID as a means to backup funds. #### work peers + Node peers which are configured to generate work for transactions at the originating nodes request. diff --git a/docs/index.md b/docs/index.md index 5dbdb39fe..ede2d9de1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,31 +1,34 @@ ---- -title: Home -description: Explore the design, features, releases and other related resources for the nano protocol and node implementation. -hide: - - navigation - - toc ---- - -# Nano Node and Protocol Documentation -Welcome! This documentation is focused on helping developers understand Nano, including setup, maintenance, and building on top of the Nano node. Details of how this documentation has been arranged are below: - -| Section | Details | Audience | -| | | | -|**[What is Nano?](what-is-nano/overview.md)**|Take a high-level tour - this is a great place to learn about how Nano is uniquely suited to being a global digital currency.|Everyone| -|**[Running a Node](running-a-node/overview.md)**| Set up a Nano node to manage the ledger, create and publish blocks and participate in consensus. | Node operators, developers | -|**[Integration Guides](integration-guides/the-basics.md)**| Learn practical concepts, structures and features for building wallets, payment systems and other services on the Nano network. | Developers | -|**[Living Whitepaper](living-whitepaper/index.md)**| Dive into the details of why Nano was created & how it's designed. Split into two sub-sections: [Protocol Design](protocol-design/introduction.md) & [Node Implementation](node-implementation/introduction.md). | Developers | -|**[Protocol Design](protocol-design/introduction.md)**| Dig deeper into the design and behaviors driving the protocol, including the election process, peering mechanics and more. | Developers | -|**[Node Implementation](node-implementation/introduction.md)**| Details of the Nano Foundation managed node implementation of the protocol. | Developers | -|**[Core Development](core-development/overview.md)**| Interested in contributing to the core Nano code or protocol? Here's how to get started. | Developers | -|**[Commands](commands/rpc-protocol.md)**| Explore an exhaustive list of interaction methods for the node via RPC and CLI. | Node operators, developers | -|**[Releases](releases/node-releases.md)**| Review past node releases and get details about the features coming soon in new releases. | Everyone | -|**[Glossary](glossary.md)**| Commonly used terms throughout the documentation and Nano ecosystem. | Everyone | - -**Join the Community** - -If you are looking for other details about Nano, links to wallets, discussions about the network and more, check out our community: - ---8<-- "community-links.md" - -[Change cookie settings](#__consent) +--- +title: Home +description: Explore the design, features, releases and other related resources for the nano protocol and node implementation. +hide: + + - navigation + - toc + +--- + +# Nano Node and Protocol Documentation + +Welcome! This documentation is focused on helping developers understand Nano, including setup, maintenance, and building on top of the Nano node. Details of how this documentation has been arranged are below: + +| Section | Details | Audience | +| | | | +|**[What is Nano?](what-is-nano/overview.md)**|Take a high-level tour - this is a great place to learn about how Nano is uniquely suited to being a global digital currency.|Everyone| +|**[Running a Node](running-a-node/overview.md)**| Set up a Nano node to manage the ledger, create and publish blocks and participate in consensus. | Node operators, developers | +|**[Integration Guides](integration-guides/the-basics.md)**| Learn practical concepts, structures and features for building wallets, payment systems and other services on the Nano network. | Developers | +|**[Living Whitepaper](living-whitepaper/index.md)**| Dive into the details of why Nano was created & how it's designed. Split into two sub-sections: [Protocol Design](protocol-design/introduction.md) & [Node Implementation](node-implementation/introduction.md). | Developers | +|**[Protocol Design](protocol-design/introduction.md)**| Dig deeper into the design and behaviors driving the protocol, including the election process, peering mechanics and more. | Developers | +|**[Node Implementation](node-implementation/introduction.md)**| Details of the Nano Foundation managed node implementation of the protocol. | Developers | +|**[Core Development](core-development/overview.md)**| Interested in contributing to the core Nano code or protocol? Here's how to get started. | Developers | +|**[Commands](commands/rpc-protocol.md)**| Explore an exhaustive list of interaction methods for the node via RPC and CLI. | Node operators, developers | +|**[Releases](releases/node-releases.md)**| Review past node releases and get details about the features coming soon in new releases. | Everyone | +|**[Glossary](glossary.md)**| Commonly used terms throughout the documentation and Nano ecosystem. | Everyone | + +**Join the Community** + +If you are looking for other details about Nano, links to wallets, discussions about the network and more, check out our community: + +--8<-- "community-links.md" + +[Change cookie settings](#__consent) diff --git a/docs/integration-guides/advanced.md b/docs/integration-guides/advanced.md index a99f2dc93..839e7a5ef 100644 --- a/docs/integration-guides/advanced.md +++ b/docs/integration-guides/advanced.md @@ -32,7 +32,6 @@ This guide extends the concepts covered in [External Private Key Management](/in 1. Transfer the signed transaction back to the `(HOT)` insecure online-computer. 1. `(HOT)` Publish the signed transaction to the Nano Network. -
```mermaid @@ -234,6 +233,7 @@ For details on configuring the HTTP callback within a node, see the [HTTP callba ``` Send state blocks have special fields "is_send" & "subtype" + ```json { "account": "nano_1ipx847tk8o46pwxt5qjdbncjqcbwcc1rrmqnkztrfjy5k7z4imsrata9est", @@ -255,7 +255,6 @@ Send state blocks have special fields "is_send" & "subtype" } ``` - !!! warning It is recommended to fetch the block using the hash provided in the callback rather than trust this data is valid, and check that data instead, since a malicious 3rd party can also make a fake callback request to your endpoint. @@ -340,7 +339,6 @@ curl -d '{ sudo systemctl enable nano_node - !!! tip To manage node, use [RPC commands](/commands/rpc-protocol) or [CLI](/commands/command-line-interface) @@ -356,12 +354,14 @@ and should be increased to at least 16384. ``` To resolve this on Linux increase max open files limit by editing `/etc/security/limits.conf` and adding or updating: + ``` * soft nofile 65535 * hard nofile 65535 root soft nofile 65535 root hard nofile 65535 ``` + Then restart session & `nano_node` service. Check changes with `ulimit -n`. For macOS the version impacts the steps necessary, but some people had success with the recipe in [https://superuser.com/a/1171028](https://superuser.com/a/1171028). diff --git a/docs/integration-guides/build-options.md b/docs/integration-guides/build-options.md index f78b12ed0..60bf84ad7 100644 --- a/docs/integration-guides/build-options.md +++ b/docs/integration-guides/build-options.md @@ -66,18 +66,21 @@ If you are building a version before V25.0, the node build commands further down * From inside [boost.src] run: === "*nix" + ```bash ./bootstrap.sh --with-libraries=context,coroutine,filesystem,log,program_options,system,thread ./b2 --prefix=[boost] --build-dir=[boost.build] link=static install ``` === "macOS" + ```bash ./bootstrap.sh --with-libraries=context,coroutine,filesystem,log,program_options,system,thread ./b2 --prefix=[boost] --build-dir=[boost.build] link=static install ``` === "Windows" + ```bash ./bootstrap.sh --with-libraries=context,coroutine,filesystem,log,program_options,system,thread ./b2 --prefix=[boost] --build-dir=[boost.build] address-model=64 link=static install @@ -90,6 +93,7 @@ If using this option, remove `bash util/build_prep/bootstrap_boost.sh -m` from t If building the Qt-based `nano_wallet`, first download [Qt 5.15.2+ open source edition](https://www.qt.io/download) and extract to [qt.src]. In [qt.build] execute: === "*nix" + ```bash [qt.src]/configure -shared -opensource -nomake examples -nomake tests -confirm-license -prefix [qt] make @@ -97,6 +101,7 @@ If building the Qt-based `nano_wallet`, first download [Qt 5.15.2+ open source e ``` === "macOS" + ```bash [qt.src]/configure -shared -opensource -nomake examples -nomake tests -confirm-license -prefix [qt] make @@ -104,6 +109,7 @@ If building the Qt-based `nano_wallet`, first download [Qt 5.15.2+ open source e ``` === "Windows" + ```bash [qt.src]/configure -shared -opensource -nomake examples -nomake tests -confirm-license -prefix [qt] nmake @@ -177,6 +183,7 @@ If building the Qt-based `nano_wallet`, first download [Qt 5.15.2+ open source e ``` **Configure repository with modern GCC** + ```bash sudo yum install gcc-toolset-12 scl enable gcc-toolset-12 bash @@ -215,6 +222,7 @@ If building the Qt-based `nano_wallet`, first download [Qt 5.15.2+ open source e The process below will create a release build of the node for the main network. See [network options](#network-options) below for details on building for the test or beta networks. === "*nix" + ```bash git clone --branch V25.0 --recursive https://github.com/nanocurrency/nano-node.git nano_build cd nano_build @@ -227,6 +235,7 @@ The process below will create a release build of the node for the main network. ``` === "macOS" + ```bash git clone --branch V25.0 --recursive https://github.com/nanocurrency/nano-node.git nano_build cd nano_build @@ -245,6 +254,7 @@ The process below will create a release build of the node for the main network. *Download Source* Using git_bash: + ```bash git clone --branch V25.0 --recursive https://github.com/nanocurrency/nano-node cd nano-node @@ -253,15 +263,18 @@ The process below will create a release build of the node for the main network. *Create a `build` directory inside nano-node (makes for easier cleaning of build)* Using git_bash: + ```bash mkdir build cd build ``` + * **Note:** all subsequent commands should be run within this "build" directory. *Get redistributables* Using Powershell: + ```bash Invoke-WebRequest -Uri https://aka.ms/vs/16/release/vc_redist.x64.exe -OutFile .\vc_redist.x64.exe ``` @@ -364,7 +377,6 @@ Run CMake GUI ![CMake Generator](../images/windows-10-build-instructions/cmake-generator.jpg) - **Visual studio** - Open project solution file in `C:\Users\YourUser\Documents\NanoSolution\nano-node-beta.sln` @@ -455,17 +467,20 @@ A number of tests binaries can be built when the CMake variable `-DNANO_TEST=ON` ### Running Tests To run all tests in a binary just launch it: + ```bash ./core_test ``` To check a specific subset of tests, gtest filtering can be used (with optional wildcards): + ```bash ./core_test --gtest_filter=confirmation_height.single ./rpc_test --gtest_filter=rpc.* ``` To run tests multiple times: + ```bash ./core_test --gtest_repeat=10 ``` @@ -484,6 +499,7 @@ If running on a debugger, add the argument `--gtest_break_on_failure` break at t 3 different CMake sanitizer options are supported: `NANO_ASAN_INT`, `NANO_TSAN` and `NANO_ASAN`. They cannot be used in conjunction with each other. #### Thread Sanitizer + Use `-DNANO_TSAN=ON` as an extra CMake option. The following environment variable should also be set: `export TSAN_OPTIONS="suppressions=../tsan_suppressions"` @@ -491,6 +507,7 @@ Use `-DNANO_TSAN=ON` as an extra CMake option. The following environment variabl `tsan_suppressions` should be a path to the file in the root nano directory. This suppresses many errors relating to the mdb and rocksdb libraries. #### Address Sanitizer + Use the CMake variable `-DNANO_ASAN=ON` or `-DNANO_ASAN_INT=ON` before running an executable. ### Valgrind diff --git a/docs/integration-guides/index.md b/docs/integration-guides/index.md index 68ff2fe9a..964687de5 100644 --- a/docs/integration-guides/index.md +++ b/docs/integration-guides/index.md @@ -88,12 +88,10 @@ This community built wallet is a production-ready, high performance developer wa [![Pippin](https://opengraph.githubassets.com/38565027a4d84e26310588fd4712b3cf836745cbe2b4a20ac44590225da01765/appditto/pippin_nano_wallet){width=50%}](https://github.com/appditto/pippin_nano_wallet) - ### Nault This community built wallet is more end-user focused with a robust GUI full of various options. It can be useful in development and testing as it supports setting the custom backend to your own node and can function as a basic account/block explorer. If you use this wallet, it also has an open source license so contributions are encouraged. - [![Nault](https://repository-images.githubusercontent.com/274627453/14c0c180-bc4a-11ea-82e9-cc23b8b5a718){width=50%}](https://github.com/Nault/Nault) --- @@ -115,4 +113,3 @@ If you've made it this far you may have a node running with a wallet setup and h - Tracking block confirmations: see [Block Confirmation Tracking guide](block-confirmation-tracking.md) - Performing efficient work generation: see [Work Generation guide](work-generation.md) - Optional WebSocket integration: see [WebSockets guide](websockets.md) - diff --git a/docs/integration-guides/ipc-integration.md b/docs/integration-guides/ipc-integration.md index bf80b89cc..c753a8994 100644 --- a/docs/integration-guides/ipc-integration.md +++ b/docs/integration-guides/ipc-integration.md @@ -82,11 +82,13 @@ The RPC gateway automatically translates between Flatbuffers and JSON messages o The examples below assumes the node is compiled with TLS support. If not, replace https with http. If using TLS with a self-signed certificate, add --insecure to curl commands. ### Making calls without a message envelope + A message envelope is a way to tell the server which message type is sent, as well as other information such as credentials. For HTTP clients, it's convenient to send messages _without_ an envelope. They do so by appending the message name (using uppercase CamelCase) to the path: `POST` to https://www.example.com:7076/api/v2/AccountWeight + ``` { "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3" @@ -139,6 +141,7 @@ The correlation header is Nano-Correlation-Id, which can be an arbitrary string. If the message name is missing from the path, an envelope will be expected which tells the node about the message type. `POST` to https://www.example.com:7076/api/v2 + ```json { "message_type" : "AccountWeight", @@ -231,6 +234,7 @@ curl --header "Nano-Api-Key:mywalletuser" --insecure -d \ '{ "account": "nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3"}' \ https://www.example.com:7076/api/v2/AccountWeight ``` + This uses HTTPS (which the node supports through a build option), and the `--insecure` is there because the node's certificate in this example is self-signed. Using an envelope instead of the `AccountWeight` endpoint: diff --git a/docs/integration-guides/key-management.md b/docs/integration-guides/key-management.md index 498796fd1..14eb53ee4 100644 --- a/docs/integration-guides/key-management.md +++ b/docs/integration-guides/key-management.md @@ -6,9 +6,11 @@ description: Learn best practices for private key management for the nano protoc ## Seeds ### Hex Seed + Nano's private key(s) have been traditionally derived from a 64 character, uppercase hexadecimal string (0-9A-F). This is currently the more popular form of seed supported by a variety of services and wallets. Additional details available in [The Basics guide](/integration-guides/the-basics/#seed). ### Mnemonic Seed + Wallets that provide mnemonic seeds should use the [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) standard word list and methods for generating the seed. When BIP32 master keys are generated from the seed, the HMAC hash key variation "ed25519 seed" should be used due to nano using [ed25519 for the signing algorithm](../protocol-design/signing-hashing-and-key-derivation.md#signing-algorithm-ed25519) (see [SLIP-0010](https://github.com/satoshilabs/slips/blob/master/slip-0010.md)). A non-standard derivation path is used for nano in the [Ledger Nano implementation](https://github.com/LedgerHQ/app-nano), as well as other popular wallets. With a coin-type of `165'` (`0x800000a5`), this is a partial BIP44 path of `m/44'/165'/[address index]`. Only hardened paths are defined. @@ -36,11 +38,15 @@ https://github.com/numsu/nanocurrency-web-js ``` edge defense waste choose enrich upon flee junk siren film clown finish luggage leader kid quick brick print evidence swap drill paddle truly occur ``` + Given Passphrase: + ``` some password ``` + Derived BIP39 Seed: + ``` 0dc285fde768f7ff29b66ce7252d56ed92fe003b605907f7a4f683c3dc8586d34a914d3c71fc099bb38ee4a59e5b081a3497b7a323e90cc68f67b5837690310c ``` @@ -48,14 +54,19 @@ Derived BIP39 Seed: ??? success "Index 0 (`44'/165'/0'`)" Derived Private Key: + ``` 3be4fc2ef3f3b7374e6fc4fb6e7bb153f8a2998b3b3dab50853eabe128024143 ``` + Derived Public key: + ``` 5b65b0e8173ee0802c2c3e6c9080d1a16b06de1176c938a924f58670904e82c4 ``` + Derived Address: + ``` nano_1pu7p5n3ghq1i1p4rhmek41f5add1uh34xpb94nkbxe8g4a6x1p69emk8y1d ``` @@ -63,14 +74,19 @@ Derived BIP39 Seed: ??? success "Index 1 (`44'/165'/1'`)" Derived Private Key: + ``` ce7e429e683d652446261c17a96da9ed1897aea96c8046f2b8036f6b05cb1a83 ``` + Derived Public key: + ``` d9f7762e9cd4e7ed632481308cdb8f54abf0241332c0a8641f61e92e2fb03c12 ``` + Derived Address: + ``` nano_3phqgrqbso99xojkb1bijmfryo7dy1k38ep1o3k3yrhb7rqu1h1k47yu78gz ``` @@ -78,14 +94,19 @@ Derived BIP39 Seed: ??? success "Index 2 (`44'/165'/2'`)" Derived Private Key: + ``` 1257df74609b9c6461a3f4e7fd6e3278f2ddcf2562694f2c3aa0515af4f09e38 ``` + Derived Public key: + ``` a46da51986e25a14d82e32d765dcee69b9eeccd4405411430d91ddb61b717566 ``` + Derived Address: + ``` nano_3b5fnnerfrkt4me4wepqeqggwtfsxu8fai4n473iu6gxprfq4xd8pk9gh1dg ``` @@ -99,6 +120,7 @@ company public remove bread fashion tortoise ahead shrimp onion prefer waste bla No Passphrase Derived BIP39 Seed: + ``` 924a962cae64448812be28a514093ebfeeed537d61a44318eb35f902961d21b2fccd30008d33c8d1d5327a34b9b73281c4b27a0a3d004c1c2e85e8dbb234cba8 ``` @@ -106,14 +128,19 @@ Derived BIP39 Seed: ??? success "Index 0 (`44'/165'/0'`)" Derived Private Key: + ``` 6f73d61ca0b56fcdb79d69d437f102348ad75ca971433eb92b2b003f8c99b48d ``` + Derived Public key: + ``` 134d938215f68bcaa3a0e574fde325fc4b1abad9bd3d698bfef95633b54ffb57 ``` + Derived Address: + ``` nano_16tfkg33dxndscjt3sdnzqjkdz4d5cxfmhbxf87zxycp8gtnzytqmcosi3zr ``` @@ -121,14 +148,19 @@ Derived BIP39 Seed: ??? success "Index 1 (`44'/165'/1'`)" Derived Private Key: + ``` 7e104389811a0967ef574af1f3f423f23cbf7b614be17844f67fb6fd315f9a7e ``` + Derived Public key: + ``` 71e6caac915affe836c3e822be6a5b3464f40c74bd2e5459d4e74205c6a7c0df ``` + Derived Address: + ``` nano_1wh8scpb4pqzx1ue9t34qso7pf56yi89bhbgcjexbst41q5chi8zqtwb74ih ``` @@ -136,19 +168,23 @@ Derived BIP39 Seed: ??? success "Index 2 (`44'/165'/2'`)" Derived Private Key: + ``` 8b7250869207a277ac37068dbe32782c2ab9fc6a5342f0deabbfdfae1285196a ``` + Derived Public key: + ``` fcebc6554853ed01c242817abf1b5050b887002f8de8f55d00c7c6b5fe01075d ``` + Derived Address: + ``` nano_3z9drscninzf193671dtqwfo1n7riw14z5hayogi3jy8pqz143txaghe4gbk ``` - ## External Management For larger, more robust systems, external private key management is recommended. In this setup, the node operator generates and stores private keys in an external database and only queries the nano\_node to: @@ -161,6 +197,7 @@ For larger, more robust systems, external private key management is recommended. [WALLET\_IDs](/integration-guides/the-basics/#wallet-id) are not used for External Private Key Management since private keys are not stored in the nano\_node. Much of this section builds off of the [Blocks Specifications](/integration-guides/the-basics/#blocks-specifications) documentation. --- + ### External accounting systems In order to properly implement accounting systems external to the Nano node the following best practices should be put into place, which ensure only fully confirmed blocks are used for external tracking of credits, debits, etc. @@ -175,7 +212,6 @@ In order to properly implement accounting systems external to the Nano node the Before crediting funds to an account internally based on a deposit on the network, the block sending the funds must be confirmed. This is done by verifying the network has reached quorum on the block. Details of the recommended verification process can be found in the [block confirmation tracking guide](/integration-guides/block-confirmation-tracking). - #### Tracking confirmed balances External accounting systems that track balances arriving to the node must track hashes of blocks that have been received in order to guarantee idempotency. Once confirmation of a block has been validated, the block hash should be recorded for the account along with any credits, debits or other related information. Any attempts to credit or debit accounts external to the node should check that no previous conflicting or duplicate activity was already recorded for that same block hash. @@ -193,6 +229,7 @@ However, you must always wait for the confirmation of **receivable blocks** befo A Nano private key is a 256-bit piece of data produced from a cryptographically secure random number generator. !!! danger "Secure Private Keys" + * Generating private keys from an insecure source may result in loss of funds. * Be sure to backup any generated private key; if lost the funds in the account will become inaccessible. @@ -320,6 +357,7 @@ curl -d '{ ``` !!! info "Additional details" + * The option `json_block`, available since V19.0, makes the RPC call return a non-stringified version of the block, which is easier to parse and always recommended. * [`block_create`](/commands/rpc-protocol#block_create) RPC commands generally take longer than other RPC commands because the nano\_node has to generate the [Proof-of-Work](/integration-guides/the-basics/#proof-of-work) for the transaction. The response block data is already properly formatted to include in the [`process`](/commands/rpc-protocol#process) RPC command. * The nano\_node creating and signing this transaction has no concept of what the transaction amount is, nor network state; all the nano\_node knows is that it is creating a block whose previous block on the account chain has hash `92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D` results in the account having a balance of `3618869000000000000000000000000`. @@ -536,6 +574,7 @@ curl -d '{ --8<-- "warning-process-sub-type-recommended.md" ##### Request Example + ```bash curl -d '{ "action": "process", @@ -556,6 +595,7 @@ curl -d '{ ``` ##### Success Response + ```json { "hash": "42A723D2B60462BF7C9A003FE9A70057D3A6355CA5F1D0A57581000000000000" @@ -571,8 +611,8 @@ curl -d '{ * The target proof-of-work difficulty threshold is obtained internally as the minimum between [`active_difficulty`](/commands/rpc-protocol/#active_difficulty) and `max_work_generate_multiplier` (converted to difficulty). * With a new, [higher difficulty](/integration-guides/the-basics/#difficulty-multiplier) proof-of-work, the block will get higher confirmation priority across the network. - !!! info "When a transaction does not confirm" + * If a transaction is taking too long to confirm, you may call the [`process`](/commands/rpc-protocol#process) RPC command with the same block data with no risk. * If for some reason a transaction fails to properly broadcast, subsequent transactions on the account-chain after that transaction will not be accepted by the network since the `"previous"` field in the transaction data refers to a non-existant block. * If this situation occurs, rebroadcasting the missing transaction(s) will make the subsequent blocks valid in the network's ledger. @@ -725,6 +765,7 @@ curl -d '{ ##### Error Response Response if the wallet_id isn't found in nano\_node: + ```json { "error": "Wallet not found" @@ -732,6 +773,7 @@ Response if the wallet_id isn't found in nano\_node: ``` Response if the seed field contains non-hexidecimal values or is too long: + ```json { "error": "Bad seed" @@ -941,4 +983,5 @@ curl -d '{ ] } ``` + On success, the nano\_node returns the hashes of all republished blocks. diff --git a/docs/integration-guides/the-basics.md b/docs/integration-guides/the-basics.md index 9a7ab133d..f318fdc82 100644 --- a/docs/integration-guides/the-basics.md +++ b/docs/integration-guides/the-basics.md @@ -12,7 +12,6 @@ Action | Description Send | Send funds from users account to another account Receive | Receive funds from a given "Send" transaction - The system is akin to writing (send) and cashing (receive) a Cashier's Check. There are a few things to consider about transactions: * The receiving account does not have to be online during the Send transaction. @@ -45,6 +44,7 @@ When dealing with the various IDs in the node it is important to understand the There are several things that can have a similar form but may have very different functions, and mixing them up can result in loss of funds. Use caution when handling them. ### Wallet ID + This is a series of 32 random bytes of data and is **not the seed**. It is used in several RPC actions and command line options for the node. It is a **purely local** UUID that is a reference to a block of data about a specific wallet (set of seed/private keys/info about them) in your node's local database file. The reason this is necessary is because we want to store information about each account in a wallet: whether it's been used, what its account is so we don't have to generate it every time, its balance, etc. Also, so we can hold ad hoc accounts, which are accounts that are not derived from the seed. This identifier is only useful in conjunction with your node's database file and **it will not recover funds if that database is lost or corrupted**. @@ -52,6 +52,7 @@ The reason this is necessary is because we want to store information about each This is the value that you get back when using the `wallet_create` etc RPC commands, and what the node expects for RPC commands with a `"wallet"` field as input. ### Seed + This is a series of 32 random bytes of data, usually represented as a 64 character, uppercase hexadecimal string (0-9A-F). This value is used to derive **account private keys** for accounts by combining it with an index and then putting that into the following hash function where `||` means concatenation and `i` is a 32-bit big-endian unsigned integer: `PrivK[i] = blake2b(outLen = 32, input = seed || i)` Private keys are derived **deterministically** from the seed, which means that as long as you put the same seed and index into the derivation function, you will get the same resulting private key every time. Therefore, knowing just the seed allows you to be able to access all the derived private keys from index 0 to $2^{32} - 1$ (because the index value is a unsigned 32-bit integer). @@ -81,6 +82,7 @@ It should be noted that Nano reference wallet is using described Blake2b private === "Bitcoinjs" Mnemonic words for Blake2b Nano seed using [Bitcoinjs](https://github.com/bitcoinjs/bip39): + ```js const bip39 = require('bip39') @@ -91,14 +93,16 @@ It should be noted that Nano reference wallet is using described Blake2b private // => '0000000000000000000000000000000000000000000000000000000000000001' ``` - ### Account private key + This is also a 32 byte value, usually represented as a 64 character, uppercase hexadecimal string(0-9A-F). It can either be random (an *ad-hoc key*) or derived from a seed, as described above. This is what represents control of a specific account on the ledger. If you know or can know the private key of someone's account, you can transact as if you own that account. ### Account public key + This is also a 32 byte value, usually represented as a 64 character, uppercase hexadecimal string (0-9A-F). It is derived from an *account private key* by using the ED25519 curve using Blake2b-512 as the hash function (instead of SHA-512). Usually account public keys will not be passed around in this form, rather the below address is used. ### Account public address + This is what you think of as someone's Nano address: it's a string that starts with `nano_` (previously `xrb_`), then has 52 characters which are the *account public key* but encoded with a specific base32 encoding algorithm to prevent human transcription errors by limiting ambiguity between different characters (no `O` and `0` for example). Then the final 8 characters are Blake2b-40 checksum of the account public key to aid in discovering typos, also encoded with the same base32 scheme (5 bytes). So for address `nano_1anrzcuwe64rwxzcco8dkhpyxpi8kd7zsjc1oeimpc3ppca4mrjtwnqposrs`: @@ -142,6 +146,7 @@ If an account balance decreases, the transaction that caused the decrease is con Because final balances are recorded rather than transaction amounts, API calls must be done carefully to avoid sending erroneous amounts. ### Block Format + Because each block contains the current state of the account, the `"type"` of the block is always `"state"`. The following table presents the anatomy of a block, along with the format used within RPC calls for building blocks, and the serialized, binary representation: | Key | RPC Format | Serialized | Description | @@ -166,6 +171,7 @@ Depending on the action each transaction intends to perform, the `"link"` field If using the [block_create](/commands/rpc-protocol#block_create) RPC command the optional fields `"source"` (with the block hash to be received) and `"destination"` (with the target `nano_` address) fields can be used instead of directly defining the `"link"` field. !!! note + * Any transaction may also simultaneously change the representative. The above description of the "Change" action is for creating a block with an explicit representative change where no funds are transferred (balance is not changed). * In the completed, signed transaction json, the `"link"` field is **always** hexadecimal. * The first block on an account must be receiving funds (cannot be an explicit representative change). The first block is often referred to as "opening the account". @@ -243,6 +249,7 @@ Change to representative with label and message nanoseed:[?][label=