mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-23 03:59:31 +00:00
Books: document p2p protocol (#216)
* add admin message definitions * add block complete entry * add protocol messages * add most flows * add final flows * fix typos * move link to epee * review fixes
This commit is contained in:
parent
6820da9848
commit
88551c800c
15 changed files with 559 additions and 47 deletions
|
@ -23,5 +23,14 @@
|
||||||
- [Bulletproofs+](./consensus_rules/transactions/ring_ct/bulletproofs+.md)
|
- [Bulletproofs+](./consensus_rules/transactions/ring_ct/bulletproofs+.md)
|
||||||
- [P2P Network](./p2p_network.md)
|
- [P2P Network](./p2p_network.md)
|
||||||
- [Levin Protocol](./p2p_network/levin.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)
|
- [Pruning](./pruning.md)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# P2P Network
|
# 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.
|
||||||
|
|
116
books/protocol/src/p2p_network/common_types.md
Normal file
116
books/protocol/src/p2p_network/common_types.md
Normal file
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L185>
|
||||||
|
|
||||||
|
[^c-s-d]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L250>
|
||||||
|
|
||||||
|
[^network-addr]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/contrib/epee/include/net/net_utils_base.h#L320>
|
||||||
|
|
||||||
|
[^pl-entry-base]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L72>
|
||||||
|
|
||||||
|
[^tb-entry]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L121>
|
||||||
|
|
||||||
|
[^bc-entry]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L132>
|
|
@ -1,3 +0,0 @@
|
||||||
# Epee Binary Format
|
|
||||||
|
|
||||||
The epee binary format is described here: TODO
|
|
|
@ -10,16 +10,16 @@ of buckets that will be combined into a single message.
|
||||||
### Bucket Format
|
### Bucket Format
|
||||||
|
|
||||||
| Field | Type | Size (bytes) |
|
| Field | Type | Size (bytes) |
|
||||||
| ------ | ----------------------------- | ------------ |
|
|--------|-------------------------------|--------------|
|
||||||
| Header | [BucketHeader](#bucketheader) | 33 |
|
| Header | [BucketHeader](#bucketheader) | 33 |
|
||||||
| Body | bytes | dynamic |
|
| Body | bytes | dynamic |
|
||||||
|
|
||||||
### BucketHeader
|
### BucketHeader
|
||||||
|
|
||||||
Format:
|
Format[^header-format]:
|
||||||
|
|
||||||
| Field | Type | Size (bytes) |
|
| Field | Type | Size (bytes) |
|
||||||
| ---------------- | ------ | ------------ |
|
|------------------|--------|--------------|
|
||||||
| Signature | LE u64 | 8 |
|
| Signature | LE u64 | 8 |
|
||||||
| Size | LE u64 | 8 |
|
| Size | LE u64 | 8 |
|
||||||
| Expect Response | bool | 1 |
|
| 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.
|
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
|
#### Size
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ responses should be `1`.
|
||||||
|
|
||||||
#### Flags
|
#### 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 |
|
| Type | Bits set |
|
||||||
| -------------- | ----------- |
|
| -------------- | ----------- |
|
||||||
|
@ -66,3 +66,17 @@ This is a bit-flag field that determines what type of bucket this is:
|
||||||
#### Protocol Version
|
#### Protocol Version
|
||||||
|
|
||||||
This is a fixed value of 1.
|
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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/contrib/epee/include/net/levin_base.h#L62>
|
||||||
|
|
||||||
|
[^signature]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/contrib/epee/include/net/levin_base.h#L38>
|
||||||
|
|
||||||
|
[^flags]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/contrib/epee/include/net/levin_base.h#L79-L82>
|
||||||
|
|
102
books/protocol/src/p2p_network/levin/admin.md
Normal file
102
books/protocol/src/p2p_network/levin/admin.md
Normal file
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L213>
|
||||||
|
|
||||||
|
[^handshake-req]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L215>
|
||||||
|
|
||||||
|
[^handshake-res]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L227>
|
||||||
|
|
||||||
|
[^timed-sync-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L249>
|
||||||
|
|
||||||
|
[^timed-sync-req]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L251>
|
||||||
|
|
||||||
|
[^timed-sync-res]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L260>
|
||||||
|
|
||||||
|
[^ping-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L284>
|
||||||
|
|
||||||
|
[^ping-req]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L288>
|
||||||
|
|
||||||
|
[^ping-res]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L297>
|
||||||
|
|
||||||
|
[^support-flags]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L316>
|
||||||
|
|
||||||
|
[^sf-req]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L318>
|
||||||
|
|
||||||
|
[^sf-res]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/p2p_protocol_defs.h#L325>
|
121
books/protocol/src/p2p_network/levin/protocol.md
Normal file
121
books/protocol/src/p2p_network/levin/protocol.md
Normal file
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L174>
|
||||||
|
|
||||||
|
[^notify-new-transactions-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L194>
|
||||||
|
|
||||||
|
[^notify-request-get-objects-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L215>
|
||||||
|
|
||||||
|
[^notify-response-get-objects-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L232>
|
||||||
|
|
||||||
|
[^notify-request-chain-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L274>
|
||||||
|
|
||||||
|
[^notify-response-chain-entry-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L291>
|
||||||
|
|
||||||
|
[^notify-new-fluffy-block-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L324>
|
||||||
|
|
||||||
|
[^notify-request-fluffy-missing-tx-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L344>
|
||||||
|
|
||||||
|
[^notify-get-txpool-compliment-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_defs.h#L366>
|
19
books/protocol/src/p2p_network/message_flows.md
Normal file
19
books/protocol/src/p2p_network/message_flows.md
Normal file
|
@ -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)
|
||||||
|
|
28
books/protocol/src/p2p_network/message_flows/chain_sync.md
Normal file
28
books/protocol/src/p2p_network/message_flows/chain_sync.md
Normal file
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_handler.inl#L2568>
|
||||||
|
|
||||||
|
[^res-max-blocks]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_handler.inl#L2599>
|
19
books/protocol/src/p2p_network/message_flows/get_blocks.md
Normal file
19
books/protocol/src/p2p_network/message_flows/get_blocks.md
Normal file
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_handler.inl#L1089>
|
51
books/protocol/src/p2p_network/message_flows/handshake.md
Normal file
51
books/protocol/src/p2p_network/message_flows/handshake.md
Normal file
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2510>
|
||||||
|
|
||||||
|
[^req-incoming-only]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2519>
|
||||||
|
|
||||||
|
[^double-handshake]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2527>
|
||||||
|
|
||||||
|
[^same-peer-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2539>
|
||||||
|
|
||||||
|
[^core-sync-data-checks]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_handler.inl#L341>
|
||||||
|
|
||||||
|
[^res-network-id]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L1164>
|
||||||
|
|
||||||
|
[^max-peer-list-res]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2170>
|
||||||
|
|
||||||
|
[^peers-all-in-same-zone]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2182>
|
||||||
|
|
||||||
|
[^same-peer-id-res]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L1195>
|
29
books/protocol/src/p2p_network/message_flows/new_block.md
Normal file
29
books/protocol/src/p2p_network/message_flows/new_block.md
Normal file
|
@ -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
|
||||||
|
```
|
||||||
|
|
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/cryptonote_protocol/cryptonote_protocol_handler.inl#L991>
|
28
books/protocol/src/p2p_network/message_flows/timed_sync.md
Normal file
28
books/protocol/src/p2p_network/message_flows/timed_sync.md
Normal file
|
@ -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]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2464>
|
||||||
|
|
||||||
|
[^max-peer-list-res]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2170>
|
||||||
|
|
||||||
|
[^peers-all-in-same-zone]: <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/p2p/net_node.inl#L2182>
|
||||||
|
|
|
@ -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) | |
|
|
||||||
| | | |
|
|
Loading…
Reference in a new issue