diff --git a/books/protocol/src/SUMMARY.md b/books/protocol/src/SUMMARY.md index 1a4b1f0e..682e0e74 100644 --- a/books/protocol/src/SUMMARY.md +++ b/books/protocol/src/SUMMARY.md @@ -23,5 +23,14 @@ - [Bulletproofs+](./consensus_rules/transactions/ring_ct/bulletproofs+.md) - [P2P Network](./p2p_network.md) - [Levin Protocol](./p2p_network/levin.md) - - [P2P Messages](./p2p_network/messages.md) + - [Admin Messages](./p2p_network/levin/admin.md) + - [Protocol Messages](./p2p_network/levin/protocol.md) + - [Common Types](./p2p_network/common_types.md) + - [Message Flows](./p2p_network/message_flows.md) + - [Handshake](./p2p_network/message_flows/handshake.md) + - [Timed Sync](./p2p_network/message_flows/timed_sync.md) + - [New Block](./p2p_network/message_flows/new_block.md) + - [New Transactions](./p2p_network/message_flows/new_transactions.md) + - [Chain Sync](./p2p_network/message_flows/chain_sync.md) + - [Get Blocks](./p2p_network/message_flows/get_blocks.md) - [Pruning](./pruning.md) diff --git a/books/protocol/src/p2p_network.md b/books/protocol/src/p2p_network.md index e0d9a799..89bd1be9 100644 --- a/books/protocol/src/p2p_network.md +++ b/books/protocol/src/p2p_network.md @@ -1,3 +1,3 @@ # P2P Network -This chapter contains descriptions of Monero's peer to peer network, including messages, flows, expected responses, etc. +This chapter contains descriptions of Monero's peer to peer network, including messages, flows, etc. diff --git a/books/protocol/src/p2p_network/common_types.md b/books/protocol/src/p2p_network/common_types.md new file mode 100644 index 00000000..0bf29cb2 --- /dev/null +++ b/books/protocol/src/p2p_network/common_types.md @@ -0,0 +1,116 @@ +# Common P2P Types + +This chapter contains definitions of types used in multiple P2P messages. + +### Support Flags + +Support flags specify any protocol extensions the peer supports, currently only the first bit is used: + +`FLUFFY_BLOCKS = 1` - for if the peer supports receiving fluffy blocks. + +### Basic Node Data [^b-n-d] { #basic-node-data } + +| Fields | Type | Description | +|------------------------|---------------------------------------|-------------------------------------------------------------------------------------------| +| `network_id` | A UUID (epee string) | A fixed constant value for a specific network (mainnet,testnet,stagenet) | +| `my_port` | u32 | The peer's inbound port, if the peer does not want inbound connections this should be `0` | +| `rpc_port` | u16 | The peer's RPC port, if the peer does not want inbound connections this should be `0` | +| `rpc_credits_per_hash` | u32 | States how much it costs to use this node in credits per hashes, `0` being free | +| `peer_id` | u64 | A fixed ID for the node, set to 1 for anonymity networks | +| `support_flags` | [support flags](#support-flags) (u32) | Specifies any protocol extensions the peer supports | + +### Core Sync Data [^c-s-d] { #core-sync-data } + +| Fields | Type | Description | +|-------------------------------|------------------------|---------------------------------------------------------------| +| `current_height` | u64 | The current chain height | +| `cumulative_difficulty` | u64 | The low 64 bits of the cumulative difficulty | +| `cumulative_difficulty_top64` | u64 | The high 64 bits of the cumulative difficulty | +| `top_id` | [u8; 32] (epee string) | The hash of the top block | +| `top_version` | u8 | The hardfork version of the top block | +| `pruning_seed` | u32 | THe pruning seed of the node, `0` if the node does no pruning | + +### Network Address [^network-addr] { #network-address } + +Network addresses are serialized differently than other types, the fields needed depend on the `type` field: + +| Fields | Type | Description | +| ------ | --------------------------------------- | ---------------- | +| `type` | u8 | The address type | +| `addr` | An object whose fields depend on `type` | The address | + +#### IPv4 + +`type = 1` + +| Fields | Type | Description | +| -------- | ---- | ---------------- | +| `m_ip` | u32 | The IPv4 address | +| `m_port` | u16 | The port | + + +#### IPv6 + +`type = 2` + +| Fields | Type | Description | +| -------- | ---------------------- | ---------------- | +| `addr` | [u8; 16] (epee string) | The IPv6 address | +| `m_port` | u16 | The port | + +#### Tor + +TODO: + +#### I2p + +TODO: + +### Peer List Entry Base [^pl-entry-base] { #peer-list-entry-base } + +| Fields | Type | Description | +|------------------------|-------------------------------------|-------------------------------------------------------------------------------------------------------| +| `adr` | [Network Address](#network-address) | The address of the peer | +| `id` | u64 | The random, self assigned, ID of this node | +| `last_seen` | i64 | A field marking when this peer was last seen, although this is zeroed before sending over the network | +| `pruning_seed` | u32 | This peer's pruning seed, `0` if the peer does no pruning | +| `rpc_port` | u16 | This node's RPC port, `0` if this peer has no public RPC port. | +| `rpc_credits_per_hash` | u32 | States how much it costs to use this node in credits per hashes, `0` being free | + +### Tx Blob Entry [^tb-entry] { #tx-blob-entry } + +| Fields | Type | Description | +| --------------- | ---------------------- | --------------------------------------- | +| `blob` | bytes (epee string) | The pruned tx blob | +| `prunable_hash` | [u8; 32] (epee string) | The hash of the prunable part of the tx | + +### Block Complete Entry [^bc-entry] { #block-complete-entry } + +| Fields | Type | Description | +|----------------|---------------------|-----------------------------------------------------------| +| `pruned` | bool | True if the block is pruned, false otherwise | +| `block` | bytes (epee string) | The block blob | +| `block_weight` | u64 | The block's weight | +| `txs` | depends on `pruned` | The transaction blobs, the exact type depends on `pruned` | + +If `pruned` is true: + +`txs` is a vector of [Tx Blob Entry](#tx-blob-entry) + +If `pruned` is false: + +`txs` is a vector of bytes. + +--- + +[^b-n-d]: + +[^c-s-d]: + +[^network-addr]: + +[^pl-entry-base]: + +[^tb-entry]: + +[^bc-entry]: diff --git a/books/protocol/src/p2p_network/epee.md b/books/protocol/src/p2p_network/epee.md deleted file mode 100644 index 2f8161d8..00000000 --- a/books/protocol/src/p2p_network/epee.md +++ /dev/null @@ -1,3 +0,0 @@ -# Epee Binary Format - -The epee binary format is described here: TODO diff --git a/books/protocol/src/p2p_network/levin.md b/books/protocol/src/p2p_network/levin.md index de746606..ec92f7d7 100644 --- a/books/protocol/src/p2p_network/levin.md +++ b/books/protocol/src/p2p_network/levin.md @@ -10,16 +10,16 @@ of buckets that will be combined into a single message. ### Bucket Format | Field | Type | Size (bytes) | -| ------ | ----------------------------- | ------------ | +|--------|-------------------------------|--------------| | Header | [BucketHeader](#bucketheader) | 33 | | Body | bytes | dynamic | ### BucketHeader -Format: +Format[^header-format]: | Field | Type | Size (bytes) | -| ---------------- | ------ | ------------ | +|------------------|--------|--------------| | Signature | LE u64 | 8 | | Size | LE u64 | 8 | | Expect Response | bool | 1 | @@ -32,7 +32,7 @@ Format: The signature field is fixed for every bucket and is used to tell apart peers running different protocols. -Its value should be `0x0101010101012101` +Its value should be `0x0101010101012101` [^signature] #### Size @@ -53,7 +53,7 @@ responses should be `1`. #### Flags -This is a bit-flag field that determines what type of bucket this is: +This is a bit-flag field that determines what type of bucket this is[^flags]: | Type | Bits set | | -------------- | ----------- | @@ -66,3 +66,17 @@ This is a bit-flag field that determines what type of bucket this is: #### Protocol Version This is a fixed value of 1. + +## Bucket Body + +All bucket bodies are serialized in the epee binary format which is described here: https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/docs/PORTABLE_STORAGE.md + +Exact message types are described in the next chapters. + +--- + +[^header-format]: + +[^signature]: + +[^flags]: diff --git a/books/protocol/src/p2p_network/levin/admin.md b/books/protocol/src/p2p_network/levin/admin.md new file mode 100644 index 00000000..6f2b7160 --- /dev/null +++ b/books/protocol/src/p2p_network/levin/admin.md @@ -0,0 +1,102 @@ +# Admin Messages + +This chapter describes admin messages, and documents the current admin messages. Admin messages are a subset of messages that handle connection +creation, making sure connections are still alive, and sharing peer lists. + +## Levin + +All admin messages are in the request/response levin format. This means requests will set the [expect response bit](./levin.md#expect-response) and +responses will set the return code to [`1`](./levin.md#return-code). + +## Messages + +### Handshake + +ID: `1001`[^handshake-id] + +#### Request [^handshake-req] { #handshake-request } + +| Fields | Type | Description | +|----------------|-------------------------------------------------------|--------------------------------------| +| `node_data` | [basic node data](../common_types.md#basic-node-data) | Static information about our node | +| `payload_data` | [core sync data](../common_types.md#core-sync-data) | Information on the node's sync state | + +#### Response [^handshake-res] { #handshake-response } + +| Fields | Type | Description | +|----------------------|--------------------------------------------------------------------------|-----------------------------------------| +| `node_data` | [basic node data](../common_types.md#basic-node-data) | Static information about our node | +| `payload_data` | [core sync data](../common_types.md#core-sync-data) | Information on the node's sync state | +| `local_peerlist_new` | A Vec of [peer list entry base](../common_types.md#peer-list-entry-base) | A list of peers in the node's peer list | + +### Timed Sync + +ID: `1002`[^timed-sync-id] + +#### Request [^timed-sync-req] { #timed-sync-request } + +| Fields | Type | Description | +| -------------- | --------------------------------------------------- | ------------------------------------ | +| `payload_data` | [core sync data](../common_types.md#core-sync-data) | Information on the node's sync state | + +#### Response [^timed-sync-res] { #timed-sync-response } + +| Fields | Type | Description | +|----------------------|--------------------------------------------------------------------------|-----------------------------------------| +| `payload_data` | [core sync data](../common_types.md#core-sync-data) | Information on the node's sync state | +| `local_peerlist_new` | A Vec of [peer list entry base](../common_types.md#peer-list-entry-base) | A list of peers in the node's peer list | + +### Ping + +ID: `1003`[^ping-id] + +#### Request [^ping-req] { #ping-request } + +No data is serialized for a ping request. + +#### Response [^ping-res] { #ping-response } + +| Fields | Type | Description | +| --------- | ------ | --------------------------------- | +| `status` | string | Will be `OK` for successful pings | +| `peer_id` | u64 | The self assigned id of the peer | + +### Request Support Flags + +ID: `1007`[^support-flags] + +#### Request [^sf-req] { #support-flags-request } + +No data is serialized for a ping request. + +#### Response [^sf-res] { #support-flags-response } + +| Fields | Type | Description | +| --------------- | ---- | ------------------------------------------------------------ | +| `support_flags` | u32 | The peer's [support flags](../common_types.md#support-flags) | + +--- + +[^handshake-id]: + +[^handshake-req]: + +[^handshake-res]: + +[^timed-sync-id]: + +[^timed-sync-req]: + +[^timed-sync-res]: + +[^ping-id]: + +[^ping-req]: + +[^ping-res]: + +[^support-flags]: + +[^sf-req]: + +[^sf-res]: diff --git a/books/protocol/src/p2p_network/levin/protocol.md b/books/protocol/src/p2p_network/levin/protocol.md new file mode 100644 index 00000000..a52ca1da --- /dev/null +++ b/books/protocol/src/p2p_network/levin/protocol.md @@ -0,0 +1,121 @@ +# Protocol Messages + +This chapter describes protocol messages, and documents the current protocol messages. Protocol messages are used to share protocol data +like blocks and transactions. + +## Levin + +All protocol messages are in the notification levin format. Although there are some messages that fall under requests/responses, levin will treat them as notifications. + +All admin messages are in the request/response levin format. This means requests will set the [expect response bit](../levin.md#expect-response) and +responses will set the return code to [`1`](../levin.md#return-code). + +## Messages + +### Notify New Block + +ID: `2001`[^notify-new-block-id] + +| Fields | Type | Description | +| --------------------------- | --------------------------------------------------------------- | ------------------------ | +| `b` | [Block Complete Entry](../common_types.md#block-complete-entry) | The full block | +| `current_blockchain_height` | u64 | The current chain height | + +### Notify New Transactions + +ID: `2002`[^notify-new-transactions-id] + +| Fields | Type | Description | +| ------------------- | ----------------- | ------------------------------------------------------ | +| `txs` | A vector of bytes | The txs | +| `_` | Bytes | Padding to prevent traffic volume analysis | +| `dandelionpp_fluff` | bool | True if this message contains fluff txs, false if stem | + +### Notify Request Get Objects + +ID: `2003`[^notify-request-get-objects-id] + +| Fields | Type | Description | +|----------|----------------------------------------------------|------------------------------------------------------------| +| `blocks` | A vector of [u8; 32] serialized as a single string | The block IDs requested | +| `prune` | bool | True if we want the blocks in pruned form, false otherwise | + +### Notify Response Get Objects + +ID: `2004`[^notify-response-get-objects-id] + +| Fields | Type | Description | +| --------------------------- | --------------------------------------------------------------------------- | ------------------------------ | +| `blocks` | A vector of [Block Complete Entry](../common_types.md#block-complete-entry) | The blocks that were requested | +| `missed_ids` | A vector of [u8; 32] serialized as a single string | IDs of any missed blocks | +| `current_blockchain_height` | u64 | The current blockchain height | + +### Notify Request Chain + +ID: `2006`[^notify-request-chain-id] + +| Fields | Type | Description | +|-------------|----------------------------------------------------|-------------------------------------------------------------------------------------------------------| +| `block_ids` | A vector of [u8; 32] serialized as a single string | A list of block IDs in reverse chronological order, the top and genesis block will always be included | +| `prune` | bool | True if we want the response to contain pruned blocks, false otherwise | + +### Notify Response Chain Entry + +ID: `2007`[^notify-response-chain-entry-id] + +| Fields | Type | Description | +|-------------------------------|----------------------------------------------------|------------------------------------------------| +| `start_height` | u64 | The start height of the entry | +| `total_height` | u64 | The height of the peer's blockchain | +| `cumulative_difficulty` | u64 | The low 64 bits of the cumulative difficulty | +| `cumulative_difficulty_top64` | u64 | The high 64 bits of the cumulative difficulty | +| `m_block_ids` | A vector of [u8; 32] serialized as a single string | The block IDs in this entry | +| `m_block_weights` | A vector of u64 serialized as a single string | The block weights | +| `first_block` | bytes (epee string) | The header of the first block in `m_block_ids` | + +### Notify New Fluffy Block + +ID: `2008`[^notify-new-fluffy-block-id] + +| Fields | Type | Description | +| --------------------------- | --------------------------------------------------------------- | ------------------------------------- | +| `b` | [Block Complete Entry](../common_types.md#block-complete-entry) | The block, may or may not contain txs | +| `current_blockchain_height` | u64 | The current chain height | + +### Notify Request Fluffy Missing Tx + +ID: `2009`[^notify-request-fluffy-missing-tx-id] + +| Fields | Type | Description | +|-----------------------------|-----------------------------------------------|--------------------------------------------| +| `block_hash` | [u8; 32] serialized as a string | The block hash txs are needed from | +| `current_blockchain_height` | u64 | The current chain height | +| `missing_tx_indices` | A vector of u64 serialized as a single string | The indices of the needed txs in the block | + +### Notify Get Txpool Compliment + +ID: `2010`[^notify-get-txpool-compliment-id] + +| Fields | Type | Description | +| -------- | ------------------------------------------- | ---------------------- | +| `hashes` | A vector of [u8; 32] serialized as a string | The current txpool txs | + +--- + +[^notify-new-block-id]: + +[^notify-new-transactions-id]: + +[^notify-request-get-objects-id]: + +[^notify-response-get-objects-id]: + +[^notify-request-chain-id]: + +[^notify-response-chain-entry-id]: + +[^notify-new-fluffy-block-id]: + +[^notify-request-fluffy-missing-tx-id]: + +[^notify-get-txpool-compliment-id]: diff --git a/books/protocol/src/p2p_network/message_flows.md b/books/protocol/src/p2p_network/message_flows.md new file mode 100644 index 00000000..8f1004ce --- /dev/null +++ b/books/protocol/src/p2p_network/message_flows.md @@ -0,0 +1,19 @@ +# Message Flows + +Message flows are sets of messages sent between peers, that achieve an identifiable goal, like a handshake. +Some message flows are complex, involving many message types, whereas others are simple, requiring only 1. + +The message flows here are not every possible request/response. + +When documenting checks on the messages, not all checks are documented, only the ones notable. This should help +to reduce the maintenance burden. + +## Different Flows + +- [Handshakes](./message_flows/handshake.md) +- [Timed Sync](./message_flows/timed_sync.md) +- [New Block](./message_flows/new_block.md) +- [New Transactions](./message_flows/new_transactions.md) +- [Chain Sync](./message_flows/chain_sync.md) +- [Get Blocks](./message_flows/get_blocks.md) + diff --git a/books/protocol/src/p2p_network/message_flows/chain_sync.md b/books/protocol/src/p2p_network/message_flows/chain_sync.md new file mode 100644 index 00000000..1b661324 --- /dev/null +++ b/books/protocol/src/p2p_network/message_flows/chain_sync.md @@ -0,0 +1,28 @@ +# Chain Sync + +Chain sync is the first step in syncing a peer's blockchain, it allows a peers to find the split point in their chains and for the peer +to learn about the missing block IDs. + +## Flow + +The first step is for the initiating peer is to get its compact chain history. The compact chain history must be in reverse chronological +order, with the first block being the top block and the last the genesis, if the only block is the genesis then that only needs to be included +once. The blocks in the middle are not enforced to be at certain locations, however `monerod` will use the top 11 blocks and will then go power +of 2 offsets from then on, i.e. `{13, 17, 25, ...}` + +Then, with the compact history, the initiating peer will send a [request chain](../levin/protocol.md#notify-request-chain) message, the receiving +peer will then find the split point and return a [response chain entry](../levin/protocol.md#notify-response-chain-entry) message. + +The `response chain entry` will contain a list of block IDs with the first being a common ancestor and the rest being the next blocks that come after +that block in the peer's chain. + +### Response Checks + +- There must be an overlapping block.[^res-overlapping-block] +- The amount of returned block IDs must be less than `25,000`.[^res-max-blocks] + +--- + +[^res-overlapping-block]: + +[^res-max-blocks]: \ No newline at end of file diff --git a/books/protocol/src/p2p_network/message_flows/get_blocks.md b/books/protocol/src/p2p_network/message_flows/get_blocks.md new file mode 100644 index 00000000..eacca7f2 --- /dev/null +++ b/books/protocol/src/p2p_network/message_flows/get_blocks.md @@ -0,0 +1,19 @@ +# Get Blocks + +The get block flow is used to download batches of blocks from a peer. + +## Flow + +The initiating peer needs a list of block IDs that the receiving peer has, this can be done with +the [chain sync flow](./chain_sync.md). + +With a list a block IDs the initiating peer will send a [get objects request](../levin/protocol.md#notify-request-get-objects) message, the receiving +peer will then respond with [get objects response](../levin/protocol.md#notify-response-get-objects). + +### Request Checks + +- The amount of blocks must be less than `100`.[^max-block-requests] + +--- + +[^max-block-requests]: diff --git a/books/protocol/src/p2p_network/message_flows/handshake.md b/books/protocol/src/p2p_network/message_flows/handshake.md new file mode 100644 index 00000000..2a4abe13 --- /dev/null +++ b/books/protocol/src/p2p_network/message_flows/handshake.md @@ -0,0 +1,51 @@ +# Handshakes + +Handshakes are used to establish connections to peers. + +## Flow + +The default handshake flow is made up of the connecting peer sending a [handshake request](../levin/admin.md#handshake-request) and the +receiving peer responding with a [handshake response](../levin/admin.md#handshake-response). + +It should be noted that not all other messages are banned during handshakes, for example, support flag requests and even some protocol +requests can be sent. + +### Handshake Request Checks + +The receiving peer will check: + +- The `network_id` is network ID expected.[^network-id] +- The connection is an incoming connection.[^req-incoming-only] +- The peer hasn't already completed a handshake.[^double-handshake] +- If the network zone is public, then the `peer_id` must not be the same as ours.[^same-peer-id] +- The core sync data is not malformed.[^core-sync-data-checks] + +### Handshake Response Checks + +The initiating peer will check: + +- The `network_id` is network ID expected.[^res-network-id] +- The number of peers in the peer list is less than `250`.[^max-peer-list-res] +- All peers in the peer list are in the same zone.[^peers-all-in-same-zone] +- The core sync data is not malformed.[^core-sync-data-checks] +- If the network zone is public, then the `peer_id` must not be the same as ours.[^same-peer-id-res] + +--- + +[^network-id]: + +[^req-incoming-only]: + +[^double-handshake]: + +[^same-peer-id]: + +[^core-sync-data-checks]: + +[^res-network-id]: + +[^max-peer-list-res]: + +[^peers-all-in-same-zone]: + +[^same-peer-id-res]: diff --git a/books/protocol/src/p2p_network/message_flows/new_block.md b/books/protocol/src/p2p_network/message_flows/new_block.md new file mode 100644 index 00000000..452aa44f --- /dev/null +++ b/books/protocol/src/p2p_network/message_flows/new_block.md @@ -0,0 +1,29 @@ +# New Block + +This is used whenever a new block is to be sent to peers. Only the fluffy block flow is described here, as the other method is deprecated. + +## Flow + +First the peer with the new block will send a [new fluffy block](../levin/protocol.md#notify-new-fluffy-block) notification, if the receiving +peer has all the txs in the block then the flow is complete. Otherwise the peer sends a [fluffy missing transactions request](../levin/protocol.md#notify-request-fluffy-missing-tx) +to the first peer, the first peer will then respond with again a [new fluffy block](../levin/protocol.md#notify-new-fluffy-block) notification but +with the transactions requested. + +```bob + + ,-----------. ,----------. + | Initiator | | Receiver | + `-----+-----' `-----+----' + | New Fluffy Block | + |-------------------->| + | | + | Missing Txs Request | + |<- - - - - - - - - - | + | | + | New Fluffy Block | + | - - - - - - - - - ->| + | | + | | + V v +``` + diff --git a/books/protocol/src/p2p_network/message_flows/new_transactions.md b/books/protocol/src/p2p_network/message_flows/new_transactions.md new file mode 100644 index 00000000..2a90a3f4 --- /dev/null +++ b/books/protocol/src/p2p_network/message_flows/new_transactions.md @@ -0,0 +1,16 @@ +# New Transactions + +Monero uses the dandelion++ protocol to pass transactions around the network, this flow just describes the actual tx passing between nodes part. + +## Flow + +This flow is pretty simple, the txs are put into a [new transactions](../levin/protocol.md#notify-new-transactions) notification and sent to +peers. + +Hopefully in the future [this is changed](https://github.com/monero-project/monero/issues/9334). + +There must be no duplicate txs in the notification.[^duplicate-txs] + +--- + +[^duplicate-txs]: \ No newline at end of file diff --git a/books/protocol/src/p2p_network/message_flows/timed_sync.md b/books/protocol/src/p2p_network/message_flows/timed_sync.md new file mode 100644 index 00000000..4d258d72 --- /dev/null +++ b/books/protocol/src/p2p_network/message_flows/timed_sync.md @@ -0,0 +1,28 @@ +# Timed Syncs + +A timed sync request is sent every 60 seconds to make sure the connection is still live. + +## Flow + +First the timed sync initiator will send a [timed sync request](../levin/admin.md#timed-sync-request), the receiver will then +respond with a [timed sync response](../levin/admin.md#timed-sync-response) + +### Timed Sync Request Checks + +- The core sync data is not malformed.[^core-sync-data-checks] + + +### Timed Sync Response Checks + +- The core sync data is not malformed.[^core-sync-data-checks] +- The number of peers in the peer list is less than `250`.[^max-peer-list-res] +- All peers in the peer list are in the same zone.[^peers-all-in-same-zone] + +--- + +[^core-sync-data-checks]: + +[^max-peer-list-res]: + +[^peers-all-in-same-zone]: + diff --git a/books/protocol/src/p2p_network/messages.md b/books/protocol/src/p2p_network/messages.md deleted file mode 100644 index c3f18287..00000000 --- a/books/protocol/src/p2p_network/messages.md +++ /dev/null @@ -1,37 +0,0 @@ -# P2P Messages - -This chapter contains every P2P message. - -## Index - -## Types - -Types used in multiple P2P messages. - -### Support Flags - -Support flags specify any protocol extensions the peer supports, currently only the first bit is used: - -`FLUFFY_BLOCKS = 1` - for if the peer supports receiving fluffy blocks. - -### Basic Node Data - -| Fields | Type (Epee Type) | Description | -| ---------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- | -| `network_id` | A UUID (String) | A fixed constant value for a specific network (mainnet,testnet,stagenet) | -| `my_port` | u32 (u32) | The peer's inbound port, if the peer does not want inbound connections this should be `0` | -| `rpc_port` | u16 (u16) | The peer's RPC port, if the peer does not want inbound connections this should be `0` | -| `rpc_credits_per_hash` | u32 (u32) | TODO | -| `peer_id` | u64 (u64) | A fixed ID for the node, set to 1 for anonymity networks | -| `support_flags` | [support flags](#support-flags) (u32) | Specifies any protocol extensions the peer supports | - -## Messages - -### Handshake Requests - -levin command: 1001 - -| Fields | Type (Epee Type) | Description | -| ----------- | -------------------------------------------- | ----------- | -| `node_data` | [basic node data](#basic-node-data) (Object) | | -| | | |