Network Messages in Ergo's P2P Protocol

This document provides a detailed overview of the network messages in Ergo's P2P protocol. Understanding these messages is crucial for interacting with the Ergo network at a low level. Each message in the protocol has a specific format and serves a unique purpose in the communication between nodes.

Message Format

Every message in the P2P protocol has the following format:

Data typeField nameDetails
byte[4]Magic bytesFor the mainnet, the magic bytes are [1, 0, 2, 4]. For testnet, [2, 0, 0, 1].
unsigned byteMessage codeOne byte describing message type
intMessage body lengthNo VLQ or ZigZag encoding is used for the message length (for historical reasons); bytes are coming in big-endian order.
byte[4]Handshake body checksumFirst four bytes of blake2b256(message body)
byte[bodyLength]Message bodyMessage body

For more detailed implementation, you can check out the Ergo Node View Synchronizer in the Ergo repository.

Records

Records are structured data types used in the P2P protocol. They include Peer, Feature, Modifier, and Header records.

Peer

Data typeField nameDetails
unsigned byteLength of next field
UTF-8 StringAgent name
byte[3]VersionFor example, [4, 0, 25]
unsigned byteLength of next field
UTF-8 StringPeer name
booleanWhether public address exists
(unsigned byte)Length of the IP plus 4When decoding, subtract the value with 4 to get the actual length
(byte[ipLength - 4])The public IP address
(VLQ unsigned int)Port
unsigned byteCount of peer features
Feature[featureCount]Features

Feature

Data typeField name
unsigned byteFeature code
VLQ unsigned shortBody length
byte[bodyLength]Body

Modifier (Record)

Data typeField name
byte[32]Modifier ID
VLQ unsigned intLength of object
byte[objectLength]Object

Header

Data typeField name
VLQ unsigned shortLength of bytes
byte[length]Bytes

For a deeper understanding of how records are serialized, check out the Ergo Serialization Documentation.

Messages

Messages are the primary means of communication between nodes in the P2P network. They include Get Peers, Peers, Sync Info, Inv, Request Modifier, and Modifier messages.

Get Peers

Code = 1

The body is empty.

Peers

Code = 2

Sent in response to Get Peers. Contains all the peers that are currently connected to. Used for node discovery.

Data typeField name
VLQ ZZ intCount of peers
Peer[]Peers

For the Java implementation of the GetPeers message, refer to Ergonnection.

Sync Info

Code = 65

New (Added in 4.0.16)

It is sent only to nodes that report a version of 4.0.16 or higher. For older nodes, the Sync Info (old) is sent.

Requests an Inv message that provides modifier IDs required by the sender to synchronize their blockchain with the recipient. It allows a peer which has been disconnected or started for the first time to get the data it needs to request the blocks it hasn't seen.

Data typeField name
VLQ unsigned shortThe constant value 0
byteThe constant value -1
unsigned byteCount of headers
Header[headerCount]Headers

Sync Info (old)

Code = 65

The old (before 4.0.16) version of the Sync Info message.

Data typeField name
VLQ unsigned shortCount of last header IDs
byte[32][lastHeaderIdCount]Last header IDs (ID byte arrays)

Inv

Code = 55

Transmits one or more inventories of objects known to the transmitting peer.

It can be sent unsolicited to announce new transactions or blocks, or it can be sent in reply to a Sync Info message.

Data typeField name
unsigned byteType ID
VLQ unsigned intCount of elements
byte[32][elementCount]Elements (ID byte arrays)

For an example of how INV messages are handled, see InvSpec.scala.

Request Modifier

Code = 22

Requests one or more modifiers from another node. The objects are requested by an inventory, which the requesting node typically received previously with an Inv message.

This message cannot be used to request arbitrary data, such as historic transactions no longer in the memory pool. Full nodes may not even be able to provide older blocks if they've pruned old transactions from their block database.

For this reason, this message should usually only be used to request data from a node that previously advertised it had that data by sending an Inv message.

Data typeField name
unsigned byteModifier type ID
VLQ unsigned intCount of elements
byte[32][elementCount]Elements (ID byte arrays)

Modifier

Code = 33

Sent in response to Request Modifier.

Data typeField name
unsigned byteType ID
VLQ unsigned intCount of modifiers
Modifier[modifierCount]Modifiers

Pull Requests (PRs) & Tests

The NiPoPoW powered bootstrapping PR #1365 is a relevant enhancement that introduces a method to bootstrap nodes using Non-Interactive Proofs of Proof-of-Work (NiPoPoWs).

Tests for parsing networking messages against test vectors are discussed in PR #1264, which includes:

  • Enhanced validation with require() for non-elidable checks.
  • Simplified test vectors for invalid PoW solution validation and handshake parsing.
  • Introduced SyncInfo networking message parsing test (can be used as a simple spec).

These tests ensure robust handling of network messages in Ergo's P2P protocol.

Demo Applications

Demo applications are available for practical implementation, such as:

These demos provide examples of how to generate addresses and print transactions using the Ergo wallet functionalities.

Resources

  • A simple implementation of VLQ and ZigZag encoding can be found here.
  • A complete implementation of the P2P protocol written in Java can be found in Ergonnection.