DEV Community

duongynhi000005-oss
duongynhi000005-oss

Posted on

Lessons from Auditing Ethereum Fusaka (EIP-7594 PeerDAS & EIP-7825) Across 14 EL & CL Clients

Why Multi-Client Differential Auditing Beats Single-Repo Code Review

Ethereum's upcoming Fusaka upgrade (combining the Osaka Execution Layer hardfork and Fulu Consensus Layer hardfork) introduces EIP-7594 (PeerDAS), EIP-7825 (Transaction Gas Limit Cap = 16,777,216), EIP-7883 (ModExp Gas Increase), and EIP-7934 (RLP Execution Block Size Limit).

When you read a single client in isolation, subtle deviations from the specification look intentional. When you compare all 7 Execution Layer clients (go-ethereum, reth, nethermind, besu, erigon, ethereumjs, ethrex) and all 7 Consensus Layer clients (lighthouse, prysm, teku, lodestar, nimbus-eth2, grandine, ethlambda) side by side against the official specification, discrepancies jump out immediately.


Case Study 1: engine_getBlobsV2 Pre-Osaka Error Code & Syncing Checks

According to execution-apis/src/engine/osaka.md#engine_getblobsv2:

  1. Clients MUST return -38005: Unsupported fork if the head block timestamp has not reached Osaka.
  2. Clients MUST return null when syncing.
  3. Clients MUST operate in all-or-nothing mode: if any requested versioned hash is missing or belongs to a v0 sidecar without 128 cell proofs, the entire response must be null.

By building a 7-client conformance matrix, we verified how each client handles > 128 hashes (-38004: Too large request), BlobSidecarVersion1 cell proof counts (CELLS_PER_EXT_BLOB = 128), and pre-Osaka fallback behavior.


Case Study 2: PeerDAS DataColumnSidecar Inclusion Proof & Custody Group Sorting

In specs/fulu/das-core.md:

  • get_custody_groups(node_id, custody_group_count) increments a uint256 counter modularly (UINT256_MAX -> 0), deduplicates group indices modulo NUMBER_OF_CUSTODY_GROUPS (128), and returns sorted(custody_groups).
  • Every DataColumnSidecar gossip message on data_column_sidecar_{subnet_id} must verify both the depth-4 Merkle inclusion proof against signed_block_header.message.body_root (generalized index 27) and the proposer signature before entering fork-choice data availability checks.

Differential matrices turn specification text into deterministic assertions across Go, Rust, C#, Java, Nim, and TypeScript.

Top comments (0)