Forward-integration: EIP-7805 (FOCIL) into the EIP-8141 frame-tx base + EIP-8369 overlap - #12772
Forward-integration: EIP-7805 (FOCIL) into the EIP-8141 frame-tx base + EIP-8369 overlap#12772Marchhill wants to merge 262 commits into
Conversation
…focil # Conflicts: # src/Nethermind/Nethermind.Specs/ChainSpecStyle/Json/GethGenesisConfigJson.cs
|
Claude finished @Marchhill's task in 6m 19s —— View job Review: EIP-7805 (FOCIL) → EIP-8141 frame-tx forward-integration
Reviewed the four commits on top of the merge ( Overall this is careful work. The classifier faithfully reuses EIP-8141's existing shape/gas predicates instead of re-deriving them, the budget accounting has no underflow or double-charge path ( Findings below. Nothing Critical or High; four Medium items, mostly around a producer/validator asymmetry and unwired API that the comments claim is wired. Medium1. IL under-fill: EIP-8369 exclusion is applied after reservoir sampling — The reservoir caps candidates at 256 and filters only 2. Producer/validator asymmetry on Profile 2 — The includer admits Profile-2 frame txs into the IL (metered against Within an all-Nethermind devnet that is merely inert. Against a peer implementing plain EIP-7805 with no EIP-8369 notion, it isn't: that peer applies its ordinary appendability check to the frame tx and can reject a block Nethermind accepts. The deferral is documented on the validator side; the fact that the builder keeps emitting entries into that gap is not. Worth an explicit decision — either hold Profile-2 txs out of produced ILs until enforcement lands, or state the interop assumption (every peer implements 8369) in the builder. 3. Validator comment contradicts the code; the API it names is dead — The comment says Profile-2 omission "is checked by bounded validation replay at the builder-claimed index ( 4.
Low5. Two of three documented builder skip reasons are unreachable — 6. Frame-shape walk runs twice per classification — 7. Two tautological tests + a coverage gap — 8. Lock file lost its trailing newline — 9. Things I checked that are fine
I did not run the build or test suites in this environment; the green results reported in the description were not independently verified. · branch |
- InclusionListValidator: the block-gas-fit guard used `block.GasLimit - tx.GasLimit`, which underflows for a ulong `tx.GasLimit` above the block gas limit — the guard was bypassed, so a tx that can never fit was marked appendable and an honest, fully-valid block was falsely rejected as INCLUSION_LIST_UNSATISFIED (weaponizable by an IL member + funded sender). Compare against remaining gas instead (`tx.GasLimit > GasLimit - GasUsed`, underflow-free since GasUsed <= GasLimit and the block-full case already returned). Adds a regression test with GasLimit above the block gas limit. - InclusionListBuilder: dispose the accumulated ArrayPool-backed buffers if EncodePooled throws mid-loop instead of leaking them. - Remove the unused PayloadStatusV1.InclusionListUnsatisfied static. - RecoverSignatures: keep the hot skipErrors==false block-tx path on the inlinable Recover call; only FOCIL IL recovery uses the try/catch wrapper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…Amsterdam) The frames base and FOCIL each introduced an incompatible `Bogota` fork: frames had `Bogota : Osaka` enabling EIP-8141 frame transactions, FOCIL had `Bogota : Amsterdam` enabling EIP-7805 inclusion lists. Reconcile to a single composed model: - Bogota inherits Amsterdam and enables BOTH EIP-8141 frame transactions and EIP-7805 FOCIL inclusion lists (newPayload V6, forkchoiceUpdated V5). - EIP-8141 is deliberately kept off the Amsterdam fork class so Amsterdam's genesis stays byte-identical to both parent branches — enabling it there installs the frame-tx expiry-verifier predeploy at genesis and shifts every Amsterdam newPayloadV5 EIP-7928 BAL consensus test vector. A frames-only devnet instead activates frame txs via the independent eip8141TransitionTimestamp chainspec parameter, staying at Amsterdam / V5. - Remove the frames Osaka-based `Bogota.cs` (superseded). The engine version ladder stays monotonic (Amsterdam -> newPayload V5, Bogota -> V6) with each fork mapped to exactly one newPayload version. ChainSpec-driven networks remain unaffected: EIP-8141 and EIP-7805 are gated by their own transition-timestamp parameters.
…verlap Classifies a transaction into its EIP-8369 FOCIL enforcement profile: - Profile 1: regular non-frame, non-blob txs (legacy/2930/1559/7702). - Profile 2: EIP-8141 frame txs with empty blob_versioned_hashes, one of the four recognized validation-prefix shapes (optional expiry frame ignored for shape matching, no ATOMIC_BATCH_FLAG in the prefix), no VERIFY-mode frame after the prefix, and VERIFY cost within MAX_VERIFY_GAS_PER_TX. - Outside: blob-carrying (incl. blob frame txs), wrong-shape, over-budget. Reuses EIP-8141's frame-shape predicates (exposed via FrameTxValidation.TryGetValidationPrefixLength) and its VERIFY-gas machinery (ValidationWorkGas). Adds Eip8369Constants (MAX_VERIFY_GAS_PER_IL / MAX_VERIFY_GAS_PER_TX = 2^20) and a TBD AA_VOPS_SLOT_COUNT, plus a DefaultClaimedInclusionIndex helper (default = end of payload).
…n lists The includer now meters Profile-2 frame transactions against the per-IL VERIFY budget (MAX_VERIFY_GAS_PER_IL): a Profile-2 tx whose VERIFY cost is uncomputable, exceeds MAX_VERIFY_GAS_PER_TX, or does not fit the remaining budget is skipped consuming nothing; otherwise it is admitted and the cost deducted. Profile-1 txs pass through freely and never consume budget; transactions outside enforcement (blob-carrying / wrong-shape / over-budget frame txs) are excluded from the IL.
The IL omission check now gates on the EIP-8369 profile: Profile-1 txs keep FOCIL's end-of-payload omission check; Profile-2 frame txs are checked at the builder-claimed index (Eip8369.DefaultClaimedInclusionIndex, default = end of payload). The full bounded validation replay against the AA-VOPS state surface (EIP-8250 keyed nonces, EIP-8272 recent roots) is a marked DEFERRAL, so a Profile-2 entry is not treated as a violation here; transactions outside enforcement are never enforced.
676490e to
4149492
Compare
Assert that the Bogota fork label (and geth-genesis bogotaTime) enables both EIP-8141 frames and EIP-7805 FOCIL together, while the independent per-EIP transition timestamps still gate each feature in isolation so existing frames-only devnets stay unaffected.
EIP-8369 Classify resolved the recognized prefix, then ValidationWorkGas re-derived it; thread the length through an internal overload so the frame-shape walk runs once on the includer/validator hot paths.
Remove the never-called DefaultClaimedInclusionIndex and the unconsumed AaVopsSlotCount constant. Correct the validator comment: Profile-2 enforcement (bounded claimed-index replay) is deferred to a future EIP-7805 extension, so Profile-2 and Outside entries never fail here. Replace the two tautological Eip8369 tests with concrete-value checks that also cover signature gas contributing to the VERIFY budget.
EIP-8369 Outside txs (blobs, wrong-shape/over-budget frame txs) were filtered only at encode time, after they had already consumed reservoir slots, under-filling the inclusion list. Classify during sampling so they never take a slot, and simplify the encode-time budget check to the one reachable guard (remaining per-IL VERIFY budget).
|
Merged
EIP-8141 blockchain fixtures from execution-specs#3047 go 73/135 → 59/135. Bisected to #12732, which changed the predeploy install condition from "account code differs from canonical" to "code differs or nonce < predeploy nonce": The EIP-8141 expiry verifier at Isolated on
The EIP-8272 predeploy itself is gated on |
Changes
Forward-integration of EIP-7805 (FOCIL, #8003) into the EIP-8141 frame-transactions base (
eip8141-frame-txs-devnet7), prepared ahead of FOCIL's merge to master so that the conflict-resolution and feature-overlap work is done and reviewable now. Base:eip8141-frame-txs-devnet7. Head:frames-focil.The diff is
FOCIL merged into the frames base+ the commits below. The FOCIL commits themselves are reviewed in #8003 and are not part of this review surface — review the four commits on top of the merge:fork:reconcile the Bogota fork collision — the fork/version model (see below).feat(focil):EIP-8369 Profile classifier (Nethermind.Core/Eip8369.cs) — the overlap classification.feat(focil):EIP-8369 VERIFY-budget fill in the IL includer (InclusionListBuilder).feat(focil):frame-aware IL validator (InclusionListValidator).Fork / version model
Both branches introduced an incompatible
Bogotafork (frames:Bogota : Osakaenabling EIP-8141; FOCIL:Bogota : Amsterdamenabling EIP-7805). Reconciled to a single composed fork:Bogota : Amsterdamenables both EIP-8141 frame transactions and EIP-7805 FOCIL inclusion lists (newPayloadV6/getPayloadV6/forkchoiceUpdatedV5).newPayloadV5, Bogota → V6 — each fork mapped to exactly onenewPayloadversion.eip8141TransitionTimestampchainspec parameter; a Bogota schedule runs V6 + inclusion lists carrying frame txs transparently. Both are covered by tests.Forks/26_Bogota.csthrough theHardforkLabelssource generator, which fansbogota(Parity chainspec) /bogotaTime(geth genesis) out to botheip8141TransitionTimestampandeip7805TransitionTimestamp. No bespokebogotaTimestampparameter was added — that would duplicate and conflict with the generator's existing fan-out, and no other fork (Osaka, Amsterdam) uses a dedicated param. The independent per-EIP params are retained, so existing frames devnets (which activate viaeip8141TransitionTimestamp) are unaffected, and a FOCIL-only schedule (eip7805TransitionTimestamp) stays possible. Regression tests inChainSpecBasedSpecProviderTestsassert all three:bogota/bogotaTime→ both on at/after the boundary and off before;eip8141TransitionTimestampalone → frames on / FOCIL off;eip7805TransitionTimestampalone → FOCIL on / frames off.EIP-8369 overlap (informational; ethereum/EIPs#12110)
Eip8369.Classify): Profile 1 = regular non-frame, non-blob (legacy/2930/1559/7702); Profile 2 = frame tx with emptyblob_versioned_hashes, one of the four recognized validation-prefix shapes (optional expiry frame ignored for shape matching, noATOMIC_BATCH_FLAGin the prefix), no VERIFY-mode frame after the prefix, VERIFY cost ≤MAX_VERIFY_GAS_PER_TX; Outside = blob-carrying / wrong-shape / over-budget. Reuses EIP-8141's frame-shape predicates and verify-gas machinery.MAX_VERIFY_GAS_PER_IL/MAX_VERIFY_GAS_PER_TX= 2²⁰ (distinct from EIP-8141's public-mempoolMAX_VERIFY_GAS= 100_000).InclusionListBuilder): Profile-1 txs pass through freely; Profile-2 txs are metered againstMAX_VERIFY_GAS_PER_IL(uncomputable / over-MAX_VERIFY_GAS_PER_TX/ over-remaining-budget → skipped, consuming nothing); frame txs outside enforcement excluded.InclusionListValidator): Profile-1 keeps FOCIL's end-of-payload omission check; Profile-2 gated to the builder-claimed index (default = end of payload).Marked deferrals
AA_VOPS_SLOT_COUNTvalue — unpinned in the informational EIP (candidate 2–4); pending the Standards-Track EIP-7805 extension + benchmarks. Marked inEip8369Constants.InclusionListValidator.InclusionListValidator.Note
The frames-devnet genesis generator (external) currently emits
bogotaTimeto schedule frame txs; under this model a frames-only devnet should emiteip8141TransitionTimestamp(orbogotaTimefor the combined frames+FOCIL fork). No source change required here.Types of changes
Testing
Requires testing
If yes, did you write tests?
Notes on testing
New:
Eip8369Tests(classifier — each shape, blob frame → Outside, over-budget → Outside, wrong shape → Outside, verify-cost);InclusionListBuilderTestsEIP-8369 cases (budget exhaustion, over-budget/uncomputable skip, Profile-1 not metered);InclusionListValidatorTestsframe-aware cases; updatedForkTests/GethGenesisLoaderTestsfor the reconciled fork model.Green: full solution build 0/0;
Nethermind.Specs.Test,Nethermind.Core.Test,Nethermind.Consensus.Test,Nethermind.Evm.Test(frame suites),Nethermind.Merge.Plugin.Test(FOCILEngineModuleTestsengine-version + BAL),Nethermind.Blockchain.Test. Code-style build (-p:EnforceCodeStyleInBuild=true) clean on touched projects;dotnet format whitespaceclean.Documentation
Requires documentation update
Requires explanation in Release Notes