<!--
Blockchain Lab reading mirror.
Licence: CC0-1.0. This is the upstream licence, not a Blockchain Lab grant.
Canonical: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8077.md
Repository: https://github.com/ethereum/EIPs
Mirrored: 2026-10-10
The text below is the upstream file. The desk study is a different page and is not covered by this licence.
-->

---
eip: 8077
title: eth/XX - announce transactions with nonce
description: Adds source and nonce to transaction announcements
author: Csaba Kiraly (@cskiraly)
discussions-to: https://ethereum-magicians.org/t/eip-8077-eth-xx-add-nonce-and-source-to-transactions-announcement/26505
status: Draft
type: Standards Track
category: Networking
created: 2025-11-07
requires: 7642
---

## Abstract

This EIP improves mempool propagation, extending the devp2p 'eth' protocol's `NewPooledTransactionHashes` message to also announce each transaction's source address and nonce together with the already announced hash, type, and size.

## Motivation

Transactions are propagated in the mempool using the devp2p protocol in two modalities. Eager push is only used for small transactions, and only towards a few nodes, while the rest of the nodes receive only announcements. For large transactions and for type 3 transactions, only announcements are sent. This announcement is made using the `NewPooledTransactionHashes` message, which only contains the hash, the type and the size of each transaction. As it is now, the receiver of the announcement does not have enough information to make intelligent scheduling choices. This creates several issues:

- the receiver of the announcement can only base its logic on the order of announcements, but if it schedules requests to different peers, it can easily end up pulling transactions that leave a nonce gap in its own view of the mempool, making the pulled transaction non-includable,
- filling existing gaps is hard, since in the absence of sender/nonce information it can only be done with trial and error, requesting more transactions of missing hashes,
- to filter out old transaction announcements, the node has to keep a cache of all transaction hashes on chain, instead of simply checking the nonce against current chain state,
- receivers have no way to selectively request transactions with specific source addresses, which would be important for UX and L2s.

Moreover, as we are increasing the throughput of block building, it is more and more probable that we end up in a state where nodes can't fetch all transactions. This extension allows nodes to do selective fetching and gap filling while keeping a consistent state of their own view of the mempool without nonce gaps.

## Specification

### NewPooledTransactionHashes message changes

Modify the `NewPooledTransactionHashes` (0x08) message as follows:

(eth/69): [txtypes: B, [txsize₁: P, txsize₂: P, ...], [txhash₁: B_32, txhash₂: B_32, ...]]

(eth/XX): [txtypes: B, [txsize₁: P, txsize₂: P, ...], [txhash₁: B_32, txhash₂: B_32, ...], [txsource₁: B_20, txsource₂: B_20, ...], [txnonce₁: P, txnonce₂: P, ...]]

### Announced source and nonce

`txsource` is the account whose nonce the transaction consumes, and `txnonce` is the nonce value it consumes.

For transaction types `0x00` through `0x04`, `txsource` is the address recovered from the transaction's signature and `txnonce` is the transaction's `nonce` field.

For [EIP-8141](./eip-8141.md) frame transactions, `txsource` is the transaction's explicit `sender` field and `txnonce` is its `nonce` field. [EIP-8250](./eip-8250.md) replaces that `nonce` field with `nonce_keys` and `nonce_seq`, and `txnonce` is then `nonce_seq`. The sender is not recovered from a signature, is not necessarily the address of any entry in the transaction's `signatures` list, and may be a contract account.

### Changes to message handling

Changes on the sender side of `NewPooledTransactionHashes` messages are trivial. Only the transmitted data changes. Since the size of announcements is increased, implementations MAY revisit the condition (typically transaction size) to select between eager push and announcement.

On the receiver side of `NewPooledTransactionHashes` messages, the extra information can be used to improve scheduling choices; however, these are not mandated by the protocol and thus we leave it to implementations.

The announced nonce is not always an account nonce. Where [EIP-8250](./eip-8250.md) is active, a frame transaction may consume a keyed nonce sequence instead of the sender's account nonce, in which case `txnonce` is that sequence's value and is unrelated to `state[txsource].nonce`; a valid transaction can announce a sequence value either far below or far above it. Which of the two a frame transaction uses is not visible in the announcement. Receivers therefore MUST NOT compare the `txnonce` of a frame transaction against `state[txsource].nonce`, neither to discard the announcement as stale nor to infer a nonce gap, and MUST NOT use `<txsource, txnonce>` as the identity of a frame transaction, since under [EIP-8250](./eip-8250.md) the pending transaction identity is `<sender, nonce_keys, nonce_seq>`. The announced type distinguishes these transactions from the ones the account nonce check remains valid for.

## Rationale

To solve the transaction propagation issues mentioned in the Motivation section, nodes require more information about a transaction than its hash, size, and type. By adding the source and the nonce, the receiver has enough information to make better fetch decisions.

### Account abstraction

[EIP-8141](./eip-8141.md) makes the sender an explicit transaction field rather than a value recovered from a signature, so a receiver has no way to derive it before fetching. Its public mempool admits at most one pending frame transaction per sender, requires that transaction's nonce to equal the sender's current nonce, and identifies pending transactions by `<sender, nonce>`. There are therefore no nonce gaps to fill for these transactions, and the announcement instead answers whether the receiver already holds a candidate for that sender. That answer is worth more than for other transaction types, because validating a frame transaction means simulating its validation prefix, so a fetch that ends in rejection costs the receiver execution and not just bandwidth.

[EIP-8250](./eip-8250.md) replaces the frame transaction nonce with `<nonce_keys, nonce_seq>` and announcements carry only `nonce_seq`. Announcing the key set would reproduce the pending transaction identity exactly, but it holds up to sixteen words, and even its canonical 32-byte hash would be paid for by every announcement of every transaction type. Since the public mempool still admits only one pending frame transaction per sender, the source already carries the scheduling decision for these transactions and the nonce is left as a hint.

### Overhead

The modification adds a significant overhead to announcements by adding a B_20 and a variable-size field to the current B_32, size, and type fields. We think this overhead is worth
the additional gain in protocol efficiency. Details TBD <-- TODO --> .

### Alternatives

While the modification is relatively straightforward, there are several design variants to
consider. First of all, small transactions are mostly propagated by the push mechanism, while
announcement-based pull is only used as recovery. We could choose to avoid the extra announcement overhead for these; however, it would mean that filling nonce gaps remains difficult, only possible by trial-and-error.

Another possibility similar to the previous one is to restrict the mechanism to blob transactions only. We choose not to restrict it in the proposal for the same reasons as in the previous point.

If the traffic overhead from notifications is a concern, it is also worth considering how many nodes announcements should be sent to. While this is not mandated by the protocol, a typical implementation is to send announcements to all neighbors (except the ones that already signaled having it, and the ones to which the message is pushed). Should nodes send announcements to all peers, or only part of their peer set (e.g. proportional, or to a fixed number of peers)? The protocol allows sending to only a part, and in case of bandwidth constraints it seems better to send more metadata (addresses and nonces) to fewer peers.

Currently, for any given transaction, nodes receive announcements from many peers. About half of their peers, on average. Having the whole metadata (txhash, type, size, source, nonce) in all these is highly redundant. We could remove some of this overhead, e.g. by having a probabilistic choice between a simple announcement and a detailed announcement. The gain however seems marginal compared to the added complexity.

Sending the source and the nonce opens up the possibility of a design variant where the transaction identifier in the announcements is based on these values, and not on the txhash. More specifically, a transaction could be identified by the source, the nonce, and an extra version number signaling the RBF (replace-by-fee) version in the given source/nonce scope. This variant would require deeper changes since the RBF version would need to be signed.

As an alternative to the above, fee values can be used as a proxy for the RBF version. Since the RBF requirement is fee-based anyway, and the fee is already signed, adding the fee information to the announcement allows the receiver to compare different versions and pull the newer one. Moreover, having the fee information already in the announcement also allows nodes to anticipate their transaction ordering decisions and avoid pulling transactions that would be dropped, providing further traffic reduction.

## Backwards Compatibility

This EIP changes the eth protocol and requires rolling out a new version. Supporting multiple versions of a wire protocol is routine practice. Rolling out this new version does not break older clients, since they can keep using the previous protocol version.

This EIP does not change consensus rules of the EVM and does not require a hard fork.

## Security Considerations

The announced source address and nonce cannot be verified by the recipient until the transaction is actually fetched (or received through eager push). Therefore, it should not be handled as trusted information. This does not compromise the security of the protocol.

Announcing a transaction whose source is chosen freely costs an attacker nothing, and a receiver that answers each announcement with a lookup of `state[txsource].nonce` performs one state read per announcement for an attacker-chosen address. This is the announcement-level form of the sender state-read amplification described in [EIP-8141](./eip-8141.md), and it argues for applying cheap checks, such as peer and rate limits, before any state access driven by announced metadata.

A mismatch between the announced <txhash,type,size,address,nonce> tuple and a received transaction should be handled as a protocol violation. In more detail, after the verification of the transaction hash, it becomes clear that the sender of the announcement was either malicious, or it sent an announcement without verifying its content. Thus, the sender of the offending announcement can be treated as a node that violated the protocol.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
