This EIP introduces eth/73, extending the cell retrieval protocol defined by EIP-8070. It adds indexed forms of GetCells and Cells in which each transaction hash references a mask in a deduplicated mask table. The existing shared-mask forms remain available for uniform requests, avoiding additional overhead in the common case.
The eth/72 GetCells message applies one cell mask to every transaction hash in a request. When transactions require different cell sets, a client must partition one scheduling batch into multiple requests by exact mask equality. Partial responses and differing peer availability can produce these heterogeneous missing-cell sets.
Using one mask per transaction would avoid partitioning but would repeat a 16-byte mask for every hash and increase the size of uniform requests. An indexed table represents each unique mask once and lets a sender retain the shared form when it is more efficient.
Synthetic request traces show substantial reductions in request frames for highly fragmented batches. A sparse devnet observation, however, recorded no fragmented batches in the measured window. This EIP is therefore a draft for evaluating a conditional optimization, not a claim that current network traffic requires a new protocol version.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
eth/73 extends eth/72. All eth/72 messages and semantics remain unchanged except for the additions to GetCells and Cells specified below.
The following notation is used:
P is an RLP-encoded positive integer.B is an RLP byte string.B_16 is a 16-byte cell mask.B_32 is a 32-byte transaction hash.B_2048 is a 2048-byte cell.An indexed message contains masks, a list of unique B_16 values, and mask_ids, a byte string containing one unsigned byte for each transaction hash. Each byte in mask_ids is the zero-based index of the mask applying to the hash at the same position.
An indexed message MUST satisfy all of the following requirements:
len(mask_ids) equals the number of transaction hashes.len(masks).mask_ids.The eth/72 protocol recommends a soft limit of 64 transaction hashes for GetCells. This EIP adopts 64 transaction hashes as a mandatory validity limit for indexed requests and non-empty indexed responses, and introduces a separate mandatory limit of 64 masks. These limits apply only to the indexed forms. The shared forms retain their existing eth/72 semantics as defined by EIP-8070. A mask identifier remains one byte, allowing a future protocol version to raise the mask-table limit to at most 256 without changing the identifier encoding.
A peer receiving an indexed message that violates any of these requirements MUST treat the message as invalid.
GetCells (0x14)eth/73 accepts two request forms:
[request_id: P, [hash_0: B_32, hash_1: B_32, ...], cell_mask: B_16][request_id: P, [hash_0: B_32, hash_1: B_32, ...], [mask_0: B_16, mask_1: B_16, ...], mask_ids: B]The RLP list length distinguishes the two forms. The shared form has the same encoding and semantics as eth/72.
For an indexed request, the mask selected by mask_ids[i] specifies the cell indices requested from every blob of the transaction identified by hashes[i].
A sender selects the request form as follows:
Cells (0x15)eth/73 accepts two response forms:
[request_id: P, [hash_0: B_32, hash_1: B_32, ...], [[cell_0_0: B_2048, ...], [cell_1_0: B_2048, ...], ...], cell_mask: B_16][request_id: P, [hash_0: B_32, hash_1: B_32, ...], [[cell_0_0: B_2048, ...], [cell_1_0: B_2048, ...], ...], [mask_0: B_16, mask_1: B_16, ...], mask_ids: B]Responses are processed according to the following rules:
eth/72 response-size and serving-capacity rules.masks and mask_ids fields describe only the hashes and cells actually present in that response and MUST satisfy the mask-table requirements above.An indexed response containing no transaction data MUST be encoded as [request_id: P, [], [], [], mask_ids: B], where mask_ids is the empty byte string. This empty response is exempt from mask-table requirements 1 and 3. Its empty mask_ids satisfies requirement 2, and the remaining requirements apply vacuously. An indexed request MUST NOT be empty.
Implementations enforce the following resource limits:
eth/72 response soft limit continues to apply.A parallel mask array has simple semantics but adds 16 bytes for every transaction. The indexed table is equivalent when every mask is unique and is smaller when masks repeat. Requiring first-reference order, unique entries, and no unused entries gives each mapping one canonical encoding.
Custody-aligned sampling normally produces one shared mask across many transactions. Keeping the eth/72 form prevents a regression for this case. Indexed encoding targets recovery and partial-delivery states where missing-cell sets diverge.
The eth/72 Cells response contains one shared mask. It cannot describe different returned cell sets for different transaction hashes. An indexed request therefore requires a corresponding indexed response; changing only GetCells would leave partial and heterogeneous responses ambiguous.
Controlled traces demonstrate the mechanism but do not establish its frequency. In one corrected sparse-node observation, 92 scheduling batches contained zero fragmented batches. Implementers should collect mask-group cardinality, hashes per group, request frames, response frames, and end-to-end latency before recommending deployment of eth/73.
This EIP introduces a new negotiated eth capability. An eth/73 implementation can continue negotiating eth/72 with peers that do not support indexed cell requests. Such peers receive only the shared GetCells and Cells forms defined by EIP-8070.
The security requirements are:
Copyright and related rights waived via CC0.