Back to Grin

P2P Protocol

doc/p2p/p2p_protocol.md

5.4.020.7 KB
Original Source

P2P Protocol

P2P Messages

WARNING: This document is still in progress and has not yet been reviewed by any of the core Grin developers.

  • All fields are serialized in Big-Endian byte order unless otherwise specified.
  • Variable-length strings (VAR_STR) are encoded in UTF8, and are preceded with a uint64 indicating their lengths.

Message Types

There are currently 19 different types of P2P Messages:

IdMessage TypeDescription
0ErrorSent when an issue is found during communication with a peer. Usually followed by closing the connection.
1HandFirst part of a handshake, sender advertises its version and characteristics.
2ShakeSecond part of a handshake, receiver of the first part replies with its own version and characteristics.
3PingSent to confirm that the connection is still valid, and used to advertise the node's total_difficulty to confirm whether sync is needed.
4PongThe response to a ping message.
5GetPeerAddrsUsed to request addresses of new peers to connect to.
6PeerAddrsPeer addresses sent in response to a GetPeerAddrs message.
7GetHeadersUsed to request block headers from a peer.
8HeaderA single block header received from a peer.
9HeadersMultiple block headers received from a peer in response to a GetHeaders message.
10GetBlockUsed to request a block from a peer.
11BlockA single block received from a peer.
12GetCompactBlockUsed to request a compact block from a peer.
13CompactBlockA single compact block received from a peer.
14StemTransactionA stem transaction received from a peer.
15TransactionA transaction received from a peer.
16TxHashSetRequestUsed to request the transaction hashset from a peer.
17TxHashSetArchiveThe transaction hashset in response to the TxHashSetRequest message.
18BanReasonContains the reason your node was banned by a peer.

Message structure

All P2P messages follow a generic message structure as follows.

SizeNameData TypeDescription/Comments
2Magicuint8[2]Magic number used to identify Grin packets. Always hard-coded as {0x1E, 0xC5}.
1TypeMessageTypeEnumIdentifier of the packet content.
8Lengthuint64The total length of the message. This will not include the header size (11 bytes).
?Payloaduint8[]The actual data.

TODO: Provide example

Common structures

SocketAddress
SizeNameData TypeDescription/Comments
1IPAddressFamilyuint8Identifies the IP address family. 0 = IPv4, 1 = IPv6.
4/16IPAddressuint8[4]/uint16[8]The IP address. 4 octets for IPv4 or 8 hexadecets for IPv6.
2Portuint16The TCP/IP port number.
CapabilitiesMask
ValueNameDescription
0x00UnknownWe don't know (yet) what the peer can do.
0x01Full HistoryFull archival node, has the whole history without any pruning.
0x02TxHashSet HistoryCan provide block headers and the TxHashSet for some recent-enough height.
0x04Peer ListCan provide a list of healthy peers.
0x06Fast Sync NodeBoth "TxHashSet History" and "Peer List"
0x07Full Node"Full History", "TxHashSet History", and "Peer List"
TransactionBody
SizeNameData TypeDescription/Comments
?InputsTxInput[]List of inputs spent by the transaction.
?OutputsTxOutput[]List of outputs the transaction produces.
?KernelsTxKernel[]List of kernels that make up this transaction (usually a single kernel).
CompactBlockBody
SizeNameData TypeDescription/Comments
?FullOutputsTxOutput[]List of full outputs - specifically the coinbase output(s).
?FullKernelsTxKernel[]List of full kernels - specifically the coinbase kernel(s).
?KernelIdsShortId[]List of transaction kernels, excluding those in the full list. Each ShortId is 6 bytes.
TxInput
TxOutput
TxKernel
ProofOfWork
SizeNameData TypeDescription/Comments
8TotalDifficultyuint64Total accumulated difficulty since genesis block.
4ScalingDifficultyuint32Difficulty scaling factor between the different proofs of work.
8Nonceuint64Nonce increment used to mine the block.
1EdgeBitsuint8Power of 2 used for the size of the cuckoo graph.
336ProofNoncesuint64[42]The cuckoo proof nonces.

Messages

Error
SizeNameData TypeDescription/Comments
4Codeuint32Error Code. TODO: Determine possible values.
?MessageVAR_STRSlightly more user-friendly message
Hand
SizeNameData TypeDescription/Comments
4Versionuint32Protocol version of the sender.
1CapabilitiesCapabilitiesMaskBitmask representing the capabilities of the sender.
8Nonceuint64Randomly generated for each handshake to help detect connections to yourself.
8TotalDifficultyuint64Total difficulty accumulated by the sender. Used to check whether sync may be needed.
7/19SenderAddressSocketAddressNetwork address of the sender. 7 bytes for IPv4 or 19 bytes for IPv6.
7/19ReceiverAddressSocketAddressNetwork address of the receiver. 7 bytes for IPv4 or 19 bytes for IPv6.
?UserAgentVAR_STRName and version of the software. Example: "MW/Grin 0.1.2"
32Hashuint8[32]Genesis block of the current chain. Testnet1/2/3 and mainnet all have a different genesis.
Shake
SizeNameData TypeDescription/Comments
4Versionuint32Protocol version of the sender.
1CapabilitiesCapabilitiesMaskBitmask representing the capabilities of the sender.
8Nonceuint64Randomly generated for each handshake to help detect connections to yourself.
8TotalDifficultyuint64Total difficulty accumulated by the sender. Used to check whether sync may be needed.
?UserAgentVAR_STRName and version of the software. Example: "MW/Grin 0.1.2"
32Hashuint8[32]Genesis block of the current chain. Testnet1/2/3 and mainnet all have a different genesis.
Ping
SizeNameData TypeDescription/Comments
8TotalDifficultyuint64Total difficulty accumulated by the sender. Used to check whether sync may be needed.
8Heightuint64Total block height accumulated by the sender. See: https://github.com/mimblewimble/grin/issues/1779
Pong
SizeNameData TypeDescription/Comments
8TotalDifficultyuint64Total difficulty accumulated by the sender. Used to check whether sync may be needed.
8Heightuint64Total block height accumulated by the sender. See: https://github.com/mimblewimble/grin/issues/1779
GetPeerAddrs
SizeNameData TypeDescription/Comments
1CapabilitiesCapabilitiesMaskThe capabilities the peer should have.
PeerAddrs
SizeNameData TypeDescription/Comments
4Sizeuint32_tThe number of peer addresses received.
?PeersSocketAddress[]Peer addresses that match the criteria from the GetPeerAddresses request.
GetHeaders
SizeNameData TypeDescription/Comments
1Sizeuint8_tThe number of headers being requested.
?HashesHash[]The 32-byte Blake2b hashes of the block headers being requested.
Header
SizeNameData TypeDescription/Comments
2Versionuint16The version of the block.
8Heightuint64Height of this block since the genesis block (height 0).
8Timestampint64Timestamp at which the block was built.
32PreviousHashBlake2b hash of the block previous to this in the chain.
32PreviousRootHashMerklish root of all the commitments in the previous block's TxHashSet.
32OutputRootHashMerklish root of all the commitments in the TxHashSet.
32RangeProofRootHashMerklish root of all range proofs in the TxHashSet.
32KernelRootHashMerklish root of all transaction kernels in the TxHashSet.
32TotalKernelOffsetBlindingFactorTotal accumulated sum of kernel offsets since genesis block.
8OutputMMRSizeuint64Total size of the output Merkle Mountain Range(MMR) after applying this block.
8KernelMMRSizeuint64Total size of the kernel MMR after applying this block.
178ProofOfWorkProofOfWorkProof of work and related.
Headers
SizeNameData TypeDescription/Comments
2Sizeuint16_tThe number of headers received.
?HeadersBlockHeader[]The headers matching the hashes provided in the GetBlockHeaders request.
GetBlock
SizeNameData TypeDescription/Comments
32BlockHashHashThe Blake2b hash of the block being requested.
Block
SizeNameData TypeDescription/Comments
405HeaderBlockHeaderThe block header.
?BodyTransactionBodyThe block transaction containing the inputs, outputs, and kernel(s).
GetCompactBlock
SizeNameData TypeDescription/Comments
32BlockHashHashThe Blake2b hash of the compact block being requested.
CompactBlock
SizeNameData TypeDescription/Comments
405HeaderBlockHeaderThe header with metadata and commitments to the rest of the data.
8Nonceuint64Nonce for connection specific short_ids.
?BodyCompactBlockBodyContainer for out_full, kern_full and kern_ids in the compact block.
StemTransaction
SizeNameData TypeDescription/Comments
32OffsetBlindingFactorThe kernel "offset" k2.
?BodyTransactionBodyThe transaction body containing the inputs, outputs, and kernel(s).
Transaction
SizeNameData TypeDescription/Comments
32OffsetBlindingFactorThe kernel "offset" k2.
?BodyTransactionBodyThe transaction body containing the inputs, outputs, and kernel(s).
TxHashSetRequest
SizeNameData TypeDescription/Comments
32BlockHashHashBlake2b hash of the block for which the TxHashSet should be provided.
8Heightuint64Height of the corresponding block.
TxHashSetArchive

The response to a TxHashSetRequest. Includes a zip stream of the archive after the message body.

SizeNameData TypeDescription/Comments
32BlockHashHashBlake2b hash of the block for which the txhashset are provided.
8Heightuint64Height of the corresponding block.
8Bytesuint64Size in bytes of the archive.
BanReason
SizeNameData TypeDescription/Comments
4BanReasonReasonForBanEnumThe reason for the ban.

Protocol Versions and Capabilities

Capabilities

Any feature that users will have the ability to disable should be implemented as a new capability (See CapabilitiesMask above). This includes things like archive mode/full history.

Protocol Version

Any change to the p2p protocol that is not toggled by the addition of a new capability should result in an increase in protocol version (See Hand & Shake messages above). This includes any addition or removal of a field or entire message, or any backward-incompatible behavior change to an existing field or message. When interacting with peers on an older protocol version, backward compatibility must be maintained, so the newer node should follow the rules of the older protocol version.

Phasing out old peers

To reduce the long-term complexity of the code, we can periodically bump the "major" protocol version. Although the protocol version is just a uint32, we can consider every increase by 1000 a new "major" protocol version. We can then gracefully phase out stubborn peers that refuse to upgrade by only supporting 1 major protocol version in the past. Here's what this would look like in practice:

  • Peers with a protocol version in the range [0-999] should be able to interact with any peer in the range [0-1999].
  • Peers with a protocol version in the range [1000-1999] should be able to interact with any peer in the range [0-2999].
  • Peers with a protocol version in the range [2000-2999] should be able to interact with any peer in the range [1000-3999].

Determining when to increase the "major" version is left up to the discretion of the developers. Care must be taken to ensure we are not increasing too quickly however, as any major bump could result in the inability to connect to certain older peers.