Devp2p/ at master · ethereum/devp2p · GitHub

‘eth’ is a protocol on the rlpx transport that facilitates peer-to-peer exchange of ethereum blockchain information. the current version of the protocol is eth/67. see the end of the document for a list of changes in previous versions of the protocol.

basic operation

once a connection is established, a status message should be sent. after receiving the status message from the partner, the ethereum session is active and any other message can be sent.

Reading: Ethereum 65m series 10m seriesblock

Within a session, three high-level tasks can be performed: chain synchronization, block propagation, and transaction exchange. these tasks use separate sets of protocol messages and are typically performed by clients as simultaneous activities on all peer-to-peer connections.

Client implementations must impose limits on the size of protocol messages. the underlying rlpx transport limits the size of a single message to 16.7 mib. practical limits for the eth protocol are lower, typically 10 mib. if a received message is larger than the limit, the partner must disconnect.

In addition to the hard limit on messages received, clients must also impose “soft” limits on the requests and responses they send. the recommended soft limit varies by message type. throttling requests and responses ensures that concurrent activity, e.g. block synchronization and transaction exchange work seamlessly on the same peer-to-peer connection.

chain synchronization

nodes participating in the eth protocol are expected to have knowledge of the complete chain of all blocks from the genesis block to the last current block. the chain is obtained by downloading it from other peers.

On connection, both partners send their status message, which includes the total difficulty (td) and the hash of their ‘best’ known block.

The client with the worst td then proceeds to download block headers using the getblockheaders message. checks the proof-of-work values ​​in the received headers and gets the block bodies using the getblockbodies message. received blocks are executed using the ethereum virtual machine, recreating the state tree and receipts.

Note that header downloads, body block downloads, and block execution can occur at the same time.

state sync (also known as “quick sync”)

Protocol versions eth/63 to eth/66 also allowed synchronization of the state tree. as of eth/67 protocol version, the ethereum state tree can no longer be retrieved using the eth protocol, and state dumps are provided by the helper plugin protocol instead.

State synchronization normally proceeds by downloading the chain of block headers, checking their validity. block bodies are requested as in the sync section of the chain, but transactions are not executed, only “data validity” is checked. the client chooses a block near the head of the chain (the ‘pivot block’) and downloads the state of that block.

block propagation

newly mined blocks should be broadcast to all nodes. this happens through block propagation, which is a two-step process. when a new block advertisement message is received from a peer, the client first checks the validity of the basic header of the block, checking whether the proof-of-work value is valid. then send the block to a small fraction of connected peers (usually the square root of the total number of peers) using the newblock message.

after the header validity check, the client imports the block to its local chain by executing all the transactions contained in the block, calculating the ‘back state’ of the block. the block’s state root hash must match the computed post state root. once the block is fully processed and deemed valid, the client sends a newblockhashes message about the block to all peers not previously notified. those peers can request the full block later if they don’t receive it via someone else’s newblock.

A node should never send a block announcement to a peer that has previously announced the same block. this is usually accomplished by remembering a large set of recently transmitted block hashes to or from each peer.

receiving a block announcement can also trigger chain synchronization if the block is not the immediate successor of the last current block from the client.

transaction exchange

all nodes must exchange pending transactions to relay them to the miners, who will select them to be included in the block chain. client implementations keep track of the set of pending transactions in the ‘transaction group’. the pool is subject to client-specific limits and can contain many (ie, thousands of) transactions.

When a new peer-to-peer connection is established, the transaction groups on both sides must be synchronized. initially, both ends must send new bundled transaction hash messages containing all the transaction hashes in the local bundle to start the exchange.

Upon receiving an announcement of new pooled transaction hashes, the client filters the received pool and collects transaction hashes that it does not already have in its own local pool. then you can request the transactions using the getpooledtransactions message.

When new transactions appear in the client’s pool, you must propagate them to the network using the bundled new transaction hash and transaction messages. the transaction message carries complete transaction objects and is typically sent to a small random fraction of connected peers. all other peers are notified of the transaction hash and can request the full transaction object if they don’t know it. broadcasting complete transactions to a fraction of peers generally ensures that all nodes receive the transaction and do not need to request it.

A node should never return a transaction to a peer that it can determine it already knows about (either because it was previously sent or originally reported by this peer). this is usually achieved by remembering a set of transaction hashes recently transmitted by the peer.

transaction encoding and validity

Peer-to-peer transaction objects have one of two encodings. in the definitions of this specification, we refer to transactions of any encoding using the identifier txₙ.

inherited untyped transactions are given as an rlp list.

eip-2718 typed transactions are encoded as rlp byte arrays where the first byte is the transaction type (type tx) and the remaining bytes are type-specific opaque data.

transactions must be validated when received. the validity depends on the state of the ethereum chain. the specific type of validity this specification refers to is not whether the transaction can be successfully executed by the evm, but only whether it is acceptable for temporary storage in the local group and for exchange with other peers.

transactions are validated according to the following rules. while the encoding of written transactions is opaque, their tx data is supposed to provide values ​​for nonce, gas-price, gas-limit, and that the account of the sender of the transaction can be determined from their signature.

  • if the transaction is written, the implementation must know the type of tx. defined transaction types may be considered valid even before they are acceptable for inclusion in a block. implementations must disconnect peers that send transactions of unknown type.
  • the signature must be valid according to the signature schemes supported by the chain. for typed transactions, the handling of the signature is defined by the eip that introduces the type. for legacy transactions, the two schemes in active use are the basic ‘homestead’ scheme and the eip-155 scheme.
  • the gas limit must cover the ‘intrinsic gas’ of the transaction.
  • the account of the sender of the transaction, which is derived from the signature, must have enough ether balance to cover the cost (gas limit * gas price + value) of the transaction.
  • the nonce of the transaction must be equal to or greater than the current nonce of the sender’s account.
  • when considering the transaction for inclusion in the local pool, it is up to implementations to determine how many ‘future’ transactions with nonces greater than the current account’s nonces are valid and to what extent “nonce gaps” are acceptable.

implementations may impose other validation rules for transactions. for example, it is common practice to reject encrypted transactions larger than 128 kb.

Unless otherwise noted, implementations should not disconnect peers for sending invalid transactions, and should simply discard them instead. this is because the pair might be operating under slightly different validation rules.

block encoding and validity

Ethereum blocks are encrypted as follows:

See also: What will Ethereum prices be as 2021 ends?

In certain protocol messages, the transaction and ommer lists are transmitted together as a single element called a ‘block body’.

The validity of block headers depends on the context in which they are used. for a single block header, only the proof-of-work seal (mix-digest, block-nonce) can be checked for validity. when a header is used to extend the client local string, or multiple headers are processed in sequence during string synchronization, the following rules apply:

  • the headers must form a string where the block numbers are consecutive and the main hash of each header matches the hash of the previous header.
  • by extending the locally stored string, implementations should also verify that the difficulty, gas limit, and time values ​​are within the limits of the protocol rules noted on the yellow paper.
  • the gas header field used should be less than or equal to the gas limit.
  • the basefee-per-gas header field must be present for blocks after the london hard fork. note that the base rate for gas must be absent for the blocks above. this rule was implicitly added by eip-1559, which added the field to the ethereum block hash definition.

for full blocks, we distinguish between the validity of the block’s evm state transition and the (weaker) “data validity” of the block. the definition of state transition rules is not covered in this specification. we require the validity of the block data for the purposes of immediate block propagation and during state synchronization.

To determine the validity of the data in a block, use the following rules. implementations must disconnect peers that send invalid blocks.

  • the block header must be valid.
  • the transactions contained in the block must be valid for inclusion in the chain in the block number. this means that, in addition to the transaction validation rules given above, it is required to validate whether the tx type is allowed in the block number, and the transaction gas validation must take the block number into account.
  • the sum of the gas limits of all transactions must not exceed the gas limit of the block.
  • transactions in the block must be verified against the txs root by calculating and comparing the merkle trie hash of the transaction list block.
  • the ommers list can contain at most two headers.
  • keccak256(ommers) must match the ommers hash of the block header.
  • the headers contained in the ommers list must be valid headers. their block number must not be greater than that of the block in which they are included. the parent hash of an ommer header must refer to an ancestor of depth 7 or less of its included block, and must not have been included in any previous block contained in this set of ancestors.

receipt encoding and validity

receipts are the output of a block’s evm state transition. Just like transactions, receipts have two different encodings and we will refer to either of them using the identifier receiptₙ.

unwritten legacy receipts are encoded as follows:

receipts written with eip-2718 are encoded as rlp byte arrays where the first byte provides the receipt type (matches the type of tx) and the remaining bytes are type-specific opaque data.

In the ethereum wire protocol, receipts are always transferred as the complete list of all receipts contained in a block. it is also assumed that the block containing the receipts is valid and known. when a peer receives a list of block receipts, it must be verified by calculating and comparing the merkle trie hash of the list with the root of block receipts. since the valid list of receipts is determined by the evm state transition, no further validity rules need to be defined for receipts in this specification.

protocol messages

In most messages, the first item in the message data list is the request ID. for requests, this is a 64-bit integer value chosen by the requesting peer. the responding peer must reflect the value in the request id element of the response message.

status (0x00)

[version: p, networkid: p, td: p, blockhash: b_32, genesis: b_32, forkid]

inform a peer of your current status. this message should be sent just after the connection is established and before any other eth protocol messages.

  • version: the current version of the protocol
  • networkid: integer identifying the blockchain, see the table below
  • td: total difficulty of the best string. integer, as found in the block header.
  • blockhash: the hash of the best known block (i.e., highest td)
  • genesis: the hash of the genesis block
  • forkid: An eip-2124 fork identifier, encoded as [fork-hash, fork-next].

This table lists common network identifiers and their corresponding networks. there are other IDs that are not listed, ie customers should not require any particular network ID to be used. note that the network id may or may not correspond to the eip-155 chain id used for transaction replay prevention.

For a community-curated list of chain ids, see

new block hashes (0x01)

[[blockhash₁: b_32, number₁: p], [blockhash₂: b_32, number₂: p], …]

Specify one or more new blocks that have appeared on the network. to be most helpful, nodes should inform peers of all blocks they may not be aware of. including hashes that the sending peer could reasonably be considered to know (due to the fact that they were previously informed because that node has advertised knowledge of the hashes via newblockhashes) is considered bad form and can reduce the reputation of the node shipping. including hashes that the sending node then refuses to honor with an ongoing getblockheaders message is considered poor quality and can reduce the reputation of the sending node.

transactions (0x02)

[tx₁, tx₂, …]

Specify the transactions that the peer must ensure are included in its transaction queue. the items in the list are transactions in the format described in the main ethereum specification. transaction messages must contain at least one (new) transaction; empty transaction messages are discouraged as they can cause disconnection.

Nodes must not forward the same transaction to a peer in the same session and must not forward transactions to a peer from which they received that transaction. in practice, this is often implemented by keeping a per-peer bloom filter or a set of hashes of transactions that have already been sent or received.


[request-id: p, [startblock: {p, b_32}, limit: p, skip: p, reverse: {0, 1}]]

require the peer to return a blockheaders message. the response must contain a number of block headers, ascending when reverse is 0, descending when reverse is 1, skip separate blocks, starting at the start block of the block (indicated by number or hash) in the canonical chain, and with boundary elements at most.

block heads (0x04)

[request-id: p, [header₁, header₂, …]]

This is the response to getblockheaders, containing the requested headers. the header list may be empty if none of the requested block headers were found. the number of headers that can be requested in a single message may be subject to implementation-defined limits.

The recommended soft limit for blockheader responses is 2 mib.


[request-id: p, [blockhash₁: b_32, blockhash₂: b_32, …]]

This message requests data from the hashed block body. the number of blocks that can be requested in a single message may be subject to implementation-defined limits.

block bodies (0x06)

[request-id: p, [block-body₁, block-body₂, …]]

this is the answer to getblockbodies. the elements of the list contain the body data of the requested blocks. the list can be empty if none of the requested blocks are available.

The recommended soft limit for block body responses is 2 mib.

new block (0x07)

[block, td: p]

See also: Cryptocurrency Market Hours | What Time of Day are Cryptos Most Traded? |

Specify a single complete block that the partner should know about. td is the total difficulty of the block, i.e. the sum of all the difficulties of the block up to and including this block.

new bundled transaction hashes (0x08)

[txhash₁: b_32, txhash₂: b_32, …]

This message announces one or more transactions that have appeared on the network and have not yet been included in a block. to be most helpful, nodes should inform peers of all transactions they may not be aware of.

The recommended soft limit for this message is 4096 hashes (128 kib).

Nodes should only advertise transaction hashes that the remote peer could reasonably be considered to be unaware of, but it is better to return more transactions than to have a nonce gap in the pool.

get bundled transactions (0x09)

[request-id: p, [txhash₁: b_32, txhash₂: b_32, …]]

This message requests transactions from the recipient’s transaction pool by hashing.

The recommended soft limit for getpooledtransactions requests is 256 hashes (8 kib). the recipient can impose an arbitrary limit on the response (size or service time), which should not be considered a protocol violation.

grouped transactions (0x0a)

[request-id: p, [tx₁, tx₂…]]

This is the response to getpooledtransactions, returning the requested transactions from the local pool. list items are transactions in the format described in the main ethereum specification.

transactions must be in the same order as in the request, but it’s fine to skip transactions that aren’t available. this way, if the response size limit is reached, the requesters will know which hashes to request again (everything from the last transaction returned) and which ones to assume are unavailable (all spaces before the last transaction returned) .

It is permissible to first advertise a transaction via new bundled transaction hashes, but then refuse to deliver it via bundled transactions. this situation can arise when the transaction is included in a block (and removed from the pool) between the ad and the request.

a peer may respond with an empty list if none of the hashes match the transactions in its group.

get receipts (0x0f)

[request-id: p, [blockhash₁: b_32, blockhash₂: b_32, …]]

requires the peer to return a receipt message containing the receipts of the given block hashes. the number of receipts that can be requested in a single message may be subject to implementation-defined limits.

receipts (0x10)

[request-id: p, [[receipt₁, receipt₂], …]]

this is the response to getreceipts, providing the requested block receipts. each element in the response list corresponds to a block hash of the getreceipts request and must contain the entire list of receipts for the block.

The recommended soft limit for receipt responses is 2 mib.


eth/67 (eip-4938, March 2022)

version 67 removed the getnodedata and nodedata messages.

  • getnodedata (0x0d) [request_id: p, [hash_0: b_32, hash_1: b_32, …]]
  • nodedata (0x0e) [request_id: p, [value_0: b, value_1: b, …]]

eth/66 (eip-2481, April 2021)

version 66 added request id element in getblockheaders, blockheaders, getblockbodies, blockbodies, getpooledtransactions, pooledtransactions, getnodedata, nodedata, getreceipts, receipts messages.

eth/65 with written transactions (eip-2976, April 2021)

When eip-2718 introduced typed transactions, the client implementers decided to accept the new transaction and receipt formats in the transfer protocol without upgrading the protocol version. this specification update also added definitions for the encoding of all consensus objects instead of referring to the yellow paper.

eth/65 (eip-2464, January 2020)

Version 65 improved the transaction exchange, introducing three additional messages: new bundled transaction hashes, get bundled transactions, and bundled transactions.

Prior to version 65, peers always exchanged complete transaction objects. As the activity and size of transactions increased on the Ethereum mainnet, the network bandwidth used for exchanging transactions became a significant burden on node operators. the upgrade reduced the required bandwidth by adopting a two-tier transaction transmission system similar to block propagation.

eth/64 (eip-2364, November 2019)

Version 64 changed the status message to include the forkid eip-2124. this allows peers to determine mutual compatibility of chain execution rules without synchronizing the blockchain.

eth/63 (2016)

version 63 added the getnodedata, nodedata, getreceipts and receipts messages that allow synchronizing the results of transaction execution.

eth/62 (2015)

In version 62, the newblockhashes message was extended to include block numbers along with the advertised hashes. the block number in status was removed. getblockhashes (0x03), blockhashes (0x04), getblocks (0x05), and blocks (0x06) messages were replaced with messages that get block headers and bodies. removed blockhashesfromnumber (0x08) message.

previous encodings for reassigned/removed message codes were:

  • getblockhashes (0x03): [hash: b_32, max-blocks: p]
  • blockhashes (0x04): [hash₁: b_32, hash₂: b_32, …]
  • getblocks (0x05): [hash₁: b_32, hash₂: b_32, …]
  • blocks (0x06): [[header, transactions, ommers], …]
  • blockhashesfromnumber (0x08): [number: p, max-blocks: p]

eth/61 (2015)

Version 61 added the blockhashesfromnumber (0x08) message which could be used to request blocks in ascending order. also added the latest block number to the status message.

eth/60 and under

version numbers less than 60 were used during the development phase of ethereum poc.

See also: ETH TON Dual Mining Definitive Guide. Overclocking, Profitability, Setup for Windows and Linux. – Crypto Mining Blog

  • 0x00 for poc-1
  • 0x01 for poc-2
  • 0x07 for poc-3
  • 0x09 for poc-4
  • 0x17 for poc-5
  • 0x1c for poc-6

Related Articles

Leave a Reply

Your email address will not be published.

Back to top button