execution: implement EIP-8037 updates for glamsterdam-devnet-6 - #22122
Merged
Merged
Conversation
…/erigon into worktree-gd6-eip-2780
…devnet-6-fixtures
…/erigon into worktree-gd6-eip-2780
…into worktree-gd6-eip-8038
…into feat/eip-8282-builder-requests
…into worktree-gd6-eip-8282
…into worktree-gd6-eip-8282
taratorio
requested review from
domiwei,
lupin012 and
sudeepdino008
as code owners
July 10, 2026 13:11
yperbasis
approved these changes
Jul 10, 2026
Member
There was a problem hiding this comment.
Reviewed against the devnet-6 pin (EELS tests-glamsterdam-devnet@v6.1.1 = d0338f56, fork amsterdam). The refill/spill model, block accounting, and 7702 delegation rules match the pinned spec, including the handleFrameRevert entry-reservoir restore. Remaining nits, none blocking:
verifyAuthoritieshas no explicitauth.nonce == 2^64-1skip (EELSvalidate_authorizationhas one). The nonce-mismatch check yields the identical skip+refund for every reachable state, so this is spec-parity hygiene; it also avoids the theoreticalSetNoncewrap in step 8.chargeTopLevelFrameGas: on the OOG return,gasRemaining.Statehas already been zeroed by the faileduseMdGas. Benign sincehandleFrameRevertrestores the entry reservoir unconditionally, but returning the pre-charge value would keep the helper self-consistent.- Two boundary paths have no unit pin: (a) depth-0 NEW_ACCOUNT charge OOG with a non-zero reservoir — the receipt must exclude the restored reservoir; (b) value CALL to a dead account with zero reservoir — the spill must be applied before the 63/64 child allowance. I verified (b) on this branch with exact leftover-gas assertions; drop-in test below if useful.
spill-before-63/64 test (drop-in next to TestEIP8038SStore)
// TestCallNewAccountSpillBefore63of64 pins the EIP-8037 charge order for a
// value CALL to a dead account: the NEW_ACCOUNT state charge (spilling into
// regular gas when the reservoir can't cover it) is applied BEFORE the 63/64
// child allowance is computed, per EELS amsterdam call(). With the reverse
// order, a caller forwarding ~all gas would OOG the whole frame on the spill.
//
// Caller bytecode: CALL(gas(), 0xdeadbeef, value=1, no args/ret), store the
// success flag at mem[0], return 32 bytes.
func TestCallNewAccountSpillBefore63of64(t *testing.T) {
callerCode := "0x60006000600060006001" + // PUSH1 0 x4 (retSize retOffset inSize inOffset), PUSH1 1 (value)
"7300000000000000000000000000000000deadbeef" + // PUSH20 callee
"5af1" + // GAS, CALL
"600052" + // PUSH1 0, MSTORE (store success flag)
"60206000f3" // PUSH1 32, PUSH1 0, RETURN
callee := accounts.InternAddress(common.HexToAddress("0x00000000000000000000000000000000deadbeef"))
// Hand-computed (Amsterdam jump table, EELS amsterdam pin):
// pre-CALL opcodes: 5*PUSH1 + PUSH20 + GAS = 20
// CALL constant (warm base) = 100
// cold account access (3000-100) = 2900
// CALL_VALUE (EIP-8038: ACCOUNT_WRITE 8000 + stipend) = 10300
// NEW_ACCOUNT state gas = 183600
// tail: PUSH1, MSTORE(+32B expansion), PUSH1, PUSH1, RET = 15
for _, tt := range []struct {
name string
pool mdgas.MdGas
leftoverRegular uint64
leftoverState uint64
}{
{
// Zero reservoir: the full NEW_ACCOUNT spills into regular gas.
// base for 63/64 = 500000-20-100-2900-10300-183600 = 303080
// callGas = 303080 - 303080/64 = 298345
// child (empty code) returns callGas + 2300 stipend in full;
// leftover = 4735 + 298345 + 2300 - 15 = 305365
name: "zero reservoir, full spill",
pool: mdgas.MdGas{Regular: 500_000, State: 0},
leftoverRegular: 305_365,
leftoverState: 0,
},
{
// Funded reservoir: no spill; 63/64 base = 500000-20-100-13200 = 486680
// callGas = 486680 - 7604 = 479076
// leftover = 7604 + 479076 + 2300 - 15 = 488965
name: "funded reservoir, no spill",
pool: mdgas.MdGas{Regular: 500_000, State: 200_000},
leftoverRegular: 488_965,
leftoverState: 200_000 - 183_600,
},
} {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
tx, sd := testTemporalTxSD(t)
txNum, _, err := sd.SeekCommitment(t.Context(), tx)
require.NoError(t, err)
r, w := state.NewReaderV3(sd.AsGetter(tx)), state.NewWriter(sd.AsPutDel(tx), nil, txNum)
s := state.New(r)
caller := accounts.InternAddress(common.BytesToAddress([]byte("contract")))
s.CreateAccount(caller, true)
s.SetCode(caller, hexutil.MustDecode(callerCode), tracing.CodeChangeUnspecified)
vmctx := evmtypes.BlockContext{
CanTransfer: func(evmtypes.IntraBlockState, accounts.Address, uint256.Int) (bool, error) { return true, nil },
Transfer: func(evmtypes.IntraBlockState, accounts.Address, accounts.Address, uint256.Int, bool, *chain.Rules) error {
return nil
},
}
_ = s.CommitBlock(vmctx.Rules(chain.AllProtocolChanges), w)
vmenv := vm.NewEVM(vmctx, evmtypes.TxContext{}, s, chain.AllProtocolChanges, vm.Config{})
ret, gas, _, err := vmenv.Call(accounts.ZeroAddress, caller, nil, tt.pool, uint256.Int{}, false /* bailout */)
require.NoError(t, err, "outer frame must not OOG: NEW_ACCOUNT spill must precede the 63/64 computation")
require.Len(t, ret, 32)
require.Equal(t, byte(1), ret[31], "inner CALL must succeed")
require.Equal(t, tt.leftoverRegular, gas.Regular, "leftover regular gas")
require.Equal(t, tt.leftoverState, gas.State, "leftover state gas")
exists, err := vmenv.IntraBlockState().Exist(callee)
require.NoError(t, err)
require.True(t, exists, "callee account must have been created")
})
}
}
Member
Author
thanks, addressed:
|
taratorio
enabled auto-merge
July 13, 2026 06:30
Sahil-4555
pushed a commit
to Sahil-4555/erigon
that referenced
this pull request
Jul 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
merge after #22093
closes #22084
ref https://eips.ethereum.org/EIPS/eip-8037