Skip to content

feat(l1): eth/72 sparse blobpool (EIP-8070)#6776

Draft
edg-l wants to merge 14 commits into
mainfrom
feat/l1-eip8070
Draft

feat(l1): eth/72 sparse blobpool (EIP-8070)#6776
edg-l wants to merge 14 commits into
mainfrom
feat/l1-eip8070

Conversation

@edg-l

@edg-l edg-l commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Implements EIP-8070 (eth/72 sparse blobpool / PeerDAS sampling). The EIP is Draft (a Glamsterdam candidate, not SFI), so this is a draft PR; not for merge.

Changes

  • eth/72 protocol (extends eth/71): cell_mask field on NewPooledTransactionHashes; blob payloads elided to samplers in PooledTransactions; new GetCells (0x14) / Cells (0x15). Capability negotiation is version-gated, so eth/71 peers are unaffected.
  • Blobpool state machine (mempool.rs, sampling.rs): per-tx custody columns, cell verification against EIP-7594 proofs before storage, and pseudo-random provider role assignment (EIP-8070 §4).
  • Engine API: forkchoiceUpdatedV4 accepts optional custodyColumns; new engine_getBlobsV4 returns BlobCellsAndProofsV1. Custody expansion re-samples pending blob txs.

Default behavior

Sampling is off by default. --blob-sampling (ETHREX_BLOB_SAMPLING) activates the sampler/provider state machine; without it the node is a full-replication provider (p=1.0) and default builds are behaviorally unchanged. --blob-eager-provider forces the provider role for builders (EIP-8070 N8).

Testing

make lint and the full test suite pass. New coverage: mempool_cells_tests, sampling_tests, eip8070_kzg_tests, p2p/rlpx/eth72_tests, rpc/eth72_engine_tests.

Follow-ups

  • cell_mask endianness (u128_to_b16, big-endian) needs cross-client confirmation vs geth/reth before interop; isolated to one function.
  • Cell pruning on custody contraction is deferred; cells are retained on shrink (overcustody is harmless).
  • GetCells request-id framing to be confirmed against a canonical client (note in cells.rs).

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

⚠️ Known Issues — intentionally skipped tests

Source: docs/known_issues.md

Known Issues

Tests intentionally excluded from CI. Source of truth for the Known
Issues
section the L1 workflow appends to each ef-tests job summary
and posts as a sticky PR comment.

EF Tests — Stateless coverage narrowed to EIP-8025 optional-proofs

make -C tooling/ef_tests/blockchain test calls test-stateless-zkevm
instead of test-stateless. The zkevm@v0.3.3 fixtures are filled against
bal@v5.6.1, out of sync with current bal spec; the broad target trips ~549
fixtures. Re-broaden once the zkevm bundle is regenerated.

Why and resolution path

PR #6527 broadened
test-stateless to extract the entire for_amsterdam/ tree from the
zkevm bundle and run all of it under --features stateless; combined with
this branch's bal-devnet-7 semantics that scope produces ~549
GasUsedMismatch / ReceiptsRootMismatch /
BlockAccessListHashMismatch failures.

test-stateless-zkevm filters cargo to the eip8025_optional_proofs
suite, which still validates the stateless harness without the bal-version
mismatch.

Re-broaden by switching test: back to test-stateless in
tooling/ef_tests/blockchain/Makefile once the zkevm bundle is regenerated
against the current bal spec.

@github-actions github-actions Bot added the L1 Ethereum client label Jun 2, 2026
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Lines of code report

Total lines added: 2289
Total lines removed: 0
Total lines changed: 2289

Detailed view
+-------------------------------------------------------------+-------+------+
| File                                                        | Lines | Diff |
+-------------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/cli.rs                                    | 1283  | +20  |
+-------------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/initializers.rs                           | 800   | +2   |
+-------------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/l2/initializers.rs                        | 394   | +2   |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/blockchain.rs                      | 2765  | +16  |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/mempool.rs                         | 911   | +308 |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/payload.rs                         | 881   | +27  |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/sampling.rs                        | 35    | +35  |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/common/crypto/kzg.rs                          | 392   | +134 |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/common/types/blobs_bundle.rs                  | 566   | +48  |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/connection/handshake.rs   | 499   | +4   |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/connection/server.rs      | 2026  | +496 |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/eth/cells.rs              | 185   | +185 |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/eth/eth72/mod.rs          | 2     | +2   |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/eth/eth72/status.rs       | 39    | +39  |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/eth/eth72/transactions.rs | 360   | +360 |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/eth/mod.rs                | 12    | +2   |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/message.rs                | 532   | +73  |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/rlpx/p2p.rs                    | 321   | +1   |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/p2p/tx_broadcaster.rs              | 322   | +13  |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/engine/blobs.rs                | 677   | +341 |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/engine/fork_choice.rs          | 747   | +180 |
+-------------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/rpc.rs                         | 1381  | +1   |
+-------------------------------------------------------------+-------+------+

@edg-l edg-l force-pushed the feat/l1-eip8070 branch 3 times, most recently from 0b5fd64 to 4114b91 Compare June 9, 2026 14:44
edg-l added 13 commits June 17, 2026 12:13
Add eth/72 protocol: cell_mask announcements, blob-payload elision,
GetCells/Cells (0x14/0x15), provider/sampler blobpool sampling behind
--blob-sampling (default off), and Engine API forkchoiceUpdatedV4
custodyColumns + engine_getBlobsV4. Built on existing EIP-7594 cell proofs.
Address spec divergences found auditing the code against EIP-8070:
- per-node entropy in the provider/sampler decision (was globally
  correlated, breaking the Binomial(D,p) model)
- advertise real cell availability in NewPooledTransactionHashes72 and
  let full-payload providers serve GetCells from stored blobs
- gate the provider path on the announcer signaling full availability
- restrict the C_extra sampling-noise column to provider peers and
  retrigger the 2-provider gate on later announcements
- add --blob-eager-provider for block builders (EIP-8070 N8)

All inert while --blob-sampling is off (default).
verify_cell_kzg_proof_batch_partial's non-c-kzg stub used &str::to_string,
which is not in scope in no_std builds of ethrex-crypto. Use .into() to
match the other KzgError::Unimplemented sites. Fixes the no_std and
levm test builds (which compile ethrex-crypto without c-kzg).
Regenerate the CLI help block for --blob-sampling and
--blob-eager-provider so the 'Verify CLI Help Consistency' check passes.
Builder now materializes elided blob bundles from stored cells (concat
data columns 0..63, or Reed-Solomon recover from >=64) before inclusion,
or skips txs it cannot fully reconstruct. Fixes BlobsBundle version drop
on accumulation (init from fork in PayloadBuildContext, max in AddAssign).
Adds kzg cells_to_blob round-trip + recovery tests, mempool
reconstruct_blobs_bundle tests (full/insufficient/validate), and updates
the over-pack regression test to store real cells so reconstruction
succeeds end-to-end. Resolves clippy lints in reconstruct_blobs_bundle.
engine_getBlobsV4 now emits fixed length-128 blobCells/proofs matrices with
null at every non-requested or unheld index, matching execution-specs PR #2948
(_validate_cells_and_proofs). proofs becomes Vec<Option<Proof>>; cell and proof
are kept in lock-step. Also record that the GetCells/Cells request_id is
confirmed by the EIP-8070 rationale.
eth/72 always elides blob payloads in PooledTransactions; a node not running
the sampler/provider cell-fetch loop receives blob txs it can never reconstruct.
Gate the eth/72 capability (offer + negotiation) on blob_sampling_enabled so
default nodes stay at eth/71 with unchanged full-blob propagation.
Resolves clippy::items-after-test-module (-D warnings) in the L2 lint job:
the c-kzg helper was defined after the #[cfg(test)] mod tests block.
The integration test asserted the old compacted (popcount-length) response;
align it with the sparse length-128 matrix from the F1 fix: value at the
requested+held column, null at every other index for both cells and proofs.
- close blobs_v1 test fn before BlobsV4 test suite (union-merge brace)
- drop unused CELLS_PER_EXT_BLOB import + needless &SECP256K1 borrow in payload_tests
@edg-l edg-l force-pushed the feat/l1-eip8070 branch from 4114b91 to 829a9df Compare June 17, 2026 11:03
- accept exactly 128 hashes (spec §5 "at least 128"): `>=` -> `>` off-by-one
- gate on Amsterdam, not Osaka: getBlobsV4 is an Amsterdam Engine API method
- return `null` per hash pre-fork/while syncing instead of -38005 UnsupportedFork
  (spec §6), mirroring getBlobsV3's established contract
- tests: add blobs_v4_accepts_exactly_max_size; replace pre-Osaka-rejects with
  pre-Amsterdam-returns-null (unit + integration); activate Amsterdam in the
  serving-path test contexts

Length-128 sparse response shape and version-0 -> null entry left as-is
(backed by execution-specs PR #2948 and spec §6 respectively).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Glamsterdam L1 Ethereum client

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant