├── .gitignore ├── _config.yml ├── chapters ├── primitives.md ├── supply-and-reward.md ├── account-tree.md ├── nodes-and-clients.md ├── transactions.md ├── verify.md ├── block.md ├── accounts-and-contracts.md ├── pool-protocol.md ├── messages.md └── constants.md ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist/docs/ 3 | /_site 4 | Gemfile 5 | Gemfile.lock 6 | _includes 7 | _layouts 8 | assets 9 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | remote_theme: nimiq/doc-theme 2 | title: "Nimiq" 3 | description: "Developer Reference" 4 | submodules: "none" 5 | -------------------------------------------------------------------------------- /chapters/primitives.md: -------------------------------------------------------------------------------- 1 | # Primitives 2 | 3 | ## Public Key 4 | 32 bytes, derived using the [Ed25519](https://ed25519.cr.yp.to/) algorithm. 5 | 6 | ## Signature 7 | 64 bytes. The result of the [Ed25519](https://ed25519.cr.yp.to/) `sign: (privateKey, message) -> signature` operation. 8 | 9 | ## Address 10 | Serialized in 20 bytes usually created by keeping the first 20 bytes of a hash or a public key. 11 | 12 | Alternatively, Nimiq addresses can also be expressed in a a human-friendly form: 13 | 14 | ``` 15 | NQCC XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX 16 | ``` 17 | 18 | * `NQ` as a prefix for "Nimiq". 19 | * Followed by a two digit checksum (`CC`) using the same algorithm like IBAN called [MOD-97-10](https://en.wikipedia.org/wiki/International_Bank_Account_Number#Check_digits) 20 | * The remaining part (`XXXX ...`) is the actual address base32 encoded as 32 characters. To reduce possibility of confusion the letters "I" and "O" are omitted. 21 | 22 | ## Hash 23 | A hash can be of three types, but only two are used: [Blake2b](https://en.wikipedia.org/wiki/BLAKE_%28hash_function%29#Blake2b_algorithm) and [Argon2d](https://en.wikipedia.org/wiki/Argon2) - SHA256 can be used for contracts, Blake2b is the default. 24 | When creating a light hash, Blake2b is used while when creating a hard hash as a proof of work, Argon2d ([memory-hard](https://en.wikipedia.org/wiki/Memory_bound_function)) is being used. 25 | Independently, a hash is always 32 bytes long. 26 | 27 | ## Variable integer 28 | 29 | The first byte (`type`) is used to determind which size should be used. Very small numbers are stored straight in the first byte, bigger numbers are stored in 2 to 8 bytes. 30 | 31 | | Element | Data type | Bytes | Description | 32 | |-----------|-------------|-----------|----------------------------| 33 | | type | uint8 | 1 | if < 0xFD, type is also the value 34 | | value | uint16..64 | 2..8 | depends on type; 0xFD: uint16, 0xFE: uint32, otherwise unit64 35 | 36 | 37 | -------------------------------------------------------------------------------- /chapters/supply-and-reward.md: -------------------------------------------------------------------------------- 1 | # Supply and Rewards 2 | 3 | ## Total and Circulating Supply 4 | 5 | The **total supply** of NIM is 21 billion (21e9 NIM, inspired by Bitcoin but increased by a factor of 1000). The smallest unit of NIM is also called Luna, there are 100,000 (1e5) Lunas in 1 NIM, which makes the total supply of NIM equivalent to 21e14 Luna (exactly like Bitcoin). 6 | 7 | The Mainnet's **initial supply** will be 12% of the total supply (2.52 billion NIM) which will be included in the Genesis Block and corresponds to the NIM redeemed by NET holders during NET-to-NIM conversion. 8 | 9 | After launch the **circulating supply** will increase in a curved fashion following our Dynamic Block Reward scheme. 10 | 11 | ## Dynamic Block Reward 12 | 13 | To avoid the inestability caused by the modification breakpoints in a halving scheme like Bitcoin's, Nimiq uses a **dynamic block reward**. The dynamic block reward ensures a smooth decay in the emission rate. It is inspired by [Monero](https://github.com/monero-project/research-lab/blob/master/whitepaper/whitepaper.pdf) & [Cryptonote](https://cryptonote.org/whitepaper.pdf). They base their reward in the following formula. 14 | 15 | blockReward = (totalSupply - circulatingSupply) >>> k 16 | 17 | We have taken a similar approach but we selected a value of `k=22` and, at a certain height (Block 48692960), switching to constant block reward of 4,000 Lunas (*tail emission*) until the total supply of 21e14 Lunas is reached. This has the following beneficial side effects: 18 | 19 | - At block 48692959 the dynamic block reward will be 4,001 Lunas, causing a **fluid transition to tail emission reward** of 4,000 Lunas. 20 | - The circulating supply at block 48692959 will be 2,099,983,215,900,000 Lunas, which is **divisible by 4,000**. 21 | - The last block governed by dynamic block reward will be reached in aproximately 92 years. 22 | - Block 48692960 will mark the beggining of tail emission. Remaining supply at this point will be 16,784,100,000 Lunas which results in **~7 years of a constant 4,000 reward**. 23 | - Total supply of 21e14 will be reached at block 52888984 (~100 years). 24 | 25 | ## Difficulty Adjustment 26 | 27 | The difficulty for every block is calculated according to the time it took to mine the last 120 blocks. To account for sudden changes in the global hashing power of the network, a minimum/maximum adjustment rate of 2 limits the variation of the difficulty. The targeted block time is 60s. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nimiq Blockchain 2 | [Nimiq](https://nimiq.com/) is a frictionless payment protocol for the web. For a high-level introduction please read the [Nimiq White Paper](https://medium.com/nimiq-network/nimiq-a-peer-to-peer-payment-protocol-native-to-the-web-ffd324bb084). The source code is available on [GitHub](https://github.com/nimiq-network/core). 3 | 4 | This developer reference contains: 5 | 6 | * [Data Schemas](#data-schemas) 7 | * [High Level Concepts and Architecture](#high-level-concepts) 8 | 9 | This documentation is also [available in German](https://terorie.github.io/nimiq-developer-reference-german/) as a community effort by Terorie. 10 | 11 | ## Data Schemas 12 | 13 | Data schemas as used on the wire, focusing on fields, bytes sizes and short explanations. 14 | 15 | * [Transactions](chapters/transactions.md): basic and extended 16 | * [Blockchain](chapters/block.md): block, header, interlink, body 17 | * [Accounts and Contracts](chapters/accounts-and-contracts.md): basic account, vesting and hashed time-locked contracts 18 | * [Accounts Tree](chapters/account-tree.md): details on the Patricia Merkle Tree used to store accounts 19 | * [Primitives](chapters/primitives.md): none-composed elements, e.g. hashes, addresses 20 | * [Messages](chapters/messages.md): All p2p-related inter-node messages 21 | 22 | ## High Level Concepts 23 | 24 | High level concepts used in and underlying Nimiq. 25 | 26 | * [Constants](chapters/constants.md): Configuration of the Nimiq core 27 | * [Nodes and Clients](chapters/nodes-and-clients.md): Node.js and browser, full, small, and nano 28 | * [Supply and Reward](chapters/supply-and-reward.md): total supply, rewards, difficulty adjustment 29 | * [Verification](chapters/verify.md): Validation rules for the Nimiq Blockchain 30 | 31 | ## Further Resources 32 | Further resources to get an overview of the Nimiq project and ecosystem: 33 | * [API Documentation](https://github.com/nimiq-network/core/blob/master/dist/API_DOCUMENTATION.md) 34 | * [Browser Miner](https://miner.nimiq.com) and [Browser Wallet](https://safe.nimiq.com) 35 | * [Contributing Guidelines](https://github.com/nimiq-network/core/blob/master/.github/CONTRIBUTING.md) and [Code of Conduct](https://github.com/nimiq-network/core/blob/master/.github/CODE_OF_CONDUCT.md) 36 | * This project is released under the [Apache License 2.0](https://github.com/nimiq-network/core/blob/master/LICENSE.md) 37 | 38 | 39 | We believe in communicating our concepts and approaches as clearly as possible. The easier it is to dive into the details, the more people will do it, again resulting in a deeper peer-reviewing process which is essential for the hardening of our protocol. 40 | You are very welcome to improve this reference via pull requests. 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /chapters/account-tree.md: -------------------------------------------------------------------------------- 1 | # Accounts Tree 2 | A tree storing addresses and account (i.e. balances and further fields). 3 | This tree's root is stored in each [block's header](block.md#header). 4 | The account tree can be used to verify that an account in a certain state was part of a certain block. 5 | And account tree is composed of [account tree nodes](#account-tree-node) using Ethereum's [Merkle Patricia Trie Specification](https://github.com/ethereum/wiki/wiki/Patricia-Tree). 6 | 7 | ## Accounts and Transactions 8 | 9 | Rules: 10 | * It forbidden to spend funds received in the same block 11 | * Transaction ordering: in general block order, but currently ignored because it is irrelevant when one can only spend funds one has received before the current block already. 12 | 13 | ### Adding Accounts to the Accounts Tree 14 | 15 | Procedure: 16 | 1. subtract from all sender accounts 17 | 2. add to all recipient accounts 18 | 3. create contract accounts 19 | 4. prune contract accounts (must be pruned when empty) 20 | 21 | Position in tree is unrelated to position in block body. 22 | 23 | ## Accounts Tree Nodes 24 | An accounts tree node can be of two types: branch or terminal. 25 | Branch nodes build the tree structure while the terminal nodes are the leaves of the tree. 26 | 27 | ### Accounts Tree Node Branch 28 | The tree structure is composed of prefixes to decend and find the correct account in a terminal node. 29 | A branch is composed of a prefix and children: 30 | 31 | | Element | Data type | Bytes | Description | 32 | |---------------|--------------|--------|--------------------------------------------------------------------| 33 | | type | uint8 | 1 | `0` | 34 | | prefix length | uint8 | 1 | | 35 | | prefix | string | length | Common part of the hashes of all accounts on this side of the tree | 36 | | child count | uint8 | 1 | Number of immediate tree sub nodes | 37 | 38 | And then for each child a structure as follows is attached: 39 | 40 | | Element | Data type | Bytes | Description | 41 | |---------------------|--------------|--------|-------------------------------------------| 42 | | child suffix length | uint8 | 1 | | 43 | | child suffix | string | length | Parent prefix + suffix compose new prefix | 44 | | child hash | Hash | 32 | Hash of part of the tree below | 45 | 46 | ### Accounts Tree Node Terminal 47 | The terminal node is the leave node of the account tree, it contains the actual account. 48 | 49 | | Element | Data type | Bytes | Description | 50 | |---------------|--------------|--------|-------------------------------------| 51 | | type | uint8 | 1 | `255` | 52 | | prefix length | uint8 | 1 | `20` | 53 | | prefix | string | length | The address of the account | 54 | | account | Account | >= 9 | The actual account, can be any kind | 55 | 56 | -------------------------------------------------------------------------------- /chapters/nodes-and-clients.md: -------------------------------------------------------------------------------- 1 | # Node and Client Types 2 | 3 | There are two types of clients in the Nimiq Network: NodeJS Clients and Browser Clients. Both types use the same isomorphic JavaScript code base and can run any of the three node types: Full, Light and Nano. Some combination of Node/Client types will, in the long run, be more common than others (i.e Browser Clients will mainly be light/nano nodes, and they won’t necessarily participate as miners). 4 | 5 | ## Client Types 6 | 7 | Depending on the platform (Browser/NodeJS) used to run the Client, it will work as a Browser Client or a NodeJS Client. Another main difference between the two of them is that Browser Clients store the Blockchain data in [IndexedDB](https://developers.google.com/web/ilt/pwa/working-with-indexeddb#what_is_indexeddb) (which has a limited capacity of ~50MB) whereas NodeJS Clients rely on [LevelDB](https://github.com/google/leveldb) (with no size constraint). To maintain a common codebase through Client Types we developed [JungleDB](https://github.com/nimiq-network/jungle-db). 8 | 9 | ### NodeJS Client 10 | 11 | NodeJS Clients are meant to run on servers and, thanks to their virtually unlimited storage capacity and publicly routable IP address, act as backbone of the network. They communicate with each other via [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket), and they act as entry point and signaling server for Browser Clients to establish browser-to-browser WebRTC connections. 12 | 13 | Browser APIs are restricted to secure origins. This means that NodeJS Clients need to provide an encrypted connection for Browser Clients to connect to them. This requires a domain and an SSL certificate. 14 | 15 | ### Browser Client 16 | 17 | Browser Clients are built upon browser engines and therefore they are completely installation-free. To connect to the network, they establish a WebSocket connection to at least one NodeJS Client. Once they have established their first connection, they start to establish browser-to-browser connections using the NodeJS Client as signaling server. Browser Clients can also act as signaling server for further browser-to-browser connections. 18 | 19 | By using [Babel](https://babeljs.io/) older browser versions are supported, WebRTC functionality is a requirement so only browsers that support WebRTC can connect to the network. 20 | 21 | An easy way to understand the different Clients/Nodes Types is to have a look at [the most simple web application on top of the Nimiq Blockchain](https://demo.nimiq.com/). 22 | 23 | ## Node Types 24 | 25 | Distinct Node types are used for different usecases and they differentiate from one another in the amount of data they need to download in order to join and synchronize with the network, which directly affects the time it takes each Node type to establish consensus and be able to process and validate transactions. 26 | 27 | ### Full Nodes 28 | 29 | Nodes of this type download the full blockchain thus requiring more storage. We expect this node type to be used solely with NodeJS Clients although theoretically it could run also in a browser. 30 | 31 | ### Light Nodes 32 | 33 | This type of nodes securely sync to almost full consensus by downloading just about 100 MB. To do that they use a LightChain which is initialized by using NiPoPoWs instead of the full blockchain history, but after initialization, it behaves as a regular full blockchain. 34 | 35 | ### Nano Nodes 36 | 37 | The preferred Node type for the Browser Clients since they require less data to be downloaded (~ 1MB) in order to establish consensus. 38 | -------------------------------------------------------------------------------- /chapters/transactions.md: -------------------------------------------------------------------------------- 1 | # Transactions 2 | 3 | - All transactions MUST transfer value (value > 0). 4 | - The value is always transferred from transaction _sender_ to transaction _recipient_. 5 | - The hash of the transaction does not include the signature/proof. 6 | - All transactions in Nimiq have a maximum validity window of 120 blocks, approximately two hours. 7 | - Transactions in Nimiq do not use a nonce, reoccurring, identical transactions can be send only once the previous transaction has been invalidated or mined. 8 | 9 | ## Basic transaction 10 | Size-Optimized format (138 bytes) for simple value transfer from basic to basic account. 11 | 12 | | Element | Data type | Bytes | Description | 13 | |-----------------------|--------------|-------|-------------------------------------------------| 14 | | Type | uint8 | 1 | `0` | 15 | | sender | raw | 32 | Public key of sender | 16 | | recipient | Address | 20 | Recipient's address | 17 | | value | uint64 | 8 | In Luna | 18 | | fee | uint64 | 8 | Miner fee | 19 | | validity start height | uint32 | 4 | Delay by blocks, defaults to current height + 1 | 20 | | network id | uint8 | 1 | Network ID (mainnet = 42) | 21 | | signature | raw | 64 | By sender's private key | 22 | 23 | To make a transaction validity shorter than the default of 120 blocks, set the start height to a value before the current blockchain height. For example, current height - 60 will result in a remaining livetime of 60 blocks, approximately one hour. 24 | 25 | 26 | ## Extended transaction 27 | Each extended transaction is at least 68 (3+|data|+65+|proof|) bytes long. 28 | 29 | | Element | Data type | Bytes | Description | 30 | |-----------------------|--------------|--------------|------------------------------------------------------------------------------| 31 | | Type | uint8 | 1 | `1` | 32 | | data length | uint16 | 2 | Maximum 64 | 33 | | data | raw | data length | Intended for recipient | 34 | | sender | Address | 20 | | 35 | | sender type | uint8 | 1 | Account type of sender | 36 | | recipient | Address | 20 | | 37 | | recipient type | uint8 | 1 | Account type of recipient | 38 | | value | uint64 | 8 | | 39 | | fee | uint64 | 8 | Fee for miner to include tx in a block | 40 | | validity start height | uint32 | 4 | Delay by blocks, defaults to current height + 1 | 41 | | network id | uint8 | 1 | Network ID (mainnet = 42) | 42 | | flags | uint8 | 1 | Unknown flags must be 0; Contract Creation (0x1) | 43 | | proof length | uint16 | 2 | | 44 | | proof | raw | proof length | Validity depends on sender account type, account state, current block height | 45 | 46 | ## Transaction hash 47 | A hash of a transaction is created by using Blake2b on all the fields of an [extended transaction](#extended-transaction), without `type`, `proof length`, and `proof`. 48 | -------------------------------------------------------------------------------- /chapters/verify.md: -------------------------------------------------------------------------------- 1 | # Verification 2 | Or: What's a valid Nimiq blockchain? 3 | 4 | ## Blockchain Verification 5 | [//]: # (how many blocks in suffix? 120 or 240) 6 | 7 | Of the [three client types](nodes-and-clients.md), a full client synchonizes the entire chain, while nano and light clients can skip major parts of chain due to a chain proof based on [NIPoPoW—Non-Interactive Proofs of Proof-of-Work](https://eprint.iacr.org/2017/963.pdf). 8 | The chain verification is split in two parts. First, during the suffix part, the client will build a complete list of 120 blocks starting from the header block. Nano clients will also drop the body part of each block to reduce load. From the last block of the suffix, the prefix will start by using the interlink to connect to the genesis block via the most difficult blocks in the chain and this way skipping major parts of the remaining blockchain. 9 | 10 | After intializing, a node will keep listening for new blocks to keep up with the blockchain. In case it receives more than one node as the immediate successor, it will choose the more difficult one (cf. [difficulty adjustment](https://nimiq.com/developer-reference/chapters/supply-and-reward.html#supply-and-rewards) for details). 11 | 12 | ### Verify Block Order 13 | Every block needs to be a valid successor of another block (besides the genesis block). 14 | 15 | A block is a valid successor if it is the [immediate successor](#verify-immediate-successor) of the known previous block (and the interlink is valid, cf. [verify interlink](#verify-interlink). 16 | 17 | #### Verify Immediate Successor 18 | Each block needs to be an immediate successor of the previous block. 19 | 20 | Rules comparing this block with the previous block: 21 | 22 | * This height = previous height + 1 23 | * This timestamp is >= previous time stamp 24 | * This previous hash == hash of previous block 25 | * Generating the next interlink on the previous block == interlink of this block. 26 | 27 | #### Verify Interlink Successor 28 | 29 | Rules to verify if this block has a valid predecessor in the interlink: 30 | 31 | * This height > predecessor height 32 | * This timestamp is >= previous time stamp 33 | * Verify that the predecessor is contained in this block's interlink 34 | * And if the predecessor's difficulty fits the position in this block's interlink 35 | * If the predecessor block is also the immediate predecessor: 36 | * Make sure that previous height == this height + 1 37 | * Generating the next interlink on the previous block == interlink of this block. 38 | * Otherwise, if not the immediate previous block make sure the previous block height is not exactly one less than this block's height 39 | * Otherwise 40 | * That the number of hashes that have been added to this block's interlink compared to the interlink in the previous block is at maximum the height difference 41 | * That the interlink is long enough to fit the previous block according to it's target 42 | * If both block share a block in the interlink, then all block below this shared block must be the same. 43 | 44 | ## Verify 45 | 46 | ### Verify Block 47 | 48 | See [block](block.md) for all the fields of a block. 49 | 50 | Rules 51 | * The [header is valid](#verify-header) 52 | * The block is not longer than 100kB (1e5 bytes) 53 | * The interlink is valid 54 | * And if it's a full block with body, also [verify the body](#verify-body) 55 | 56 | ### Verify Header 57 | 58 | * Time stamp must not be more than 10 minutes into the future compared to the local clock 59 | * Verify that proof of work suit's the current difficulty 60 | * Hash of the body equals body hash 61 | 62 | ### Verify Interlink 63 | 64 | * If this block is the genesis block (height = 1), then the interlink needs to be the hash of null, i.e. 32 bytes of `0` 65 | * Verify that the hash of the interlink (in body) == interlink hash of the header 66 | 67 | ### Verfiy Body 68 | 69 | * Verify each transaction 70 | * Is ordered correctly, cf. [transaction order](#transaction-order) 71 | * Is valid 72 | * And each account 73 | * Is ordered 74 | * Is to be pruned 75 | 76 | ### Transaction Order 77 | 78 | Transaction fields are compared by in following order: 79 | 80 | 1. Recipient 81 | 2. Validity start height: low first 82 | 3. Fee: higher first 83 | 4. Value: higher first 84 | 5. Sender 85 | 6. Recipient type 86 | 7. Sender type 87 | 8. Flags 88 | 89 | As soon as one field is not the same, the block can be ordered accordingly. Unless the field is a paricular number, the order is detemind by the bytes in the field, lower first (e.g. addresses, types, flags). 90 | 91 | ### Verify Transaction 92 | 93 | * Sender must not be recipient 94 | * Both sender's and recipient's account types must be valid account types 95 | * This transaction is a valid outgoing transaction for the sender's account type 96 | * And a valid incoming transaction for the recipient's account type 97 | 98 | ### Valid Incoming and Outgoing Transactions 99 | 100 | Basic accounts accept any kind of transaction. 101 | Outgoing transactions must have a [valid signature](#verify-signature-proof) for all the fields of a [extended transaction](transactions.md#extended-transaction), without `type`, `proof length`, and `proof`. 102 | 103 | ### Verify Signature Proof 104 | 105 | * Verify it's at most the length of public key + merkle path + signature 106 | * The sender must be the signer 107 | * That the signature is present 108 | * That the signature matches the public key 109 | -------------------------------------------------------------------------------- /chapters/block.md: -------------------------------------------------------------------------------- 1 | # Blockchain 2 | 3 | ## Block 4 | A Nimiq block can exist in two modes: full and light. A light block is equal to a full block, but does not have a body. 5 | A Nimiq block can be at most 100kB (100 thousand bytes) maximum and is composed of (body optional): 6 | 7 | | Element | Bytes | Description 8 | |-------------------|---------|-------- 9 | | Header | 146 | 10 | | Interlink | <= 8193 | 11 | | Full/Light Switch | 1 | `0` or `1` 12 | | Body | >= 117 | If switch is `1` 13 | 14 | 15 | ## Header 16 | The header has total size of 146 bytes and is composed of: 17 | 18 | | Element | Data type | Bytes | Description | 19 | |---------------|-----------|-------|-------------------------------------------------------------------| 20 | | version | uint16 | 2 | Protocol version | 21 | | previous hash | Hash | 32 | Hash of previous block | 22 | | interlink | Hash | 32 | Cf. [interlink](#interlink) | 23 | | body hash | Hash | 32 | Cf. [body hash](#body-hash) and [body](#body) | 24 | | accounts hash | Hash | 32 | Root hash of PM tree storing accounts state, cf. [account tree](accounts-tree.md) | 25 | | nBits | bits | 4 | Minimum difficulty for Proof-of-Work | 26 | | height | uint32 | 4 | Blockchain height when created | 27 | | timestamp | uint32 | 4 | When the block was created | 28 | | nonce | uint32 | 4 | Needs to fulfill Proof-of-Work difficulty required for this block | 29 | 30 | At main net launch time, version will be "1" and hashes in the header will be based on Blake2b. 31 | 32 | ### Previous Hash 33 | 34 | The expressions "block hash" and "block header hash" refer to the same hash. 35 | The hash is used to refer to the previous block in the blockchain. 36 | It's created using [Blake2b](#hash) on the serialized block header of the previous block as pre-image. 37 | 38 | 39 | ## Interlink 40 | The interlink implements the [Non Interactive Proofs of Proof of Work (NiPoPow)](https://eprint.iacr.org/2017/963.pdf) and contains links to previous blocks. 41 | 42 | An interlink is composed of: 43 | 44 | | Element | Data type | Bytes | Description | 45 | |-------------|--------------|---------------|------------------------------------------| 46 | | count | uint8 | 1 | Up to 255 blocks can be referred | 47 | | repeat bits | bit map | ceil(count/8) | So duplicates can be skipped. See below. | 48 | | hashes | [Hash] | <= count * 32 | Hashes of referred blocks | 49 | 50 | Repeat bits is a bit mask corresponding to the list of hashes, 51 | a 1-bit indicating that the hash at that particular index is the same as the previous one, 52 | i.e. repeated, and thus the hash will not be stored in the hash list again to reduce size. 53 | As each hash is represented by one bit the size is ceil(count/8). 54 | 55 | `hashes` are a list of up to 255 block hashes of 32 bytes each. 56 | 57 | Thus, an interlink can be up to 1+ceil(255/8)+255*32 = 8193 bytes. 58 | 59 | ### Interlink Construction 60 | The concept of [Non-Interactive Proofs of Proof-of-Work](https://eprint.iacr.org/2017/963.pdf) are used to create the interlink. 61 | 62 | An interlink contains hashes to previous blocks with a higher-than-target difficulty. The position of a hash in the interlink correlates to how much higher the difficulty was compared to the target difficulty. 63 | 64 | An interlink is created based on the interlink of the previous block plus putting the current hash into place. 65 | 66 | 1. The block's hash will be placed into the beginning of the new interlink as many times as it is more difficult than the required difficulty. 67 | 2. The remaining places of the new interlink will be filled by the hashes of the previous interlink, keeping the position. 68 | 69 | Finally, the interlink is compressed by counting and skipping repeating hashes. 70 | 71 | ## Body 72 | The body part is 25 bytes plus data, transactions, and prunded accounts: 73 | 74 | | Element | Data type | Bytes | Description | 75 | |-----------------------|-------------------------------|-------------------|-----------------------------------------------------| 76 | | miner address | Address | 20 | Recipient of the mining reward | 77 | | extra data length | uint8 | 1 | | 78 | | extra data | raw | extra data length | For future use | 79 | | transaction count | uint16 | 2 | | 80 | | transactions | [Transaction] | ~150 each | Transactions mined in this block | 81 | | pruned accounts count | uint16 | 2 | | 82 | | pruned accounts | [Pruned Account](accounts.md) | each >= 20+8 | Accounts with balence `0`; so they will be dropped | 83 | 84 | [Transactions](./transactions) can be basic or extended. 85 | Basic uses 138 bytes, extended more than 68 bytes. 86 | Transactions need to be in block order (first recipient, then validityStartHeight, fee, value, sender). 87 | Pruned accounts by their address. 88 | 89 | ### Body Hash 90 | The body hash is generated by calculating the root of a [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree) with following leaves: `miner address`, `extra data`, each `Transaction`, and each `Pruned Account` (in this order). 91 | 92 | ### Pruned Account 93 | A pruned account is composed of an account of any type with an address: 94 | 95 | | Element | Data type | Bytes | Description | 96 | |---------|-----------|-------|---------------------------------------------------| 97 | | address | Address | 20 | Address of account | 98 | | account | Account | >9 | Can be a basic account, vesting contract, or HTLC | 99 | 100 | This type is used in the body of a block to communicate the accounts to be pruned with this block. 101 | 102 | 103 | -------------------------------------------------------------------------------- /chapters/accounts-and-contracts.md: -------------------------------------------------------------------------------- 1 | # Accounts and Contracts 2 | 3 | Nimiq supports three types of accounts and contracts: [basic](#basic-account), [vesting contract](#vesting-contract), and [hashed time-locked contract](#hashed-time-locked-contract-htlc). 4 | 5 | All accounts and contracts share the following fields: 6 | 7 | | Element | Data type | Bytes | Description | 8 | |---------|--------------|-------|-------------------------------------------------------------------------------------------------| 9 | | type | uint8 | 1 | 0..2: basic, [vesting](#vesting-contract), [HTLC](#hashed-time-locked-contract-htlc); immutable | 10 | | balance | uint64 | 8 | In Luna; mutable | 11 | 12 | ## Account 13 | An account controlled by a (set of) private key(s). 14 | 15 | ### Basic Account 16 | A simple account that can hold funds (balance) and is controlled by a private key. 17 | The type field is set to `0`. No additional properties. 18 | No restrictions on when the funds might be used. Most common type. 19 | Basic account will automatically be pruned when made empty. It can be replaced by a contract account via a contract creation transaction. 20 | All addresses are initially empty basic accounts. 21 | 22 | ## Contracts 23 | Contract-specific properties are immutable. All incoming transactions will be rejected. 24 | Cannot be replaced by other contract accounts. 25 | Can only be explicitly pruned (replaced by an empty basic account) when empty. When pruning, contract type & contract-specific properties must be stored in the block body (for reverts). 26 | 27 | ### Contract Creation 28 | * If receiving account in a transaction is not to `basic` but the current recipient account type is `basic` and the contract creation flag `0x01` is set, a contract of the type defined for the recipient will be created. 29 | * The contract address is the transaction hash with the recipient address set to all zero (because recipient is not known at that time), truncated to the address size. 30 | * The recipient defined in the transaction must be equal to the contract address. 31 | * The created contract inherits any balance already present in the account, i.e. the funds of the contract will be added if a balance is already available. 32 | * All properties of the transaction are available to the contract constructor, i.e. all values are stored inside, no outside dependencies. 33 | 34 | ### Vesting Contract 35 | A vesting contract allows money to be spent in a scheduled way. An initial amount can be made available immediately followed by a scheduled release of the remaining amount. 36 | 37 | A vesting contract can be initialized in three different ways, from full/explicit to minimal: 38 | 39 | #### Full 40 | Defining all possible fields: 41 | 42 | | Element | Data type | Bytes | Description | 43 | |----------------------|--------------|-------|----------------------------------------------------------------------------| 44 | | type | uint8 | 1 | Set to `1` | 45 | | balance | uint64 | 8 | Must be >= `vesting total amount`. | 46 | | vesting start | uint32 | 4 | The block height to start with. | 47 | | vesting step blocks | uint32 | 4 | Number of blocks until next `vesting step amount` should be made available | 48 | | vesting step amount | uint64 | 8 | The amount to be made available each step | 49 | | vesting total amount | uint64 | 8 | The total amount to be spent in all steps added up. | 50 | 51 | If `balance` > `vesting total amount`, then the difference will be made available immediately. 52 | The first time a vesting becomes available is at block height of `vesting start` + `vesting step blocks`. 53 | If `vesting total amount` does not match an even number of steps, the last step will make the remaining amount available. 54 | All other steps have the exact amount as defined in `vesting step amount`. 55 | 56 | #### Normal 57 | 58 | | Element | Data type | Bytes | Description | 59 | |----------------------|--------------|-------|----------------------------------------------------------------------------| 60 | | type | uint8 | 1 | Set to `1` | 61 | | balance | uint64 | 8 | Must be >= `vesting total amount`. | 62 | | vesting start | uint32 | 4 | The block height to start with. | 63 | | vesting step blocks | uint32 | 4 | Number of blocks until next `vesting step amount` should be made available | 64 | | vesting step amount | uint64 | 8 | The amount to be made available each step | 65 | 66 | The field `vesting total amount` is again initialized with `balance`. 67 | 68 | #### Minimal 69 | 70 | | Element | Data type | Bytes | Description | 71 | |----------------------|--------------|-------|----------------------------------------------------------------------------| 72 | | type | uint8 | 1 | Set to `1` | 73 | | balance | uint64 | 8 | Must be >= `vesting total amount`. | 74 | | vesting step blocks | uint32 | 4 | Number of blocks until next `vesting step amount` should be made available | 75 | 76 | All other fields are initialized automatically: `vesting start` = 0, `vesting step amount` = `vesting total amount` = `balance` 77 | 78 | ### Hashed Time-Locked Contract 79 | Hashed Time-Locked Contracts (HTLCs) are used for conditional transfers, off-chain payment methods, and cross-chain [atomic swaps](https://en.wikipedia.org/wiki/Atomic_swap). [HTLC](https://en.bitcoin.it/wiki/Hashed_Timelock_Contracts) are time-limited. When settling the contract, a pre-image needs to be presented that fits the hash root to transfer the balance. 80 | 81 | | Element | Data type | Bytes | Description | 82 | |----------------|--------------|-------|------------------------------------------------| 83 | | type | uint8 | 1 | Set to `2` | 84 | | balance | uint64 | 8 | Must be >= `vesting total amount`. | 85 | | sender | Address | 20 | Normally, the sender will provide the amount | 86 | | recipient | Address | 20 | Signs the contract, usually the receiver of the amount | 87 | | hash algorithm | uint8 | 1 | 1 or 3, Blake2b or SHA256; Argon2d not allowed | 88 | | hash root | Hash | 32 | Hash of pre-image | 89 | | hash count | uint8 | 1 | How many times the proof has been hashed. Must be > 0. | 90 | | timeout | uint32 | 4 | Contract invalid after this amount of blocks | 91 | | total amount | uint64 | 8 | | 92 | 93 | If `balance` > `total amount`, then the difference will go back to the sender. 94 | 95 | Recipient signs the contract, but the outgoing transaction can go to somebody else, as long as it's signed this way, reducing the amount of transactions necessary. 96 | -------------------------------------------------------------------------------- /chapters/pool-protocol.md: -------------------------------------------------------------------------------- 1 | # Mining Pool protocol 2 | 3 | ## General 4 | 5 | ### Client modes 6 | 7 | The Nimiq Mining Pool protocol currently describes two client modes: smart and nano. 8 | 9 | #### smart 10 | 11 | In smart-mode, the client is fully responsible for creating blocks. 12 | The client operates as a solo-miner would do (and is also capable of doing a graceful fallback to solo mining). 13 | The server only describes the values to be used as a miner address and in the `extraData` field of a block. 14 | 15 | The smart-mode Pool Miner requires a Nimiq light- or full-node. 16 | 17 | #### nano 18 | 19 | In nano-mode, the client only validates that the pool asks for the correct chain to be operated on. 20 | The server provides all necessary details for the client to build the block, as long as it operates on a chain known to the client. 21 | This mode is similar to `getblocktemplate`-based protocols on Bitcoin. 22 | 23 | The nano-mode Pool Miner requires a Nimiq node of any kind, a nano-node is sufficient. 24 | 25 | ### Network communication 26 | 27 | A secure websocket connection is used as a transport layer for client-server communication. All messages are exchanged as a single WebSocket frame. 28 | 29 | ## Messages 30 | 31 | All messages follow the same structure: they consist of a JSON-encoded object with a property named `message` as well as message specific properties. 32 | 33 | #### `register` 34 | 35 | Send by client directly after connecting to the server. 36 | 37 | ##### Parameters 38 | 39 | | Parameter | Type | Description | 40 | |-----------|------|-------------| 41 | | `mode` | string, `nano` or `smart` | The mode this client uses | 42 | | `address` | string | The address (in IBAN-style format) that should be rewarded for the miner actions | 43 | | `deviceId` | number, uint32 | The clients device id. This ID should be unique for the device and stored, such that it stays the same after restarts | 44 | | `deviceData` | object, optional | A JSON object including stats about the device. The format of this JSON should be defined by the pool operator | 45 | | `genesisHash` | string | Base64 encoded hash of the genesis block used by the client | 46 | 47 | ##### Example 48 | 49 | ```json 50 | { 51 | "message": "register", 52 | "mode": "nano", 53 | "address": "NQ07 0000 0000 0000 0000 0000 0000 0000 0000", 54 | "deviceId": 12345678, 55 | "deviceData": { 56 | "groupLabel": "AWS Skylakes" 57 | }, 58 | "genesisHash": "Jkqvik+YKKdsVQY12geOtGYwahifzANxC+6fZJyGnRI=" 59 | } 60 | ``` 61 | 62 | #### `registered` 63 | 64 | Sent by the server after a succesful registration. Does not include parameters. 65 | 66 | ##### Example 67 | 68 | ```json 69 | { 70 | "message": "registered" 71 | } 72 | ``` 73 | 74 | #### `settings` 75 | 76 | Sent by the server to announce new mining settings. 77 | 78 | ##### Parameters 79 | 80 | | Parameter | Type | Description | 81 | |-----------|------|-------------| 82 | | `address` | string | The address (in IBAN-style format) that the client should use as a miner address for future shares | 83 | | `extraData` | string | Base64 encoded buffer that the client should use in the `extraData` field for future shares | 84 | | `targetCompact` | number, uint32 | The maximum allowed hash value for future shares, in compact form | 85 | | `nonce` |number, uint64 | A number used once that is associated with this connection | 86 | 87 | ##### Example 88 | 89 | ```json 90 | { 91 | "message": "settings", 92 | "address": "NQ07 0000 0000 0000 0000 0000 0000 0000 0000", 93 | "extraData": "J8riQiN1lgXT6QYlsdWMKA+qEWxCPYycjZ19zsk1...", 94 | "targetCompact": 520159232, 95 | "nonce": 1030036789885656 96 | } 97 | ``` 98 | 99 | #### `new-block` (nano) 100 | 101 | Sent by the server to announce a new block that should be used by a client running in nano-mode. 102 | 103 | ##### Parameters 104 | 105 | | Parameter | Type | Description | 106 | |-----------|------|-------------| 107 | | `bodyHash` | string | Base64 encoded hash of the block body | 108 | | `accountsHash` | string | Base64 encoded hash of the accounts tree after applying the block body | 109 | | `previousBlock` | string | Base64 encoded light block that is the predecessor of the block to be mined | 110 | 111 | ##### Example 112 | 113 | ```json 114 | { 115 | "message": "new-block", 116 | "bodyHash": "rCBGsSJGOOo82af+MhRXb7Dj+lb0oRzrN0EXBg7Jh4g=", 117 | "accountsHash": "9GgRxMDSVUpePCyUDKuAw3hmHeMEj7Y77GsWEssd2qU=", 118 | "previousBlock": "AAHL9kSzaU/uVRSsBVRSlYrx7Dw7NUSFDCWIDhY/..." 119 | } 120 | ``` 121 | 122 | #### `share` 123 | 124 | Sent by client when a valid share was found. 125 | 126 | ##### Parameters (nano) 127 | 128 | | Parameter | Type | Description | 129 | |-----------|------|-------------| 130 | | `block` | string | Base64 encoded light block | 131 | 132 | ##### Parameters (smart) 133 | 134 | | Parameter | Type | Description | 135 | |-----------|------|-------------| 136 | | `blockHeader` | string | Base64 encoded block header | 137 | | `minerAddrProof` | string | Base64 encoded inclusion proof for the `minerAddr` field in the block body | 138 | | `extraDataProof` | string | Base64 encoded inclusion proof for the `extraData` field in the block body | 139 | | `block` | string, optional | Base64 encoded full block. May only be sent if the block is a valid block so that the pool server is faster in picking it up | 140 | 141 | ##### Example (nano) 142 | 143 | ```json 144 | { 145 | "message": "share", 146 | "block": "AAHL9kSzaU/uVRSsBVRSlYrx7Dw7NUSFDCWIDhY/..." 147 | } 148 | ``` 149 | 150 | ##### Example (smart) 151 | 152 | ```json 153 | { 154 | "message": "share", 155 | "blockHeader": "AAHL9kSzaU/uVRSsBVRSlYrx7Dw7NUSFDCWIDhY/...", 156 | "minerAddrProof": "IXd9Hbms/FWTUl5YEYa5ztf6N9eIz+nIfswDOqGk...", 157 | "extraDataProof": "aZiypZ9S4qvSYbG4dBX4ww9TwOdKeLB+KRwNc0eP..." 158 | } 159 | ``` 160 | 161 | #### `error` 162 | 163 | Sent by the server if the client sent an invalid share. 164 | The server may send this message at most once per `share`. 165 | 166 | ##### Parameters 167 | 168 | | Parameter | Type | Description | 169 | |-----------|------|-------------| 170 | | `reason` | string | A user-readable string explaining why the server denied the share | 171 | 172 | ##### Example 173 | 174 | ```json 175 | { 176 | "message": "error", 177 | "reason": "Invalid PoW" 178 | } 179 | ``` 180 | 181 | #### `balance` 182 | 183 | Sent by the server to announce the balance that is currently hold by the pool for the address the user announced on `register`. 184 | 185 | The server may send this message at any time after the client registered. A new `balance` message does not imply any balance changes. 186 | 187 | ##### Parameters 188 | 189 | | Parameter | Type | Description | 190 | |-----------|------|-------------| 191 | | `balance` | number | The current balance of the user in the smallest possible unit. This includes funds that are not yet confirmed on the blockchain | 192 | | `confirmedBalance` | number | The current balance of the user in the smallest possible unit. This only includes funds that operator considers confirmed and are available for payout | 193 | | `payoutRequestActive` | boolean | `true`, if there is a payout request waiting for the user, `false` otherwise | 194 | 195 | ##### Example 196 | 197 | ```json 198 | { 199 | "message": "balance", 200 | "balance": 123010221, 201 | "confirmedBalance": 122010202, 202 | "payoutRequestActive": false 203 | } 204 | ``` 205 | 206 | #### `payout` 207 | 208 | Sent by the client to request payout from the server. Depending on server configuration, manual payout may be suspect to an additional fee. 209 | 210 | ##### Parameters 211 | 212 | | Parameter | Type | Description | 213 | |-----------|------|-------------| 214 | | `proof` | string | Base64 encoded signature proof of the string `POOL_PAYOUT`, concatenated with the byte representation of the connection nonce. | 215 | 216 | ##### Example 217 | 218 | ```json 219 | { 220 | "message": "payout", 221 | "proof": "J4VEpFwKNoklkyeUCvzBvixate3yPbDyYfWSusF/..." 222 | } 223 | ``` 224 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /chapters/messages.md: -------------------------------------------------------------------------------- 1 | # Messages 2 | 3 | All message contain following basic fields: 4 | 5 | | Element | Data type | Bytes | Description | 6 | |-----------|--------------|------------|----------------------------| 7 | | magic | uint32 | 4 | `0x42042042`, Indicating that this is a message. | 8 | | type | [VarInt](primitives.md#variable-integer) | >=1, <= 8 | Usually 1 bytes | 9 | | length | uint32 | 4 | Length of the message. Currently ignored. | 10 | | checksum | uint32 | 4 | CRC32 checksum. | 11 | 12 | All messages have a fixed [message type](constants.md#message-types). 13 | Additional fields of specialized messages will be added behind. 14 | 15 | ## Version Message 16 | 17 | This message `type = 0` sends out the status of this node, including it's protocol version, peer address, genesis block hash, and the hash of the latest block in its blockchain (the head). 18 | It must be the first message a node sends to another node. 19 | 20 | | Element | Data type | Bytes | Description 21 | |-----------------|------------|-------|--- 22 | | version | uint32 | 4 | Version of the protocol 23 | | peer address | uint32 | 4 | Three address types; see below 24 | | genesis hash | Hash | 32 | Hash of Genesis block 25 | | head hash | Hash | 32 | Hash of latest block in node's blockchain. 26 | | challenge nonce | raw | 32 | Peer needs to sign to authenticate. 27 | 28 | ## Version Acknowledgement Message 29 | 30 | Immediately after receiving the initial version message, a node answers with the version acknowledgement message. 31 | 32 | | Element | Data type | Bytes | Description 33 | |--------------|----------------|--------|--- 34 | | public key | raw | 32 | Public key of peer 35 | | signature | raw | 64 | Signature on received address concatinated with challenge nonce 36 | 37 | ## Addresses 38 | 39 | Three addresses are being used: Web Socket address, Web RTC address, and plain/dumb address. 40 | 41 | All three share following fields: 42 | 43 | | Element | Data type | Bytes | Description 44 | |--------------|----------------|--------|--- 45 | | protocol | uint8 | 1 | `0..2`: dumb, RTC, WS address. See below. 46 | | service mask | uint32 | 4 | `0` none, `1` nano, `2` light, `4` full 47 | | timestamp | uint64 | 8 | Used by other nodes to calculate offset. 48 | | net address | string | 1 - 17 | IPv4 address as string unless the IP is private (then empty string), or ``; first byte specifies length. 49 | | public key | raw | 32 | Peer's public key 50 | | signature | raw | 64 | Peer signs net address to make sure it can not be modified by someone else 51 | | distance | uint8 | 1 | Number of hops to this peer, `1` meaning the peers are connected directly. 52 | 53 | Each peer is identified by it's peer ID, which is obtained by truncating the public key down to 16 bytes. 54 | The RTC peer address uses the peer ID as signaling ID. 55 | 56 | A WS peer address has following additional fields: 57 | 58 | | Element | Data type | Bytes | Description 59 | |--------------|----------------|-------|--- 60 | | host | string | >10 | Hostname 61 | | port | number | 2 | Port number for Web Socket Connector to listen to. 62 | 63 | ## Request and Receive Inventory 64 | 65 | A typical situation: 66 | 1. Node A enters the network and needs to synchronize 67 | 1. B sends out a `get blocks` message 68 | 1. B receives and sends an `relay inventory` with hashes of blocks that B considers useful for A 69 | 1. B compares the list with the blocks it has already 70 | 1. B uses `get data` to request the data for the blocks it doesn't have yet. 71 | 72 | Similarily 73 | 1. Node A wants to update it's mempool and 74 | 1. A sends out a `mempool` message 75 | 1. Node B receives and sends an `relay inventory` message with blocks and transaction they have in their mempool 76 | 1. ... same like previous 77 | 78 | ### Get Blocks 79 | 80 | | Element | Data type | Bytes | Description | 81 | |-----------|----------------|-------|------------------------| 82 | | count | uint16 | 2 | Number of hashes requested 83 | | locators | [Hash] | count * 32 | List of block hashes from where to start sending more blocks. The receiving node will start sending from the first block it finds in it's blockchain. 84 | | max inventory size | uint8 | 2 | The number of blocks that are been asked. | 85 | | direction | uint8 | 1 | `1` forward (blocks afterwards); `2` backwards (previous blocks). 86 | 87 | The response can be `type = 6` for blocks, `7` for header, `8` for transaction, or `type = 4` if the requested inventory could not be found. 88 | 89 | ### Relay Inventory 90 | 91 | Announcing it's blocks and transmissions, a node sends out an inventory message: 92 | 93 | | Element | Data type | Bytes | Description 94 | |-----------|-------------|------------|--- 95 | | count | uint16 | 2 | 96 | | hashes | [Type+Hash] | count * 36 | Depending on type, hashes of transactions or blocks 97 | 98 | ### Requesting Data 99 | Request headers via `type = 3`, and block or transactions data via `type = 2` 100 | 101 | | Element | Data type | Bytes | Description 102 | |-----------|-------------|------------|--- 103 | | count | uint16 | 2 | 104 | | hashes | [Type+Hash] | count * 36 | Depending on type, hashes of transactions or blocks 105 | 106 | The type for each element in the hashes list can be `0..2`: error, transaction, and block. `0` is not being used. 107 | 108 | ### Block Message 109 | 110 | This message is used to send one block at a time (in serialized form). 111 | 112 | | Element | Data type | Bytes | Description | 113 | |-----------|-----------|----------|------------------------------| 114 | | block | Block | <= 100kB | [Full block](block.md#block) | 115 | 116 | ### Header Message 117 | 118 | This message is used to send one header at a time (in serialized form). 119 | 120 | | Element | Data type | Bytes | Description | 121 | |-----------|-----------|-------|------------------------| 122 | | header | Header | 162 | [Block header](block.md#header) | 123 | 124 | ### TX Message 125 | 126 | This message is used to send one header at a time (in serialized form). 127 | 128 | | Element | Data type | Bytes | Description | 129 | |-------------|-------------|-------|------------------------| 130 | | transaction | Transaction | XXX | [Transaction](transaction.md#header) | 131 | 132 | ## Mempool Message 133 | 134 | This message is used to request peers to relay their inventory/mempool content. No additional fields, `type = 9`, cf. [message types](constants.md#message-types). 135 | 136 | ## Reject Message 137 | 138 | 139 | This message is used to signal to a peer that something they sent to the node was rejected and the reason why it was rejected. 140 | 141 | | Element | Data type | Bytes | Description 142 | |--------------------|-----------------------------------------|--------|--- 143 | | message type | [VarInt](primitives.md#variable-integer) | 1 | [Message type](/constants.md#message-types) | 144 | | code | uint8 | 1 | [Reject message codes](/constants.md#reject-message-code) | 145 | | reason length | uint8 | 1 | 146 | | reason | string | length | The reason why. | 147 | | extra data length | uint16 | 2 | 148 | | extra data | raw | length | Extra information that might be useful to the requester. 149 | 150 | ## Subscribe Message 151 | 152 | This message is used to subscribe to messages from the node that this message is sent to, two version exist, "addresses" and "min fee". 153 | 154 | [//]: # (FIXME what's the effect of being subscribed? how to unsubscribe?) 155 | 156 | | Element | Data type | Bytes | Description | 157 | |-------------|----------------|-------|------------------------------------| 158 | | subscription type | uint8 | 1 | `2` for "addresses" or `3` for "min fee" 159 | 160 | Type "addresses" adds: 161 | 162 | | Element | Data type | Bytes | Description | 163 | |-------------|----------------|-------|------------------------------------| 164 | | address count | uint16 | 2 | Number of addresses 165 | | addresses | [Address] | count * 20 | List of addresses to subscribe to 166 | 167 | Type "min fee" adds: 168 | 169 | | Element | Data type | Bytes | Description 170 | |---------|-----------|-------|--- 171 | | fee | uint64 | 8 | Min fee per byte in Luna required to subscribe 172 | 173 | ## Relay Addresses 174 | 175 | This message is used to relay the addresses to other peers. 176 | 177 | ### Get Addresses Message 178 | 179 | Ask for for addresses to peers that use the specified protocol and provide the specified services. 180 | 181 | | Element | Data type | Bytes | Description 182 | |---------------|-----------|-------|--- 183 | | protocol mask | uint8 | 1 | `0` dumb, `1` ws, `2` rtc 184 | | service mask | uint32 | 4 | `0` none, `1` nano, `2` light, `4` full 185 | 186 | ### Addresses Message 187 | 188 | A list of address in return for a `get addresses` message. 189 | 190 | | Element | Data type | Bytes | Description 191 | |---------------|-----------|------------|--- 192 | | address count | uint16 | 2 | Number of addresses 193 | | addresses | [Address] | count * 20 | List of addresses of other peers in the network. 194 | 195 | ## Heart Beat Messages 196 | 197 | This messages are used to make sure that the other peer node is available still. 198 | 199 | | Element | Data type | Bytes | Description 200 | |---------|-----------|-------|--- 201 | | type | uint16 | 2 | `22` for ping, `23` for pong (response) 202 | | ... 203 | | nonce | uint32 | 4 | Make pings and pongs unique, avoid replay | 204 | 205 | ## Signal Message 206 | 207 | [//]: # (FIXME What's the effect of this message? Answers?) 208 | 209 | Signaling is needed for the [browser clients](nodes-and-clients.md#browser-client) to establish a connection with other clients of the same type. 210 | 211 | | Element | Data type | Bytes | Description 212 | |--------------------|-----------|--------|--- 213 | | sender id | raw | 16 | 16 bytes address of sender 214 | | recipient id | raw | 16 | 16 bytes address of recipient 215 | | nonce | uint32 | 4 | To avoid replay 216 | | time to live | uint8 | 1 | TTL 217 | | flags | uint8 | 1 | Unroutable: `0x1`, TTL exceeded: `0x2` 218 | | payload length | uint16 | 2 | 219 | | payload | raw | length | Signed data, cf. `signature` 220 | | sender public key | uint32 | 32 | If payload payload length > 0 221 | | signature | raw | 64 | If payload payload length > 0 222 | 223 | ## Relay Proofs 224 | 225 | ### Chain Proof 226 | To get chain proof, sent a basic message with type = `40`. 227 | 228 | [//]: # (FIXME More details on the response. Any fields in get?) 229 | 230 | The response (`type = 41`) contains blocks and headers. 231 | 232 | | Element | Data type | Bytes | Description 233 | |--------------------|---------------------------|-------------------|--- 234 | | block count | uint16 | 2 | Amount of blocks attached 235 | | blocks | [Block](block.md#block) | max count * 100kB | Full blocks 236 | | header count | uint16 | 2 | Amount of headers attached 237 | | header chain | [Header](block.md#header) | count * 162 | Headers 238 | 239 | ### Accounts Proof 240 | 241 | A node can ask (`type = 42`) for proofs for certain accounts by using the hash of it's [accounts tree root](block.md#header). 242 | 243 | | Element | Data type | Bytes | Description 244 | |--------------------|----------------------------|----------------|--- 245 | | block hash | Hash | 32 | Hash of block these accounts should be in 246 | | address count | uint16 | 2 | 247 | | addresses | [Address](block.md#header) | count * 20 | Addresses to be checked 248 | 249 | To get a response (`type = 43`) with following data: 250 | 251 | | Element | Data type | Bytes | Description 252 | |--------------------|----------------------------|----------------|--- 253 | | block hash | Hash | 32 | Block these accounts are in 254 | | has proof | uint8 | 1 | `1` means the proof is attached, otherwise `0` 255 | | proof count | uint16 | 2 | 256 | | proofs | [AccountsTreeNode](account-tree.md#account-tree-node) | count * variable size | Proofs for the requested accounts as nodes from the Merkle tree. 257 | 258 | To request a paricular chunk of of account tree nodes (`type = 44`) 259 | 260 | | Element | Data type | Bytes | Description 261 | |---------------------|----------------------------|----------------|--- 262 | | block hash | Hash | 32 | Hash of block these accounts should be in 263 | | start prefix length | uint8 | 1 | 264 | | start prefix | string | length | Defining the part of the tree where accounts are needed from. 265 | 266 | The node should respond a message `type = 45`: 267 | 268 | | Element | Data type | Bytes | Description 269 | |---------------------|----------------------------|--------|--- 270 | | block hash | Hash | 32 | Hash of block these accounts should be in 271 | | has chunks | uint8 | 1 | `1` means chunks are attached 272 | | node count | uint16 | 2 | 273 | | nodes | [AccountsTreeNode](account-tree.md#account-tree-node) | count * variable size | Account tree nodes from the requested part of the tree. 274 | | proof count | uint16 | 2 | 275 | | proofs | [AccountsTreeNode](account-tree.md#account-tree-node) | count * variable size | Account tree nodes as proof 276 | 277 | [//]: # (FIXME both nodes and proof are acount tree nodes?) 278 | 279 | ### Transactions Proof 280 | 281 | [//]: # (FIXME can not find a transaction message, only a transaction proof message) 282 | This message is used to send one transaction at a time (in serialized form) but can also contain an [`accountsProof`](/messages.md#accounts-proof-message). 283 | 284 | #### Request Transaction Proofs 285 | 286 | | Element | Data type | Bytes | Description | 287 | |-----------|-----------|-------|------------------------| 288 | | block hash | Hash | 32 | Hash of [block](block.md#block) the transactions belong to | 289 | | transactions count | uint16 | 2 | Count of transactoins being requested 290 | | transactions hash | [Transaction] | count * 20 | Hashes of transactions being requested 291 | 292 | #### Receive Transaction Proofs 293 | 294 | [//]: # (FIXME how do the tx hashes of the get relate to this response?) 295 | 296 | | Element | Data type | Bytes | Description | 297 | |-----------|-----------|-------|------------------------| 298 | | block hash | Hash | 32 | Hash of [block](block.md#block) the transactions belong to | 299 | | has proof | uint8 | 1 | `1` means the proof is attached, otherwise `0` 300 | | proof length | uint16 | 2 | If `has proof` was set | 301 | | proof | raw | proof length | The proof if `has proof` was set | 302 | 303 | ### Transaction Receipts 304 | 305 | Get transactions receipts via message `type = 49` 306 | 307 | | Element | Data type | Bytes | Description 308 | |-----------|----------------------------------|-------|--- 309 | | address | [Address](primitives.md#address) | 20 | Address of transaction 310 | 311 | Receive transactions receipts in a `type = 50` message: 312 | 313 | | Element | Data type | Bytes | Description | 314 | |---------------|-----------|-------|------------------------| 315 | | receipt count | uint16 | 2 | 316 | | receipts | 2x Hash | 64 | Transaction hash and block hash 317 | 318 | 319 | -------------------------------------------------------------------------------- /chapters/constants.md: -------------------------------------------------------------------------------- 1 | # Constants 2 | 3 | ## Policy 4 | 5 | ### Block Parameters 6 | 7 | | Parameters | Value | Description | 8 | |-------------------- |---------------|--------------------------------- | 9 | |`BLOCK_TIME` |60 |Targeted block time in seconds. | 10 | |`BLOCK_SIZE_MAX` |1e5 (100 kB) |Maximum block size in bytes. | 11 | |`DIFFICULTY_BLOCK_WINDOW` |120 |Number of blocks that are taken into account for calculating the next difficulty.| 12 | |`DIFFICULTY_MAX_ADJUSTMENT_FACTOR` |2 |Maximum factor about which the difficulty can be adjusted from one block to the next.| 13 | |`TRANSACTION_VALIDITY_WINDOW` |120 |Number of blocks a transaction is valid for, after it's `startValidity`. | 14 | 15 | ### Supply & Emission Parameters 16 | 17 | | Parameter | Value | Description | 18 | |-------------------------- |-------------- |------------------------------------------ | 19 | |`LUNAS_PER_COIN` |1e5 |Number of Lunas per Nimiq. Referred to in code as Satoshi. | 20 | |`TOTAL_SUPPLY` |21e14 |Targeted total supply in Lunas. This is the same amount that Bitcoin has. | 21 | |`INITIAL_SUPPLY` |252000000000000|Initial supply at the genesis block in Lunas. This describes the amount NIMs that are created from the fundraising and all other pre-allocated funds. | 22 | |`EMISSION_SPEED` |2^22 |The amount of Lunas that haven't been rewarded at that point in time are divided by this speed to calculate the reward (this ensures the smoothness of the reward emission process). | 23 | |`EMISSION_TAIL_START` |48692960 |First block using constant tail emission until total supply is reached. | 24 | |`EMISSION_TAIL_REWARD` |4000 |Constant tail emission per block in Lunas until total supply is reached. | 25 | |`M` |240 |NIPoPoW parameter `M`; The minimum length of a superchain. | 26 | |`K` |120 |NIPoPoW parameter `K`; The suffix size of the [chainproof](verify.md#chainproof). | 27 | |`DELTA` |0.1 |NIPoPoW Security parameter `DELTA`. | 28 | |`NUM_BLOCKS_VERIFICATION` |250 |Number of blocks the light client downloads to verify the [accounts tree](account-tree.md) construction. | 29 | |`NUM_SNAPSHOTS_MAX` |20 |Maximum number of snapshots that a node will keep (snapshots are used so that other nodes can synchronize to a consistent state even if a new block is added to the blockchain). | 30 | 31 | ## Network 32 | 33 | | Parameter | Value | Description | 34 | |------------ |------------------- |------------------------------------------ | 35 | |`PEER_COUNT_DESIRED` |6 |Number of peers a node aims to connect to. | 36 | |`PEER_COUNT_RELAY` |4 |Specifies to how many peers newly learned addresses are forwarded.| 37 | |`CONNECTING_COUNT_MAX` |2 |Maximum number of simultaneous outbound connection attempts. | 38 | |`SIGNAL_TTL_INITIAL` |3 |Considered to check validity of signals. | 39 | |`ADDRESS_UPDATE_DELAY` |1000 |Delay added before checking peer count and connecting to new peers. This allows RTC peer addresses to be sent to the peer in question. | 40 | |`CONNECT_BACKOFF_INITIAL` |1000 |Backoff for peer count check in seconds. | 41 | |`CONNECT_BACKOFF_MAX` |300000
(5 min) |Maximum Backoff time before a new backoff is triggered. | 42 | |`SIGNAL_MAX_AGE` |10 |Maximum age in seconds a signal needs to have to be valid. | 43 | |`PEER_COUNT_MAX` |15/50000 |Maximum amount of peers. Browsers are limited to 15, other platforms to 50k. | 44 | |`PEER_COUNT_PER_IP_WS_MAX` |1/25 |Maximum WebSocket connections from the same IP Address. Browsers are limited to 1, other platforms to 25.| 45 | |`PEER_COUNT_PER_IP_RTC_MAX`|2 |Maximum RTC connections for a peer's IP Address. | 46 | 47 | ### Network Utils 48 | 49 | | Parameter | Value | Description | 50 | |------------------- |------------------------- |---------------------------------------- | 51 | |`IP_BLACKLIST` |'0.0.0.0',
'255.255.255.255','::'|Blacklisted IP addresses will never be contacted.| 52 | |`IPv4_PRIVATE_NETWORK` |'10.0.0.0/8',
'172.16.0.0/12',
'192.168.0.0/16',
'100.64.0.0/10',
'169.254.0.0/16'|IP Address ranges considered to be within private networks and thus are not connected to.| 53 | 54 | ### Network Agent 55 | 56 | | Parameter | Value | Description | 57 | |------------------------------ |------------------ |----------------------------------------------------- | 58 | |`HANDSHAKE_TIMEOUT` |3000
(3 sec) |Timeout {ms} the node waits before droping a peer's connection. | 59 | |`PING_TIMEOUT` |10000
(10 sec) |Timeout {ms} the node waits for a peer to answer with a matching pong message during connectivity check.| 60 | |`CONNECTIVITY_CHECK_INTERVAL` |60000
(1 min) |Interval at which the node regularly checks connectivity. | 61 | |`ANNOUNCE_ADDR_INTERVAL` |300000
(5 min) |Interval at which the node regularly announces its address. | 62 | |`RELAY_THROTTLE` |120000
(2 min) |Time {ms} the node will wait to re send an address. | 63 | |`VERSION_ATTEMPTS_MAX` |10 |During handshake, maximum amount of version attempts per address the node will allow before droping the connection. A version attempt checks version, network address & blockchain head hash.| 64 | |`VERSION_RETRY_DELAY` |500 |Time {ms} the node waits before retrying a version attempt during handshake. | 65 | 66 | ### Peer Address 67 | 68 | #### Parameters 69 | 70 | | Parameter | Value | Description | 71 | |-------------------------- |----------------- |-------------------------------------------------- | 72 | |`MAX_AGE_WEBRTC` |60000
(1 min) |Age {ms} of a peer address to be sent back in a WebRTC address query. | 73 | |`MAX_AGE_DUMB` |4 |Age {ms} of a peer address to be sent back in a Dumb address query. | 74 | |`MAX_FAILED_ATTEMPTS_WS` |3 |Maximum failed attempts for peers connecting using WebSocket | 75 | |`MAX_FAILED_ATTEMPTS_RTC` |2 |Maximum failed attempts for peers connecting using WebRTC | 76 | |`MAX_TIMESTAMP_DRIFT` |600000
(10 min) |Maximum time allowed for a peer address's timestamp to drift into the future. | 77 | |`HOUSEKEEPING_INTERVAL` |60000
(1 min) |Interval {ms} at which regular housekeeping routines are executed. | 78 | |`DEFAULT_BAN_TIME` |600000
(10 min) |Duration {ms} a peer address remains banned. | 79 | |`INITIAL_FAILED_BACKOFF` |15000
(15 sec) |Initial backoff, {ms}, for failed connections. | 80 | |`MAX_FAILED_BACKOFF` |600000
(10 min) |Maximum backoff, {ms}, for failed connections. | 81 | 82 | #### States 83 | 84 | | State | Value | Description | 85 | |-------------------------- |---------- |----------------------------------------------------- | 86 | |`NEW` |1 |Initial state peer addresses are initialized with. | 87 | |`CONNECTING` |2 |State in which the node remains while connection to the peer address is being established | 88 | |`CONNECTED` |3 |Indicates a connection to a peer address has been established. | 89 | |`TRIED` |4 |State a peer address is set to when it is disconnected. | 90 | |`FAILED` |5 |Indicates a network connection to a peerAddress has failed. | 91 | |`BANNED` |6 |State of a peer address that have been banned. | 92 | 93 | 94 | ### Signal ID Serialized Size 95 | 96 | | Parameter | Value | Description | 97 | |-------------------------- |---------- |------------------------------------------- | 98 | |`SERIALIZED_SIZE` |16 |Size in bytes of the serialized signal. | 99 | 100 | 101 | ### Transaction Receipts Message Maximum Count 102 | 103 | | Parameter | Value | Description | 104 | |-------------------------- |---------- |-------------------------------------------- | 105 | |`RECEIPTS_MAX_COUNT` |500 |Maximum amount of transaction receipts in transaction receipts.| 106 | 107 | ### Signal Message Flags 108 | 109 | | Flag | Value | Description | 110 | |-------------------------- |---------- |----------------------------------------------------- | 111 | |`UNROUTABLE` |0x1 |Indicates a signal message is unroutable. | 112 | |`TTL_EXCEEDED` |0x2 |Indicates the TTL of a signal message has exceeded the maximum allowed.| 113 | 114 | 115 | ### Reject Message Code 116 | 117 | | Flag | Value | 118 | |-------------------------- |---------- | 119 | |`REJECT_MALFORMED` |0x01 | 120 | |`REJECT_INVALID` |0x10 | 121 | |`REJECT_OBSOLETE` |0x11 | 122 | |`REJECT_DOUBLE` |0x12 | 123 | |`REJECT_DUST` |0x41 | 124 | |`REJECT_INSUFFICIENT_FEE` |0x42 | 125 | 126 | ## Messages 127 | 128 | ### Message Magic 129 | 130 | | Type | Value | Description | 131 | |---------------- |---------- |----------------------------- | 132 | |`MAGIC` |0x42042042 |Special string that indicates the information sent should be interpreted as a message. | 133 | 134 | ### Message Types 135 | 136 | | Type | Value | Description | 137 | |-------------------------- |---------- |----------------------------------- | 138 | |`VERSION` |0 | [Version message.](/messages.md#version-message) | 139 | |`INV` |1 | [Inventory message](/messages.md#inventory-message) | 140 | |`GET_DATA` |2 | | 141 | |`GET_HEADER` |3 | | 142 | |`NOT_FOUND` |4 | | 143 | |`GET_BLOCKS` |5 | [Get Blocks message](/messages.md#get-blocks-message) | 144 | |`BLOCK` |6 | [Blocks message](/messages.md#block-message) | 145 | |`HEADER` |7 | [Header message](/messages.md#header-message) | 146 | |`TX` |8 | [Transaction message](/messages.md#transaction-message) | 147 | |`MEMPOOL` |9 | [Mempool message](/messages.md#mempool-message) | 148 | |`REJECT` |10 | [Reject message](/messages.md#reject-message) | 149 | |`SUBSCRIBE` |11 | [Subscribe message](/messages.md#subscribe-message) | 150 | |`ADDR` |20 | [Addresses Message](/messages.md#addresses-message) | 151 | |`GET_ADDR` |21 | [Get Addresses Message](/messages.md#get-addresses-message) | 152 | |`PING` |22 | [Ping message](/messages.md#ping-message) | 153 | |`PONG` |23 | [Pong message](/messages.md#pong-message) | 154 | |`SIGNAL` |30 | [Signal message](/messages.md#signal-message) | 155 | |`GET_CHAIN_PROOF` |40 | [Get Chain Proof message](/messages.md#get-chain-proof-message) | 156 | |`CHAIN_PROOF` |41 | [Chain proof message](#chain-proof-message) | 157 | |`GET_ACCOUNTS_PROOF` |42 | [Get accounts proof message](/messages.md#get-accounts-proof-message) | 158 | |`ACCOUNTS_PROOF` |43 | [Accounts proof message](/messages.md#accounts-proof-message) | 159 | |`GET_ACCOUNTS_TREE_CHUNK` |44 | [Gets accounts tree chunk message](/messages.md#get-accounts-tree-chunk-message) | 160 | |`ACCOUNTS_TREE_CHUNK` |45 | [Accounts tree chunk message](/messages.md#accounts-tree-chunk-message) | 161 | |`GET_TRANSACTIONS_PROOF` |47 | [Get transactions proof message](/messages.md#get-transactions-proof-message) | 162 | |`TRANSACTIONS_PROOF` |48 | [Transactions proof](/messages.md#transactions-proof-message) | 163 | |`GET_TRANSACTION_RECEIPTS` |49 | | 164 | |`TRANSACTION_RECEIPTS` |50 | [Transactions receipts](/messages.md#transactions-receipts-message) | 165 | 166 | ### Get Blocks Message Directions 167 | 168 | | Direction | Value | 169 | |-------------- |---------- | 170 | |`FORWARD` |0x1 | 171 | |`BACKWARD` |0x2 | 172 | 173 | ## Further Constants 174 | 175 | ### Protocol Types 176 | 177 | | Protocol | Value | 178 | |-------------- |---------- | 179 | |`DUMP` |0 | 180 | |`WS` |1 | 181 | |`RTC` |2 | 182 | 183 | ### Services Types 184 | 185 | | Protocol | Value | 186 | |-------------- |---------- | 187 | |`NONE` |0 | 188 | |`NANO` |1 | 189 | |`LIGHT` |2 | 190 | |`FULL` |4 | 191 | 192 | ### Alphabets 193 | 194 | | Alphabet | Value | 195 | |-------------- |---------------------------------- | 196 | |`RFC4648` |'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567='| 197 | |`RFC4648_HEX` |'0123456789ABCDEFGHIJKLMNOPQRSTUV='| 198 | |`NIMIQ` |'0123456789ABCDEFGHJKLMNPQRSTUVXY' | 199 | |`HEX_ALPHABET` |'0123456789abcdef' | 200 | 201 | ### WebRTC Data Channel 202 | 203 | | Parameter | Value | Description | 204 | |-------------------------- |------------------ |------------------------------------------- | 205 | |`CHUNK_SIZE_MAX` |16384
(16 Kb) |Maximum size {bits} allowed for a WebRTC message before being splited into chunks. | 206 | |`MESSAGE_SIZE_MAX` |10485760
(10Mb) |Maximum size {bits} allowed for a message WebRTC. | 207 | |`CHUNK_TIMEOUT` |5000
(5 sec) |Allowed timeout between chunks for a chunked WebRTC message. | 208 | |`CHUNK_BEGIN_MAGIC` |0xff |Special string that indicates the beginning chunk of a message splitted in chunks. | 209 | |`CHUNK_INNER_MAGIC` |0xfe |Special string that indicates the middle chunks of a message splitted in chunks. | 210 | |`CHUNK_END_MAGIC` |0xfd |Special string that indicates the end chunk of a message splitted in chunks. | 211 | 212 | ### WebSocket Connector 213 | 214 | | Parameter | Value | Description | 215 | |-------------------------- |---------- |---------------------------------------------------------- | 216 | |`CONNECT_TIMEOUT` |5000 |Timeout for WebSocket conections in Browsers. | 217 | 218 | 219 | ## Consensus Constants 220 | 221 | ### Full Consensus 222 | 223 | | Parameter | Value | Description | 224 | |-------------------------- |---------- |---------------------------------------------------------- | 225 | |`SYNC_THROTTLE` |1500 |Time {ms} for the node to wait for more peers to connect before start syncing. | 226 | 227 | ### Full Consensus Agent 228 | 229 | | Parameter | Value | Description | 230 | |-------------------------- |------------------ |---------------------------------------------- | 231 | |`SYNC_ATTEMPTS_MAX` |10 |Maximum number of blockchain sync retries before closing the connection. | 232 | |`GETBLOCKS_VECTORS_MAX` |500 |Maximum number of inventory vectors to sent in the response for `onGetBlocks`. | 233 | |`RESYNC_THROTTLE` |3000
(3 sec) |Time in millisecongs to wait before triggering a blockchain re-sync with the peer. | 234 | |`MEMPOOL_DELAY_MIN` |2000
(2 sec) |Minimum time {ms} to wait before triggering the initial mempool request. | 235 | |`MEMPOOL_DELAY_MAX` |20000
(20 sec) |Maximum time {ms} to wait before triggering the initial mempool request. | 236 | |`MEMPOOL_THROTTLE` |1000 |Time {ms} to wait between sending full inv vectors of transactions during Mempool request. | 237 | |`MEMPOOL_ENTRIES_MAX` |10 |Maximum number Number of allowed transaction to send. | 238 | 239 | 240 | ### Full Chain 241 | 242 | | Parameter | Value | Description | 243 | |------------------ |---------- |-------------------------------------- | 244 | |`ERR_ORPHAN` |-2 |Indicates the block's immediate predecessor is not part of the chain.| 245 | |`ERR_INVALID` |-1 |Indicates the block is not a full block (does not include block body) or matches with an intrinsic variant. (?) | 246 | |`OK_KNOWN` |0 |Indicates the node already knows this block. | 247 | |`OK_EXTENDED` |1 |Indicates the block extends the node's current main chain. | 248 | |`OK_REBRANCHED` |2 |Indicates the block fork has become the hardest chain and the node will rebranch to it. | 249 | |`OK_FORKED` |3 |Indicates a new fork was created. | 250 | 251 | 252 | 253 | ### Light Consensus Agent 254 | 255 | | Parameter | Value | Description | 256 | |-------------------------------------- |---------- |------------------ | 257 | |`CHAINPROOF_REQUEST_TIMEOUT` |20000 |Maximum time {ms} to wait for `chainProof` after sending out `getChainProof` before dropping the peer. | 258 | |`ACCOUNTS_TREE_CHUNK_REQUEST_TIMEOUT` |5000 |Maximum time {ms} to wait for accounts tree chunk after requesting it to a peer before dropping that peer.| 259 | |`SYNC_ATTEMPTS_MAX` |5 |Maximum number of blockchain sync retries before closing the connection. | 260 | |`GETBLOCKS_VECTORS_MAX` |500 |Maximum number of inventory vectors to sent in the response for `onGetBlocks`. | 261 | 262 | 263 | ### Light Consensus 264 | 265 | | Parameter | Value | Description | 266 | |-------------------------- |---------- |---------------------------------------------------------- | 267 | |`SYNC_THROTTLE` |1000 |Time {ms} for the node to wait for more peers to connect before start syncing. | 268 | 269 | ### Nano Mempool 270 | 271 | | Parameter | Value | Description | 272 | |-------------------------- |---------- |---------------------------------------------------------- | 273 | |`TRANSACTIONS_MAX_COUNT` |50000 |Maximum lenght of the mempool, oldest transactions are evicted from the mempool if it grows too large than this value. | 274 | |`TRANSACTIONS_EVICT_COUNT` |5000 |Amount of transaction to be evicted each time. | 275 | 276 | ### Nano Consensus Agent 277 | 278 | | Parameter | Value | Description | 279 | |------------------------------ |---------- |---------------------------------------------------------- | 280 | |`CHAINPROOF_REQUEST_TIMEOUT` |30000 |Maximum time {ms} to wait for `chainProof` after sending out `getChainProof` before dropping the peer. | 281 | |`ACCOUNTSPROOF_REQUEST_TIMEOUT`|5000 |Maximum time {ms} to wait for accounts proof after requesting it to a peer before dropping that peer. | 282 | |`TRANSACTIONSPROOF_REQUEST_TIMEOUT` |10000 |Maximum time {ms} to wait for transaction proof after requesting it to a peer before dropping that peer. | 283 | |`TRANSACTIONS_REQUEST_TIMEOUT` |15000 |Maximum time {ms} to wait for `transactions` after sending out `getTransactions` before dropping the peer.| 284 | 285 | ### Nano Consensus 286 | 287 | | Parameter | Value | Description | 288 | |-------------------------- |---------- |----------------------------------------- | 289 | |`SYNC_THROTTLE` |1000 |Time {ms} for the node to wait for more peers to connect before start syncing. | 290 | 291 | ### Nano Chain 292 | 293 | | Parameter | Value | Description | 294 | |------------------ |---------- |---------------------------------------------------- | 295 | |`ERR_ORPHAN` |-2 |Indicates the block's immediate predecessor is not part of the chain. | 296 | |`ERR_INVALID` |-1 |Idicates the block is not a full block (includes block body) or match with an intrinsic variant. (?) | 297 | |`OK_KNOWN` |0 |Indicates the node already knows this block.. | 298 | |`OK_EXTENDED` |1 |Indicates the block extends our current main chain. | 299 | |`OK_REBRANCHED` |2 |Indicates the block fork has become the hardest chain and node will rebranch to it. | 300 | |`OK_FORKED` |3 |Indicates a new fork was created. | 301 | --------------------------------------------------------------------------------