From eb91018a234174f9568f665401f0aa6b26cbc001 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Wed, 15 Jul 2026 06:47:27 +0000 Subject: [PATCH 01/13] execution: implement EIP-7928 fixes for tests-glamsterdam-devnet@v6.1.1 --- .github/workflows/test-hive-eest.yml | 3 +- db/state/domain.go | 28 ++++----- db/state/history.go | 27 +++++---- db/state/inverted_index.go | 10 ++-- db/state/inverted_index_bench_test.go | 50 ---------------- execution/engineapi/engine_api_bal_test.go | 56 ++++++++++++++++++ execution/engineapi/engine_server.go | 41 ++++++------- execution/execmodule/exec_module.go | 5 +- execution/state/intra_block_state.go | 10 +++- execution/state/versionedio.go | 33 +++++++++-- execution/state/versionedio_test.go | 67 ++++++++++++++++++++++ execution/types/block_access_list.go | 27 +++++---- execution/types/block_access_list_test.go | 67 ++++++++++++++++++++++ execution/vm/operations_acl.go | 13 +++-- tools/eest-spec-shards.yml | 12 ++-- 15 files changed, 314 insertions(+), 135 deletions(-) delete mode 100644 db/state/inverted_index_bench_test.go diff --git a/.github/workflows/test-hive-eest.yml b/.github/workflows/test-hive-eest.yml index c013c800d5b..3510dac740d 100644 --- a/.github/workflows/test-hive-eest.yml +++ b/.github/workflows/test-hive-eest.yml @@ -102,8 +102,7 @@ jobs: fixtures-tarball: eest_devnet extra-hive-flags: "--sim.loglevel=3 --client.checktimelimit=300s" erigon-extra-flags: "--experimental.bal" - # TODO: reduce to 0 (glamsterdam-devnet-6 EIPs WIP) - max-failures: 7 + max-failures: 0 exec_mode: parallel steps: - name: Clean docker system diff --git a/db/state/domain.go b/db/state/domain.go index 16228d645c1..73dba922168 100644 --- a/db/state/domain.go +++ b/db/state/domain.go @@ -567,12 +567,13 @@ func (w *DomainBufferedWriter) addValue(k, value []byte, step kv.Step) error { // DomainRoTx allows accesing the same domain from multiple go-routines type DomainRoTx struct { - files visibleFiles - visible *domainVisible - name kv.Domain - stepSize uint64 - ht *HistoryRoTx - salt *uint32 + files visibleFiles + visible *domainVisible + name kv.Domain + stepSize uint64 + stepsInFrozenFile uint64 + ht *HistoryRoTx + salt *uint32 d *Domain @@ -644,13 +645,14 @@ func (d *Domain) beginForTests() *DomainRoTx { // aggregatorVisible generation, avoiding a torn cross-entity read func (d *Domain) beginFilesRo(dv *domainVisible, hf visibleFiles, hiv *iiVisible) *DomainRoTx { return &DomainRoTx{ - name: d.Name, - stepSize: d.stepSize, - d: d, - ht: d.History.beginFilesRo(hf, hiv), - visible: dv, - files: dv.files, - salt: d.salt.Load(), + name: d.Name, + stepSize: d.stepSize, + stepsInFrozenFile: d.stepsInFrozenFile, + d: d, + ht: d.History.beginFilesRo(hf, hiv), + visible: dv, + files: dv.files, + salt: d.salt.Load(), } } diff --git a/db/state/history.go b/db/state/history.go index 8742111aa4e..e6ad99195d1 100644 --- a/db/state/history.go +++ b/db/state/history.go @@ -905,16 +905,19 @@ type HistoryRoTx struct { h *History iit *InvertedIndexRoTx - files visibleFiles // have no garbage (canDelete=true, overlaps, etc...) - getters []*seg.Reader - readers []*recsplit.IndexReader - stepSize uint64 + files visibleFiles // have no garbage (canDelete=true, overlaps, etc...) + getters []*seg.Reader + readers []*recsplit.IndexReader + stepSize uint64 + stepsInFrozenFile uint64 + + trace bool valsC kv.Cursor valsCDup kv.CursorDupSort - _bufTs []byte - blockCompressionBuf []byte + _bufTs []byte + snappyReadBuffer []byte } func (h *History) beginForTests() *HistoryRoTx { @@ -932,10 +935,12 @@ func (h *History) BeginFilesRoForDebug() *HistoryRoTx { func (h *History) beginFilesRo(files visibleFiles, iv *iiVisible) *HistoryRoTx { return &HistoryRoTx{ - h: h, - iit: h.InvertedIndex.beginFilesRo(iv), - files: files, - stepSize: h.stepSize, + h: h, + iit: h.InvertedIndex.beginFilesRo(iv), + files: files, + stepSize: h.stepSize, + stepsInFrozenFile: h.stepsInFrozenFile, + trace: false, } } @@ -1183,7 +1188,7 @@ func (ht *HistoryRoTx) historySeekInFiles(key []byte, txNum uint64) ([]byte, boo } if compressedPageValuesCount > 1 { - v, ht.blockCompressionBuf = seg.GetFromPage(historyKey, v, ht.blockCompressionBuf, true) + v, ht.snappyReadBuffer = seg.GetFromPage(historyKey, v, ht.snappyReadBuffer, true) } return v, true, nil } diff --git a/db/state/inverted_index.go b/db/state/inverted_index.go index 193d233996b..bbac3994125 100644 --- a/db/state/inverted_index.go +++ b/db/state/inverted_index.go @@ -472,9 +472,13 @@ type InvertedIndexRoTx struct { seekInFilesCache *IISeekInFilesCache + // TODO: retrofit recent optimization in main and reenable the next line + // ef *multiencseq.SequenceBuilder // re-usable salt *uint32 stepSize uint64 stepsInFrozenFile uint64 + + reUsableSeq multiencseq.SequenceReader // re-usable instance, to reduce allocations } // hashKey - change of salt will require re-gen of indices @@ -518,8 +522,6 @@ func (iit *InvertedIndexRoTx) seekInFiles(key []byte, txNum uint64) (found bool, return false, 0, nil } - var seq multiencseq.SequenceReader - hi, lo := iit.hashKey(key) if iit.seekInFilesCache == nil { iit.seekInFilesCache = iit.visible.newSeekInFilesCache() @@ -556,8 +558,8 @@ func (iit *InvertedIndexRoTx) seekInFiles(key []byte, txNum uint64) (found bool, } encodedSeq, _ := g.Next(nil) - seq.Reset(iit.files[i].startTxNum, encodedSeq) - equalOrHigherTxNum, _, found = seq.Seek(txNum) + iit.reUsableSeq.Reset(iit.files[i].startTxNum, encodedSeq) + equalOrHigherTxNum, _, found = iit.reUsableSeq.Seek(txNum) if !found { continue } diff --git a/db/state/inverted_index_bench_test.go b/db/state/inverted_index_bench_test.go deleted file mode 100644 index 9b83baa37fd..00000000000 --- a/db/state/inverted_index_bench_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package state - -import ( - "encoding/binary" - "testing" - - "github.com/erigontech/erigon/common/background" - "github.com/erigontech/erigon/common/log/v3" - "github.com/erigontech/erigon/db/kv" -) - -// BenchmarkInvertedIndexSeekInFiles measures the per-seek cost of the file-scan path. -// Run with II_LRU_ENABLED=false to bypass the seek cache, otherwise the cache short-circuits -// before the sequence decoding this is meant to measure. -func BenchmarkInvertedIndexSeekInFiles(b *testing.B) { - logger := log.New() - db, ii, txs := filledInvIndexOfSize(b, 1000, 16, 31, logger) - ctx := b.Context() - - tx, err := db.BeginRw(ctx) - if err != nil { - b.Fatal(err) - } - defer tx.Rollback() - for step := kv.Step(0); step < kv.Step(txs/ii.stepSize)-1; step++ { - if err := ii.collateBuildIntegrate(ctx, step, tx, background.NewProgressSet()); err != nil { - b.Fatal(err) - } - } - - iit := ii.beginForTests() - defer iit.Close() - if len(iit.files) == 0 { - b.Fatal("no visible files: benchmark would not reach the seek path") - } - - keys := make([][8]byte, 31) - for i := range keys { - binary.BigEndian.PutUint64(keys[i][:], uint64(i+1)) - } - - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - k := keys[i%len(keys)] - if _, _, err := iit.seekInFiles(k[:], uint64(i%900)); err != nil { - b.Fatal(err) - } - } -} diff --git a/execution/engineapi/engine_api_bal_test.go b/execution/engineapi/engine_api_bal_test.go index 5a4c02f490b..36cdda27c61 100644 --- a/execution/engineapi/engine_api_bal_test.go +++ b/execution/engineapi/engine_api_bal_test.go @@ -29,9 +29,11 @@ import ( "github.com/erigontech/erigon/common" "github.com/erigontech/erigon/common/crypto" "github.com/erigontech/erigon/common/dbg" + "github.com/erigontech/erigon/common/hexutil" "github.com/erigontech/erigon/common/log/v3" "github.com/erigontech/erigon/common/testlog" "github.com/erigontech/erigon/execution/abi/bind" + enginetypes "github.com/erigontech/erigon/execution/engineapi/engine_types" "github.com/erigontech/erigon/execution/engineapi/engineapitester" "github.com/erigontech/erigon/execution/protocol/params" stateContracts "github.com/erigontech/erigon/execution/state/contracts" @@ -1141,3 +1143,57 @@ func findStorageChange(sc *types.SlotChanges, index uint32) *types.StorageChange } return nil } + +// TestEngineApiNewPayloadBALMalformedVsInvalid pins the EIP-7928 newPayload +// error split: a blockAccessList param that is not decodable RLP is a +// malformed request (-32602 invalid params), while a decodable one that +// violates EIP-7928 ordering rules is an invalid block ({status: INVALID}). +func TestEngineApiNewPayloadBALMalformedVsInvalid(t *testing.T) { + if !dbg.Exec3Parallel { + t.Skip("requires parallel exec") + } + ctx := t.Context() + logger := testlog.Logger(t, log.LvlDebug) + eat, err := engineapitester.DefaultEngineApiTester(ctx, logger, t.TempDir()) + require.NoError(t, err) + t.Cleanup(func() { + err := eat.Close() + require.NoError(t, err) + }) + receiver := common.HexToAddress("0x333") + eat.Run(t, func(ctx context.Context, t *testing.T, eat engineapitester.EngineApiTester) { + _, err := eat.Transactor.SubmitSimpleTransfer(eat.CoinbaseKey, receiver, big.NewInt(1)) + require.NoError(t, err) + payload, err := eat.MockCl.BuildCanonicalBlock(ctx) + require.NoError(t, err) + executionRequests := payload.ExecutionRequests + if executionRequests == nil { + executionRequests = []hexutil.Bytes{} + } + sendWithBAL := func(bal hexutil.Bytes) (*enginetypes.PayloadStatus, error) { + elPayload := *payload.ExecutionPayload + elPayload.BlockAccessList = &bal + return eat.EngineApiClient.NewPayloadV5(ctx, &elPayload, []common.Hash{}, payload.ParentBeaconBlockRoot, executionRequests) + } + for name, malformed := range map[string]hexutil.Bytes{ + "empty byte string": {}, + "string not list": {0x80}, + "truncated list": {0xc1}, + } { + _, err := sendWithBAL(malformed) + require.Errorf(t, err, "%s: expected invalid-params error", name) + var rpcErr rpc.Error + require.ErrorAsf(t, err, &rpcErr, "%s: expected rpc error, got: %v", name, err) + require.Equalf(t, -32602, rpcErr.ErrorCode(), "%s: %v", name, err) + } + account := append([]byte{0xda, 0x94}, make([]byte, 20)...) + account = append(account, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0) + duplicateAccounts := make([]byte, 0, 1+2*len(account)) + duplicateAccounts = append(duplicateAccounts, 0xc0+byte(2*len(account))) + duplicateAccounts = append(duplicateAccounts, account...) + duplicateAccounts = append(duplicateAccounts, account...) + status, err := sendWithBAL(duplicateAccounts) + require.NoError(t, err) + require.Equal(t, enginetypes.InvalidStatus, status.Status) + }) +} diff --git a/execution/engineapi/engine_server.go b/execution/engineapi/engine_server.go index bcd56908223..05ad9f04e4c 100644 --- a/execution/engineapi/engine_server.go +++ b/execution/engineapi/engine_server.go @@ -367,39 +367,36 @@ func (s *EngineServer) newPayload(ctx context.Context, req *engine_types.Executi return nil, &rpc.InvalidParamsError{Message: "blockAccessList missing"} } bal := *req.BlockAccessList - if len(bal) == 0 { - blockAccessList = make(types.BlockAccessList, 0) - hash := empty.BlockAccessListHash - header.BlockAccessListHash = &hash - blockAccessListBytes, err = types.EncodeBlockAccessListBytes(blockAccessList) - if err != nil { - return nil, &rpc.InvalidParamsError{Message: fmt.Sprintf("encode empty blockAccessList: %v", err)} - } - } else { - blockAccessList, err = types.DecodeBlockAccessListBytes(bal) - if err != nil { - s.logger.Debug("[NewPayload] failed to decode blockAccessList", "err", err, "raw", hex.EncodeToString(bal)) - return &engine_types.PayloadStatus{ - Status: engine_types.InvalidStatus, - ValidationError: engine_types.NewStringifiedErrorFromString(fmt.Sprintf("invalid block access list decode: %v", err)), - }, nil - } - if err := blockAccessList.Validate(); err != nil { + blockAccessList, err = types.DecodeBlockAccessListBytes(bal) + if err != nil { + s.logger.Debug("[NewPayload] failed to decode blockAccessList", "err", err, "raw", hex.EncodeToString(bal)) + // A decodable list that violates EIP-7928 rules is an invalid + // block; undecodable bytes are a malformed request (-32602). + if errors.Is(err, types.ErrInvalidBlockAccessList) { return &engine_types.PayloadStatus{ Status: engine_types.InvalidStatus, - ValidationError: engine_types.NewStringifiedErrorFromString(fmt.Sprintf("invalid block access list validate: %v", err)), + ValidationError: engine_types.NewStringifiedErrorFromString(err.Error()), }, nil } - hash := crypto.HashData(bal) - header.BlockAccessListHash = &hash - blockAccessListBytes = bal + return nil, &rpc.InvalidParamsError{Message: fmt.Sprintf("undecodable blockAccessList: %v", err)} + } + if err := blockAccessList.Validate(); err != nil { + return &engine_types.PayloadStatus{ + Status: engine_types.InvalidStatus, + ValidationError: engine_types.NewStringifiedErrorFromString(fmt.Sprintf("invalid block access list validate: %v", err)), + }, nil } + hash := crypto.HashData(bal) + header.BlockAccessListHash = &hash + blockAccessListBytes = bal if req.SlotNumber != nil { slotNumber := uint64(*req.SlotNumber) header.SlotNumber = &slotNumber } else { return nil, &rpc.InvalidParamsError{Message: "slotNumber missing"} } + } else if req.BlockAccessList != nil && len(*req.BlockAccessList) > 0 { + return nil, &rpc.InvalidParamsError{Message: "unexpected blockAccessList in pre-Amsterdam payload"} } if (!s.config.IsCancun(header.Time) && version >= clparams.DenebVersion) || diff --git a/execution/execmodule/exec_module.go b/execution/execmodule/exec_module.go index 6bf8ed4f6c7..72ab0d19b9e 100644 --- a/execution/execmodule/exec_module.go +++ b/execution/execmodule/exec_module.go @@ -759,15 +759,14 @@ func (e *ExecModule) HasBlock(ctx context.Context, blockHash *common.Hash, _ *ui if *num <= e.blockReader.FrozenBlocks() { return true, nil } - dbKey := dbutils.HeaderKey(*num, *blockHash) - has, err := tx.Has(kv.Headers, dbKey) + has, err := tx.Has(kv.Headers, dbutils.HeaderKey(*num, *blockHash)) if err != nil { return false, err } if !has { return false, nil } - has, err = tx.Has(kv.BlockBody, dbKey) + has, err = tx.Has(kv.BlockBody, dbutils.HeaderKey(*num, *blockHash)) if err != nil { return false, err } diff --git a/execution/state/intra_block_state.go b/execution/state/intra_block_state.go index 5e38490c370..ba98c815edc 100644 --- a/execution/state/intra_block_state.go +++ b/execution/state/intra_block_state.go @@ -1925,10 +1925,16 @@ func (sdb *IntraBlockState) CreateAccount(addr accounts.Address, contractCreatio } // for newly created accounts these synthetic read/writes are used so that account - // creation clashes between trnascations get detected + // creation clashes between transactions get detected. Only record the BalancePath + // read on the first creation of this account in the tx: a re-creation (e.g. CREATE2 + // to an address funded and created earlier in the same tx) carries the live + // post-transfer balance, and overwriting the first read's pre-tx value with it would + // seed a wrong block-access-list baseline and drop the real balance change. sdb.MarkAddressAccess(addr, true) if sdb.versionMap != nil { - sdb.versionedReads.SetBalance(addr, VersionedRead[uint256.Int]{ReadHeader{Source: balSource, Version: balVersion}, newObj.Balance()}) + if _, seen := sdb.versionedReads.GetBalance(addr); !seen { + sdb.versionedReads.SetBalance(addr, VersionedRead[uint256.Int]{ReadHeader{Source: balSource, Version: balVersion}, newObj.Balance()}) + } sdb.versionedReads.SetIncarnation(addr, VersionedRead[uint64]{ReadHeader{Source: incSource, Version: incVersion}, prevInc}) } sdb.recordWriteBalance(addr, newObj.Balance()) diff --git a/execution/state/versionedio.go b/execution/state/versionedio.go index 716f17b8620..1b9b9c43d22 100644 --- a/execution/state/versionedio.go +++ b/execution/state/versionedio.go @@ -2239,7 +2239,13 @@ func (io *VersionedIO) AsBlockAccessList() types.BlockAccessList { if addr.IsNil() || tr.internal { continue } - ensureAccountState(ac, addr) + account := ensureAccountState(ac, addr) + // An empty pre-block code hash means pre-block code was empty, so a same-tx + // code set-then-clear (e.g. an EIP-7702 delegation set then cleared) nets to + // empty and must not be recorded as a code change (see applyToCode). + if tr.Val == accounts.EmptyCodeHash || tr.Val == (accounts.CodeHash{}) { + account.initialCodeEmpty = true + } } for addr, tr := range rs.codeSize { if addr.IsNil() || tr.internal { @@ -2291,8 +2297,14 @@ func (io *VersionedIO) AsBlockAccessList() types.BlockAccessList { // codeSize/address) and can't silently miss a future path — the repeat // ensureAccountState is a harmless get-or-create. for addr := range writes.addrs() { - if !addr.IsNil() { - ensureAccountState(ac, addr) + if addr.IsNil() { + continue + } + account := ensureAccountState(ac, addr) + // A contract created this block did not exist pre-block, so its pre-block + // code is empty; applyToCode uses this to drop a net-zero empty code change. + if vw, ok := writes.GetCreateContract(addr); ok && vw.Val { + account.initialCodeEmpty = true } } } @@ -2358,13 +2370,14 @@ type accountState struct { initialBalanceValue *uint256.Int // tracks pre-block balance for net-zero detection storageReadValues map[accounts.StorageKey]uint256.Int // original read values for net-zero detection nonRevertableUserAccess bool // true if a user tx (txIndex >= 0) has non-revertable access + initialCodeEmpty bool // pre-block code was empty (created contract or empty-codehash read) } // check pre- and post-values, add to BAL if different func (a *accountState) finalize() { applyToBalance(a.balance, a.changes, a.initialBalanceValue) applyToNonce(a.nonce, a.changes) - applyToCode(a.code, a.changes) + applyToCode(a.code, a.changes, a.initialCodeEmpty) } type fieldTracker[T any] struct { @@ -2417,8 +2430,18 @@ func newCodeTracker() *fieldTracker[accounts.Code] { return &fieldTracker[accounts.Code]{} } -func applyToCode(ct *fieldTracker[accounts.Code], ac *types.AccountChanges) { +func applyToCode(ct *fieldTracker[accounts.Code], ac *types.AccountChanges, initialCodeEmpty bool) { + // A first code change back to empty when pre-block code was already empty + // (e.g. an EIP-7702 delegation set then cleared in the same tx) is a net-zero + // change and is omitted, matching EELS's post-vs-pre code-hash diff. + firstFiltered := false ct.changes.apply(func(idx uint32, value accounts.Code) { + if !firstFiltered { + firstFiltered = true + if initialCodeEmpty && len(value.Bytes) == 0 { + return + } + } ac.CodeChanges = append(ac.CodeChanges, &types.CodeChange{ Index: idx, Bytecode: bytes.Clone(value.Bytes), diff --git a/execution/state/versionedio_test.go b/execution/state/versionedio_test.go index 71bd1004c5b..617b3968835 100644 --- a/execution/state/versionedio_test.go +++ b/execution/state/versionedio_test.go @@ -479,6 +479,73 @@ func TestVersionedIO_PostWriteBalanceReadDoesNotPoisonInitialBalance(t *testing. require.True(t, found, "burn target address must appear in BAL") } +// TestCreateAccount_FundedThenCreated_SyntheticReadKeepsPreTxBalance is the +// regression test for the eip7997 factory_deploys_to_pre_funded_address BAL +// mismatch. A value transfer creates and funds an address (balance 0 -> 1), then +// a CREATE2 deploys a contract at that same address in the same tx. CreateAccount +// records a synthetic BalancePath read for conflict detection; it must only be +// recorded on the first creation, keeping the pre-tx balance (0). Re-recording it +// on the CREATE2 would capture the live funded balance (1) and seed a wrong +// block-access-list baseline, dropping the real 0 -> 1 change as a net-zero no-op. +func TestCreateAccount_FundedThenCreated_SyntheticReadKeepsPreTxBalance(t *testing.T) { + t.Parallel() + + ibs := New(&minimalStateReader{}) + ibs.SetVersionMap(NewVersionMap(nil)) + ibs.SetTxContext(1, 0) + ibs.SetVersion(0) + + addr := accounts.InternAddress(common.HexToAddress("0xf11577")) + require.NoError(t, ibs.CreateAccount(addr, false)) // value transfer creates the recipient + require.NoError(t, ibs.AddBalance(addr, *uint256.NewInt(1), tracing.BalanceChangeTransfer)) // funds it 0 -> 1 + require.NoError(t, ibs.CreateAccount(addr, true)) // CREATE2 deploys the contract + + rs := ibs.VersionedReads() + vr, ok := rs.GetBalance(addr) + require.True(t, ok, "a synthetic BalancePath read must be recorded for the created account") + require.True(t, vr.Val.IsZero(), + "the synthetic creation BalancePath read must keep the pre-tx balance (0); the CREATE2 re-creation must not overwrite it with the in-tx funded balance") +} + +// TestVersionedIO_CreatedAccountEmptyCodeChangeOmitted is the regression test +// for the eip8037 same_tx_create_then_clear_double_auth_base_refill BAL +// mismatch. An EIP-7702 authority that did not exist pre-block (nil AddressPath +// read, empty pre-block code) has a delegation set then cleared in the same tx, +// so its net code write is empty. Per EIP-7928 a code change is recorded only +// when the post-tx code hash differs from the pre-tx one; empty -> empty is not +// a change and must be omitted. The nonce bump (0 -> 2) is a real change. +func TestVersionedIO_CreatedAccountEmptyCodeChangeOmitted(t *testing.T) { + t.Parallel() + + addr := accounts.InternAddress(common.HexToAddress("0xc0f6dc9")) + + io := NewVersionedIO(1) + + // The authority did not exist pre-block: its CodeHash reads as empty. + reads := ReadSet{} + reads.SetCodeHash(addr, VersionedRead[accounts.CodeHash]{Val: accounts.EmptyCodeHash}) + io.RecordReads(Version{TxIndex: 0}, reads) + + io.RecordWrites(Version{TxIndex: 0}, newWriteSet( + &VersionedWrite[uint64]{WriteHeader: WriteHeader{Address: addr, Path: NoncePath, Version: Version{TxIndex: 0}}, Val: uint64(2)}, + &VersionedWrite[accounts.Code]{WriteHeader: WriteHeader{Address: addr, Path: CodePath, Version: Version{TxIndex: 0}}, Val: accounts.Code{}}, + )) + + bal := io.AsBlockAccessList() + + found := false + for _, ac := range bal { + if ac.Address == addr { + found = true + require.Empty(t, ac.CodeChanges, + "a delegation set then cleared in the same tx nets to empty code; pre-block code of an absent account is empty, so no code change must be recorded\n%s", bal.DebugString()) + require.Len(t, ac.NonceChanges, 1, "the nonce bump must be recorded") + require.Equal(t, uint64(2), ac.NonceChanges[0].Value) + } + } + require.True(t, found, "authority account must appear in BAL") +} + // TestVersionedIO_StorageNoOpWriteAfterChangeOmittedFromBAL verifies the // EIP-7928 rule that, for a slot written multiple times in a block, a write // storing the value an earlier write already set is a no-op and must be diff --git a/execution/types/block_access_list.go b/execution/types/block_access_list.go index 0827d11acfe..f13f3d4a7f9 100644 --- a/execution/types/block_access_list.go +++ b/execution/types/block_access_list.go @@ -176,7 +176,7 @@ func (ac *AccountChanges) DecodeRLP(s *rlp.Stream) error { ac.CodeChanges = codes if err := ac.validate(); err != nil { - return err + return fmt.Errorf("%w: %w", ErrInvalidBlockAccessList, err) } return s.ListEnd() @@ -512,6 +512,11 @@ func encodingSizeHashList(hashes []accounts.StorageKey) int { return rlp.ListPrefixLen(size) + size } +// ErrInvalidBlockAccessList marks a block access list that is well-formed RLP +// but violates EIP-7928 ordering or uniqueness rules. Callers use it to +// distinguish an invalid list from undecodable input. +var ErrInvalidBlockAccessList = errors.New("invalid block access list") + func decodeBlockAccessList(out *BlockAccessList, s *rlp.Stream) error { var err error var size uint64 @@ -538,7 +543,7 @@ func decodeBlockAccessList(out *BlockAccessList, s *rlp.Stream) error { } address := ac.Address.Value() if hasPrev && bytes.Compare(prevAddr[:], address[:]) >= 0 { - err = fmt.Errorf("block access list addresses must be strictly increasing (prev=%s current=%s)", prevAddr.Hex(), address.Hex()) + err = fmt.Errorf("%w: addresses must be strictly increasing (prev=%s current=%s)", ErrInvalidBlockAccessList, prevAddr.Hex(), address.Hex()) break } acCopy := ac @@ -609,7 +614,7 @@ func decodeSlotChangesList(s *rlp.Stream) ([]*SlotChanges, error) { } slot := sc.Slot.Value() if hasPrev && bytes.Compare(prevSlot[:], slot[:]) >= 0 { - err = fmt.Errorf("storage slot list must be strictly increasing (prev=%x current=%x)", prevSlot, sc.Slot) + err = fmt.Errorf("%w: storage slot list must be strictly increasing (prev=%x current=%x)", ErrInvalidBlockAccessList, prevSlot, sc.Slot) break } out = append(out, sc) @@ -624,7 +629,7 @@ func decodeSlotChangesList(s *rlp.Stream) ([]*SlotChanges, error) { return nil, err } if err := validateSlotChangeList(out); err != nil { - return nil, err + return nil, fmt.Errorf("%w: %w", ErrInvalidBlockAccessList, err) } return out, nil } @@ -653,7 +658,7 @@ func decodeStorageChanges(s *rlp.Stream) ([]*StorageChange, error) { return nil, err } if err := validateStorageChangeEntries(out); err != nil { - return nil, err + return nil, fmt.Errorf("%w: %w", ErrInvalidBlockAccessList, err) } return out, nil } @@ -682,7 +687,7 @@ func decodeBalanceChanges(s *rlp.Stream) ([]*BalanceChange, error) { return nil, err } if err := validateBalanceChangeList(out); err != nil { - return nil, err + return nil, fmt.Errorf("%w: %w", ErrInvalidBlockAccessList, err) } return out, nil } @@ -704,7 +709,7 @@ func decodeNonceChanges(s *rlp.Stream) ([]*NonceChange, error) { break } if hasLast && change.Index <= lastIdx { - err = fmt.Errorf("nonce change indices must be strictly increasing (prev=%d current=%d)", lastIdx, change.Index) + err = fmt.Errorf("%w: nonce change indices must be strictly increasing (prev=%d current=%d)", ErrInvalidBlockAccessList, lastIdx, change.Index) break } out = append(out, change) @@ -719,7 +724,7 @@ func decodeNonceChanges(s *rlp.Stream) ([]*NonceChange, error) { return nil, err } if err := validateNonceChangeList(out); err != nil { - return nil, err + return nil, fmt.Errorf("%w: %w", ErrInvalidBlockAccessList, err) } return out, nil } @@ -746,7 +751,7 @@ func decodeCodeChanges(s *rlp.Stream) ([]*CodeChange, error) { break } if hasLast && change.Index <= lastIdx { - err = fmt.Errorf("code change indices must be strictly increasing (prev=%d current=%d)", lastIdx, change.Index) + err = fmt.Errorf("%w: code change indices must be strictly increasing (prev=%d current=%d)", ErrInvalidBlockAccessList, lastIdx, change.Index) break } lastIdx = change.Index @@ -756,7 +761,7 @@ func decodeCodeChanges(s *rlp.Stream) ([]*CodeChange, error) { return nil, err } if err := validateCodeChangeList(out); err != nil { - return nil, err + return nil, fmt.Errorf("%w: %w", ErrInvalidBlockAccessList, err) } return out, nil } @@ -790,7 +795,7 @@ func decodeStorageKeys(s *rlp.Stream) ([]accounts.StorageKey, error) { return nil, err } if err := validateStorageReads(hashes); err != nil { - return nil, err + return nil, fmt.Errorf("%w: %w", ErrInvalidBlockAccessList, err) } return hashes, nil } diff --git a/execution/types/block_access_list_test.go b/execution/types/block_access_list_test.go index 8901ae1e7c4..fa7c04577ee 100644 --- a/execution/types/block_access_list_test.go +++ b/execution/types/block_access_list_test.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "errors" "reflect" "strings" "testing" @@ -245,3 +246,69 @@ func TestBlockAccessListRejectsEmptySlotChanges(t *testing.T) { t.Fatalf("expected 'empty slot changes' error, but got: %v", err) } } + +// balTestAccountRLP hand-encodes a minimal AccountChanges entry: a 20-byte +// address whose last byte is lastAddrByte, followed by five empty change/read +// lists (storage changes, storage reads, balance, nonce, code changes). +func balTestAccountRLP(lastAddrByte byte) []byte { + acc := []byte{0xda, 0x94} + addr := make([]byte, 20) + addr[19] = lastAddrByte + acc = append(acc, addr...) + return append(acc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0) +} + +func balTestWrapList(items ...[]byte) []byte { + var content []byte + for _, item := range items { + content = append(content, item...) + } + if len(content) >= 56 { + panic("balTestWrapList supports short lists only") + } + return append([]byte{0xc0 + byte(len(content))}, content...) +} + +func TestDecodeBlockAccessListBytesMalformedVsInvalid(t *testing.T) { + valid, err := DecodeBlockAccessListBytes(balTestWrapList(balTestAccountRLP(1), balTestAccountRLP(2))) + if err != nil { + t.Fatalf("valid two-account list: %v", err) + } + if len(valid) != 2 { + t.Fatalf("valid two-account list: got %d accounts, want 2", len(valid)) + } + emptyBal, err := DecodeBlockAccessListBytes([]byte{0xc0}) + if err != nil || emptyBal == nil || len(emptyBal) != 0 { + t.Fatalf("empty list: bal=%v err=%v", emptyBal, err) + } + malformed := map[string][]byte{ + "empty input": {}, + "string not list": {0x80}, + "truncated list": {0xc1}, + } + for name, data := range malformed { + _, err := DecodeBlockAccessListBytes(data) + if err == nil { + t.Fatalf("%s: expected error", name) + } + if errors.Is(err, ErrInvalidBlockAccessList) { + t.Fatalf("%s: malformed RLP must not map to ErrInvalidBlockAccessList: %v", name, err) + } + } + emptySlotChanges := append([]byte{0xdd, 0x94}, make([]byte, 20)...) + emptySlotChanges = append(emptySlotChanges, 0xc3, 0xc2, 0x01, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0) + semanticallyInvalid := map[string][]byte{ + "duplicate address": balTestWrapList(balTestAccountRLP(1), balTestAccountRLP(1)), + "descending address": balTestWrapList(balTestAccountRLP(2), balTestAccountRLP(1)), + "empty slot changes": balTestWrapList(emptySlotChanges), + } + for name, data := range semanticallyInvalid { + _, err := DecodeBlockAccessListBytes(data) + if err == nil { + t.Fatalf("%s: expected error", name) + } + if !errors.Is(err, ErrInvalidBlockAccessList) { + t.Fatalf("%s: expected ErrInvalidBlockAccessList, got: %v", name, err) + } + } +} diff --git a/execution/vm/operations_acl.go b/execution/vm/operations_acl.go index cdd7307778e..5b7507079bf 100644 --- a/execution/vm/operations_acl.go +++ b/execution/vm/operations_acl.go @@ -60,15 +60,20 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc { slot := callContext.peekStorageKey() access := params.WarmStorageReadCostEIP2929 - if _, slotMod := evm.IntraBlockState().AddSlotToAccessList(callContext.Address(), slot); slotMod { + _, slotMod := evm.IntraBlockState().AddSlotToAccessList(callContext.Address(), slot) + if slotMod { access = coldAccess - if callContext.gas < access { - return mdgas.MdGas{}, ErrOutOfGas - } } var value uint256.Int value.Set(callContext.Stack.Back(1)) + // Read the current slot value before the cold-access affordability check + // so an SSTORE that clears the EIP-2200 sentry but then OOGs on the + // access cost still records the slot read in the EIP-7928 block access + // list, matching EELS sstore where get_storage precedes charge_gas. current, _ := evm.IntraBlockState().GetState(callContext.Address(), slot) + if slotMod && callContext.gas < access { + return mdgas.MdGas{}, ErrOutOfGas + } if current.Eq(&value) { // noop (1) return mdgas.MdGas{Regular: access}, nil diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index 18edbb5b5fa..8d3d3101c49 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -48,8 +48,7 @@ exec3-parallel: true - shard: blocktests-devnet workers: 12 - # TODO: reduce to 0 (glamsterdam-devnet-6 EIPs WIP) - max-allowed-failures: 3 + max-allowed-failures: 0 exec3-parallel: true - shard: enginextests-stable-sequential workers: 8 @@ -123,8 +122,7 @@ no-ramdisk: true - shard: zkevm-witness workers: 8 - # TODO: reduce to 0 (glamsterdam-devnet-6 EIPs WIP) - max-allowed-failures: 3 + max-allowed-failures: 0 - shard: blocktests-stable-race-pre-cancun-sequential workers: 12 max-allowed-failures: 0 @@ -163,11 +161,9 @@ run: 'fork_(Osaka|BPO)' - shard: blocktests-devnet-race-amsterdam workers: 12 - # TODO: reduce to 0 (glamsterdam-devnet-6 EIPs WIP) - max-allowed-failures: 3 + max-allowed-failures: 0 exec3-parallel: true run: 'fork_Amsterdam' - shard: zkevm-witness-race workers: 8 - # TODO: reduce to 0 (glamsterdam-devnet-6 EIPs WIP) - max-allowed-failures: 3 + max-allowed-failures: 0 From 6a571a560930a7485b4f8d45b61426f5b3dda9bb Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Wed, 15 Jul 2026 07:24:42 +0000 Subject: [PATCH 02/13] fix --- db/state/domain.go | 28 +++++++-------- db/state/history.go | 27 ++++++--------- db/state/inverted_index.go | 10 +++--- db/state/inverted_index_bench_test.go | 50 +++++++++++++++++++++++++++ execution/execmodule/exec_module.go | 5 +-- 5 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 db/state/inverted_index_bench_test.go diff --git a/db/state/domain.go b/db/state/domain.go index 73dba922168..16228d645c1 100644 --- a/db/state/domain.go +++ b/db/state/domain.go @@ -567,13 +567,12 @@ func (w *DomainBufferedWriter) addValue(k, value []byte, step kv.Step) error { // DomainRoTx allows accesing the same domain from multiple go-routines type DomainRoTx struct { - files visibleFiles - visible *domainVisible - name kv.Domain - stepSize uint64 - stepsInFrozenFile uint64 - ht *HistoryRoTx - salt *uint32 + files visibleFiles + visible *domainVisible + name kv.Domain + stepSize uint64 + ht *HistoryRoTx + salt *uint32 d *Domain @@ -645,14 +644,13 @@ func (d *Domain) beginForTests() *DomainRoTx { // aggregatorVisible generation, avoiding a torn cross-entity read func (d *Domain) beginFilesRo(dv *domainVisible, hf visibleFiles, hiv *iiVisible) *DomainRoTx { return &DomainRoTx{ - name: d.Name, - stepSize: d.stepSize, - stepsInFrozenFile: d.stepsInFrozenFile, - d: d, - ht: d.History.beginFilesRo(hf, hiv), - visible: dv, - files: dv.files, - salt: d.salt.Load(), + name: d.Name, + stepSize: d.stepSize, + d: d, + ht: d.History.beginFilesRo(hf, hiv), + visible: dv, + files: dv.files, + salt: d.salt.Load(), } } diff --git a/db/state/history.go b/db/state/history.go index e6ad99195d1..8742111aa4e 100644 --- a/db/state/history.go +++ b/db/state/history.go @@ -905,19 +905,16 @@ type HistoryRoTx struct { h *History iit *InvertedIndexRoTx - files visibleFiles // have no garbage (canDelete=true, overlaps, etc...) - getters []*seg.Reader - readers []*recsplit.IndexReader - stepSize uint64 - stepsInFrozenFile uint64 - - trace bool + files visibleFiles // have no garbage (canDelete=true, overlaps, etc...) + getters []*seg.Reader + readers []*recsplit.IndexReader + stepSize uint64 valsC kv.Cursor valsCDup kv.CursorDupSort - _bufTs []byte - snappyReadBuffer []byte + _bufTs []byte + blockCompressionBuf []byte } func (h *History) beginForTests() *HistoryRoTx { @@ -935,12 +932,10 @@ func (h *History) BeginFilesRoForDebug() *HistoryRoTx { func (h *History) beginFilesRo(files visibleFiles, iv *iiVisible) *HistoryRoTx { return &HistoryRoTx{ - h: h, - iit: h.InvertedIndex.beginFilesRo(iv), - files: files, - stepSize: h.stepSize, - stepsInFrozenFile: h.stepsInFrozenFile, - trace: false, + h: h, + iit: h.InvertedIndex.beginFilesRo(iv), + files: files, + stepSize: h.stepSize, } } @@ -1188,7 +1183,7 @@ func (ht *HistoryRoTx) historySeekInFiles(key []byte, txNum uint64) ([]byte, boo } if compressedPageValuesCount > 1 { - v, ht.snappyReadBuffer = seg.GetFromPage(historyKey, v, ht.snappyReadBuffer, true) + v, ht.blockCompressionBuf = seg.GetFromPage(historyKey, v, ht.blockCompressionBuf, true) } return v, true, nil } diff --git a/db/state/inverted_index.go b/db/state/inverted_index.go index bbac3994125..193d233996b 100644 --- a/db/state/inverted_index.go +++ b/db/state/inverted_index.go @@ -472,13 +472,9 @@ type InvertedIndexRoTx struct { seekInFilesCache *IISeekInFilesCache - // TODO: retrofit recent optimization in main and reenable the next line - // ef *multiencseq.SequenceBuilder // re-usable salt *uint32 stepSize uint64 stepsInFrozenFile uint64 - - reUsableSeq multiencseq.SequenceReader // re-usable instance, to reduce allocations } // hashKey - change of salt will require re-gen of indices @@ -522,6 +518,8 @@ func (iit *InvertedIndexRoTx) seekInFiles(key []byte, txNum uint64) (found bool, return false, 0, nil } + var seq multiencseq.SequenceReader + hi, lo := iit.hashKey(key) if iit.seekInFilesCache == nil { iit.seekInFilesCache = iit.visible.newSeekInFilesCache() @@ -558,8 +556,8 @@ func (iit *InvertedIndexRoTx) seekInFiles(key []byte, txNum uint64) (found bool, } encodedSeq, _ := g.Next(nil) - iit.reUsableSeq.Reset(iit.files[i].startTxNum, encodedSeq) - equalOrHigherTxNum, _, found = iit.reUsableSeq.Seek(txNum) + seq.Reset(iit.files[i].startTxNum, encodedSeq) + equalOrHigherTxNum, _, found = seq.Seek(txNum) if !found { continue } diff --git a/db/state/inverted_index_bench_test.go b/db/state/inverted_index_bench_test.go new file mode 100644 index 00000000000..9b83baa37fd --- /dev/null +++ b/db/state/inverted_index_bench_test.go @@ -0,0 +1,50 @@ +package state + +import ( + "encoding/binary" + "testing" + + "github.com/erigontech/erigon/common/background" + "github.com/erigontech/erigon/common/log/v3" + "github.com/erigontech/erigon/db/kv" +) + +// BenchmarkInvertedIndexSeekInFiles measures the per-seek cost of the file-scan path. +// Run with II_LRU_ENABLED=false to bypass the seek cache, otherwise the cache short-circuits +// before the sequence decoding this is meant to measure. +func BenchmarkInvertedIndexSeekInFiles(b *testing.B) { + logger := log.New() + db, ii, txs := filledInvIndexOfSize(b, 1000, 16, 31, logger) + ctx := b.Context() + + tx, err := db.BeginRw(ctx) + if err != nil { + b.Fatal(err) + } + defer tx.Rollback() + for step := kv.Step(0); step < kv.Step(txs/ii.stepSize)-1; step++ { + if err := ii.collateBuildIntegrate(ctx, step, tx, background.NewProgressSet()); err != nil { + b.Fatal(err) + } + } + + iit := ii.beginForTests() + defer iit.Close() + if len(iit.files) == 0 { + b.Fatal("no visible files: benchmark would not reach the seek path") + } + + keys := make([][8]byte, 31) + for i := range keys { + binary.BigEndian.PutUint64(keys[i][:], uint64(i+1)) + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + k := keys[i%len(keys)] + if _, _, err := iit.seekInFiles(k[:], uint64(i%900)); err != nil { + b.Fatal(err) + } + } +} diff --git a/execution/execmodule/exec_module.go b/execution/execmodule/exec_module.go index 72ab0d19b9e..6bf8ed4f6c7 100644 --- a/execution/execmodule/exec_module.go +++ b/execution/execmodule/exec_module.go @@ -759,14 +759,15 @@ func (e *ExecModule) HasBlock(ctx context.Context, blockHash *common.Hash, _ *ui if *num <= e.blockReader.FrozenBlocks() { return true, nil } - has, err := tx.Has(kv.Headers, dbutils.HeaderKey(*num, *blockHash)) + dbKey := dbutils.HeaderKey(*num, *blockHash) + has, err := tx.Has(kv.Headers, dbKey) if err != nil { return false, err } if !has { return false, nil } - has, err = tx.Has(kv.BlockBody, dbutils.HeaderKey(*num, *blockHash)) + has, err = tx.Has(kv.BlockBody, dbKey) if err != nil { return false, err } From 30fe204ea70ab8b355bbac4b3101f669240c23ea Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:16:11 +0000 Subject: [PATCH 03/13] execution: update devnet fixtures to v7.2.0 --- .github/workflows/test-hive-eest.yml | 3 ++- test-fixtures.json | 14 +++++++------- tools/eest-spec-shards.yml | 12 ++++++++---- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test-hive-eest.yml b/.github/workflows/test-hive-eest.yml index 3510dac740d..81ff1444f41 100644 --- a/.github/workflows/test-hive-eest.yml +++ b/.github/workflows/test-hive-eest.yml @@ -102,7 +102,8 @@ jobs: fixtures-tarball: eest_devnet extra-hive-flags: "--sim.loglevel=3 --client.checktimelimit=300s" erigon-extra-flags: "--experimental.bal" - max-failures: 0 + # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. + max-failures: 3532 exec_mode: parallel steps: - name: Clean docker system diff --git a/test-fixtures.json b/test-fixtures.json index 17419265183..c744c32df1f 100644 --- a/test-fixtures.json +++ b/test-fixtures.json @@ -5,10 +5,10 @@ "size": 1025048557 }, "eest_devnet": { - "url": "https://github.com/ethereum/execution-specs/releases/download/tests-glamsterdam-devnet%40v6.1.1/fixtures_glamsterdam-devnet.tar.gz", - "sha256": "45c1e1489c31aac055f8ccd38bd0f1466aab87d9d61178e9979e79164e4ee02b", - "size": 674284009, - "branch": "devnets/glamsterdam/6" + "url": "https://github.com/ethereum/execution-specs/releases/download/tests-glamsterdam-devnet%40v7.2.0/fixtures_glamsterdam-devnet.tar.gz", + "sha256": "29ba214eaf37c880c845179994cb62e82a0fb63e58f83e6c640d85f3e7d7a796", + "size": 677943112, + "branch": "devnets/glamsterdam/7" }, "eest_stable": { "url": "https://github.com/ethereum/execution-specs/releases/download/tests%40v20.0.0/fixtures.tar.gz", @@ -16,9 +16,9 @@ "size": 399656884 }, "eest_zkevm": { - "url": "https://github.com/ethereum/execution-specs/releases/download/tests-zkevm%40v0.5.0/fixtures_zkevm.tar.gz", - "sha256": "6b5fd6dea77cc5ea51dfdc35b03bdca41875926e17ad26f3ebebf9841038a366", - "size": 486272611 + "url": "https://github.com/ethereum/execution-specs/releases/download/tests-zkevm%40v0.6.2/fixtures_zkevm.tar.gz", + "sha256": "cf9395b2cb1a87c195fd827ea03dce65a37c6036bb182441da28e7b0f6d45f40", + "size": 497764775 }, "cl_mainnet": { "url": "https://github.com/ethereum/consensus-specs/releases/download/v1.7.0-alpha.11/mainnet.tar.gz", diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index 8d3d3101c49..0c5108932e9 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -48,7 +48,8 @@ exec3-parallel: true - shard: blocktests-devnet workers: 12 - max-allowed-failures: 0 + # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. + max-allowed-failures: 21877 exec3-parallel: true - shard: enginextests-stable-sequential workers: 8 @@ -122,7 +123,8 @@ no-ramdisk: true - shard: zkevm-witness workers: 8 - max-allowed-failures: 0 + # TODO: reduce to 0 as tests-zkevm@v0.6.2 support lands. + max-allowed-failures: 22031 - shard: blocktests-stable-race-pre-cancun-sequential workers: 12 max-allowed-failures: 0 @@ -161,9 +163,11 @@ run: 'fork_(Osaka|BPO)' - shard: blocktests-devnet-race-amsterdam workers: 12 - max-allowed-failures: 0 + # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. + max-allowed-failures: 21789 exec3-parallel: true run: 'fork_Amsterdam' - shard: zkevm-witness-race workers: 8 - max-allowed-failures: 0 + # TODO: reduce to 0 as tests-zkevm@v0.6.2 support lands. + max-allowed-failures: 22031 From bc2e54cf5c1d1be4c6d476a065443f5e4cdfe3c5 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:20:37 +0000 Subject: [PATCH 04/13] execution: update EIP-8282 contracts for glamsterdam-devnet-7 --- .github/workflows/test-hive-eest.yml | 2 +- execution/chain/spec/allocs/dev.json | 8 +-- execution/chain/spec/eip8282_test.go | 58 +++++++++++++++++++++ execution/protocol/misc/eip8282.go | 8 ++- execution/protocol/misc/eip8282_test.go | 38 ++++++++------ execution/protocol/params/protocol.go | 8 ++- execution/tests/testutil/state_test_util.go | 9 ++-- tools/eest-spec-shards.yml | 10 ++-- 8 files changed, 108 insertions(+), 33 deletions(-) create mode 100644 execution/chain/spec/eip8282_test.go diff --git a/.github/workflows/test-hive-eest.yml b/.github/workflows/test-hive-eest.yml index 81ff1444f41..ba07c147d7b 100644 --- a/.github/workflows/test-hive-eest.yml +++ b/.github/workflows/test-hive-eest.yml @@ -103,7 +103,7 @@ jobs: extra-hive-flags: "--sim.loglevel=3 --client.checktimelimit=300s" erigon-extra-flags: "--experimental.bal" # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-failures: 3532 + max-failures: 597 exec_mode: parallel steps: - name: Clean docker system diff --git a/execution/chain/spec/allocs/dev.json b/execution/chain/spec/allocs/dev.json index 31fcba8c69c..f31559fc083 100644 --- a/execution/chain/spec/allocs/dev.json +++ b/execution/chain/spec/allocs/dev.json @@ -95,18 +95,18 @@ "0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B": { "balance": "0x21e19e0c9bab2400000" }, - "0x0000884d2AA32eAa155F59A2f24eFa73D9008282": { + "0x0000BFF46984E3725691FA540A8C7589300D8282": { "balance": "0", "nonce": "1", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe146101065760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461023457600182026001905f5b5f82111560695781019083028483029004916001019190604e565b90939004925050503660b814608957366102345734610234575f5260205ff35b8034106102345760383567ffffffffffffffff1680633b9aca001161023457633b9aca00029034031061023457600154600101600155600354806006026004015f358155600101602035815560010160403581556001016060358155600101608035815560010160a035905560b85f5f3760b85fa0600101600355005b600354600254808203806101001161011d57506101005b5f5b8181146101c3578281016006026004018160b8028154815260200181600101548152602001816002015480825260401c67ffffffffffffffff16816010018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360200181600301548152602001816004015481526020019060050154905260010161011f565b91018092146101d557906002556101e0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561020d57505f5b6001546020828201116102225750505f610228565b01602090035b5f555f60015560b8025ff35b5f5ffd", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1461011c575f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146102705760015460088111605257506058565b60089003015b601190600182026001905f5b5f821115607f57810190830284830290049160010191906064565b90939004925050503660b814609f57366102705734610270575f5260205ff35b8034106102705760383567ffffffffffffffff1680633b9aca001161027057633b9aca00029034031061027057600154600101600155600354806006026004015f358155600101602035815560010160403581556001016060358155600101608035815560010160a035905560b85f5f3760b85fa0600101600355005b60035460025480820380604011610131575060405b5f5b8181146101d7578281016006026004018160b8028154815260200181600101548152602001816002015480825260401c67ffffffffffffffff16816010018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c816001015353602001816003015481526020018160040154815260200190600501549052600101610133565b91018092146101e957906002556101f4565b90505f6002555f6003555b36610242575f54600154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461023057600882820111610238575b50505f610264565b0160089003610264565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5f555f60015560b8025ff35b5f5ffd", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } }, - "0x000014574A74c805590AFF9499fc7A690f008282": { + "0x000064D678505AD48F8CCB093BC65613800E8282": { "balance": "0", "nonce": "1", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461018857600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603014608857366101885734610188575f5260205ff35b341061018857600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260305f60143760445fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101175782810160030260040181604402815460601b8152601401816001015481526020019060020154905260010160e1565b91018092146101295790600255610134565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561016157505f5b6001546002828201116101765750505f61017c565b01600290035b5f555f6001556044025ff35b5f5ffd", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460e1575f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101c65760015460028111605157506057565b60029003015b601190600182026001905f5b5f821115607e57810190830284830290049160010191906063565b909390049250505036603014609e57366101c657346101c6575f5260205ff35b34106101c657600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260305f60143760445fa0600101600355005b6003546002548082038060101160f5575060105b5f5b81811461012d5782810160030260040181604402815460601b8152601401816001015481526020019060020154905260010160f7565b910180921461013f579060025561014a565b90505f6002555f6003555b36610198575f54600154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101865760028282011161018e575b50505f6101ba565b01600290036101ba565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5f555f6001556044025ff35b5f5ffd", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } diff --git a/execution/chain/spec/eip8282_test.go b/execution/chain/spec/eip8282_test.go new file mode 100644 index 00000000000..747f0d74f2c --- /dev/null +++ b/execution/chain/spec/eip8282_test.go @@ -0,0 +1,58 @@ +// Copyright 2026 The Erigon Authors +// This file is part of Erigon. +// +// Erigon is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Erigon is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Erigon. If not, see . + +package chainspec_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/erigontech/erigon/common" + chainspec "github.com/erigontech/erigon/execution/chain/spec" + "github.com/erigontech/erigon/execution/protocol/misc" +) + +func TestDeveloperGenesisBuilderContracts(t *testing.T) { + genesis := chainspec.DeveloperGenesisBlock() + tests := []struct { + name string + address common.Address + code []byte + }{ + { + name: "deposit", + address: common.HexToAddress("0x0000BFF46984E3725691FA540A8C7589300D8282"), + code: misc.BuilderDepositRequestCode, + }, + { + name: "exit", + address: common.HexToAddress("0x000064D678505AD48F8CCB093BC65613800E8282"), + code: misc.BuilderExitRequestCode, + }, + } + for _, tt := range tests { + t.Run( + tt.name, + func(t *testing.T) { + account, ok := genesis.Alloc[tt.address] + require.True(t, ok) + require.Equal(t, uint64(1), account.Nonce) + require.Equal(t, tt.code, account.Code) + }, + ) + } +} diff --git a/execution/protocol/misc/eip8282.go b/execution/protocol/misc/eip8282.go index d1e7e66c1cf..827739f374a 100644 --- a/execution/protocol/misc/eip8282.go +++ b/execution/protocol/misc/eip8282.go @@ -30,12 +30,16 @@ import ( // geas-compiled derivative of the EIP-7002 withdrawal contract — same dispatch, // fee mechanism, queue, and storage layout with a wider record (184 bytes) and // two additional value checks (amount >= BUILDER_MIN_DEPOSIT, msg.value >= fee + amount*1gwei). -var BuilderDepositRequestCode = common.FromHex("0x3373fffffffffffffffffffffffffffffffffffffffe146101065760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461023457600182026001905f5b5f82111560695781019083028483029004916001019190604e565b90939004925050503660b814608957366102345734610234575f5260205ff35b8034106102345760383567ffffffffffffffff1680633b9aca001161023457633b9aca00029034031061023457600154600101600155600354806006026004015f358155600101602035815560010160403581556001016060358155600101608035815560010160a035905560b85f5f3760b85fa0600101600355005b600354600254808203806101001161011d57506101005b5f5b8181146101c3578281016006026004018160b8028154815260200181600101548152602001816002015480825260401c67ffffffffffffffff16816010018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360200181600301548152602001816004015481526020019060050154905260010161011f565b91018092146101d557906002556101e0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561020d57505f5b6001546020828201116102225750505f610228565b01602090035b5f555f60015560b8025ff35b5f5ffd") +var BuilderDepositRequestCode = common.FromHex( + "0x3373fffffffffffffffffffffffffffffffffffffffe1461011c575f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146102705760015460088111605257506058565b60089003015b601190600182026001905f5b5f821115607f57810190830284830290049160010191906064565b90939004925050503660b814609f57366102705734610270575f5260205ff35b8034106102705760383567ffffffffffffffff1680633b9aca001161027057633b9aca00029034031061027057600154600101600155600354806006026004015f358155600101602035815560010160403581556001016060358155600101608035815560010160a035905560b85f5f3760b85fa0600101600355005b60035460025480820380604011610131575060405b5f5b8181146101d7578281016006026004018160b8028154815260200181600101548152602001816002015480825260401c67ffffffffffffffff16816010018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c816001015353602001816003015481526020018160040154815260200190600501549052600101610133565b91018092146101e957906002556101f4565b90505f6002555f6003555b36610242575f54600154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461023057600882820111610238575b50505f610264565b0160089003610264565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5f555f60015560b8025ff35b5f5ffd", +) // EIP-8282 builder exit contract runtime bytecode. // geas-compiled derivative of the EIP-7002 withdrawal contract — same skeleton // with the amount field removed, producing a 68-byte record (source_address ++ pubkey). -var BuilderExitRequestCode = common.FromHex("0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461018857600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603014608857366101885734610188575f5260205ff35b341061018857600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260305f60143760445fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101175782810160030260040181604402815460601b8152601401816001015481526020019060020154905260010160e1565b91018092146101295790600255610134565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561016157505f5b6001546002828201116101765750505f61017c565b01600290035b5f555f6001556044025ff35b5f5ffd") +var BuilderExitRequestCode = common.FromHex( + "0x3373fffffffffffffffffffffffffffffffffffffffe1460e1575f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101c65760015460028111605157506057565b60029003015b601190600182026001905f5b5f821115607e57810190830284830290049160010191906063565b909390049250505036603014609e57366101c657346101c6575f5260205ff35b34106101c657600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260305f60143760445fa0600101600355005b6003546002548082038060101160f5575060105b5f5b81811461012d5782810160030260040181604402815460601b8152601401816001015481526020019060020154905260010160f7565b910180921461013f579060025561014a565b90505f6002555f6003555b36610198575f54600154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101865760028282011161018e575b50505f6101ba565b01600290036101ba565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5f555f6001556044025ff35b5f5ffd", +) // https://eips.ethereum.org/EIPS/eip-8282 func DequeueBuilderDepositRequests(syscall rules.SystemCall, state *state.IntraBlockState, builderDepositAddress accounts.Address) (*types.FlatRequest, error) { diff --git a/execution/protocol/misc/eip8282_test.go b/execution/protocol/misc/eip8282_test.go index 9f3250fd778..6579bcc4609 100644 --- a/execution/protocol/misc/eip8282_test.go +++ b/execution/protocol/misc/eip8282_test.go @@ -17,6 +17,7 @@ package misc_test import ( + "crypto/sha256" "testing" "github.com/stretchr/testify/require" @@ -114,23 +115,28 @@ func TestDequeueBuilderExitRequests_EmptyCodeReturnsError(t *testing.T) { "must reject syscall to builder exit contract with empty bytecode") } -// TestBuilderContractAddresses verifies the EIP-8282 predeploy addresses -// match the specification, and that the pre-deployed bytecode variables are populated. -func TestBuilderContractAddresses(t *testing.T) { +func TestBuilderContractArtifacts(t *testing.T) { t.Parallel() - - require.Equal(t, - common.HexToAddress("0x0000884d2AA32eAa155F59A2f24eFa73D9008282"), + require.Equal( + t, + common.HexToAddress("0x0000BFF46984E3725691FA540A8C7589300D8282"), params.BuilderDepositAddress.Value(), - "BuilderDepositAddress must match EIP-8282 spec") - - require.Equal(t, - common.HexToAddress("0x000014574A74c805590AFF9499fc7A690f008282"), + ) + require.Equal( + t, + common.HexToAddress("0x000064D678505AD48F8CCB093BC65613800E8282"), params.BuilderExitAddress.Value(), - "BuilderExitAddress must match EIP-8282 spec") - - require.NotEmpty(t, misc.BuilderDepositRequestCode, - "BuilderDepositRequestCode must be populated with official bytecode") - require.NotEmpty(t, misc.BuilderExitRequestCode, - "BuilderExitRequestCode must be populated with official bytecode") + ) + depositHash := sha256.Sum256(misc.BuilderDepositRequestCode) + require.Equal( + t, + common.HexToHash("0x2c49dcf745b1304f3dac0ea7487eae6d8fd07812ada980d542f79e8e5e53eb8d"), + common.Hash(depositHash), + ) + exitHash := sha256.Sum256(misc.BuilderExitRequestCode) + require.Equal( + t, + common.HexToHash("0xc889ed88730d157d192aae28c2dee61324d0df3bd01ff0078386808b4adb27aa"), + common.Hash(exitHash), + ) } diff --git a/execution/protocol/params/protocol.go b/execution/protocol/params/protocol.go index a702e15dc61..b9e614787c4 100644 --- a/execution/protocol/params/protocol.go +++ b/execution/protocol/params/protocol.go @@ -291,11 +291,15 @@ var ( // EIP-8282 - The Builder Deposit Addresses // Nick's-method derived address from the builder deposit contract deployment transaction. -var BuilderDepositAddress = accounts.InternAddress(common.HexToAddress("0x0000884d2AA32eAa155F59A2f24eFa73D9008282")) +var BuilderDepositAddress = accounts.InternAddress( + common.HexToAddress("0x0000BFF46984E3725691FA540A8C7589300D8282"), +) // EIP-8282 - The Builder Exit Addresses // Nick's-method derived address from the builder exit contract deployment transaction. -var BuilderExitAddress = accounts.InternAddress(common.HexToAddress("0x000014574A74c805590AFF9499fc7A690f008282")) +var BuilderExitAddress = accounts.InternAddress( + common.HexToAddress("0x000064D678505AD48F8CCB093BC65613800E8282"), +) // See EIP-7840: Add blob schedule to EL config files type BlobConfig struct { diff --git a/execution/tests/testutil/state_test_util.go b/execution/tests/testutil/state_test_util.go index f73eaf2c2de..cb71199b89e 100644 --- a/execution/tests/testutil/state_test_util.go +++ b/execution/tests/testutil/state_test_util.go @@ -95,7 +95,7 @@ type stTransaction struct { GasPrice *math.HexOrDecimal256 `json:"gasPrice"` MaxFeePerGas *math.HexOrDecimal256 `json:"maxFeePerGas"` MaxPriorityFeePerGas *math.HexOrDecimal256 `json:"maxPriorityFeePerGas"` - Nonce math.HexOrDecimal64 `json:"nonce"` + Nonce math.HexOrDecimal256 `json:"nonce"` GasLimit []math.HexOrDecimal64 `json:"gasLimit"` PrivateKey hexutil.Bytes `json:"secretKey"` To string `json:"to"` @@ -590,7 +590,10 @@ func toMessage(tx stTransaction, ps stPostState, baseFee *uint256.Int) (protocol feeCap = big.Int(*gasPrice) tipCap = big.Int(*gasPrice) } - + nonce := (*big.Int)(&tx.Nonce) + if !nonce.IsUint64() { + return nil, fmt.Errorf("invalid txn nonce (overflowed) %q", nonce) + } gpi := big.Int(*gasPrice) gasPriceInt := uint256.NewInt(gpi.Uint64()) @@ -602,7 +605,7 @@ func toMessage(tx stTransaction, ps stPostState, baseFee *uint256.Int) (protocol msg := types.NewMessage( from, to, - uint64(tx.Nonce), + nonce.Uint64(), value, uint64(gasLimit), gasPriceInt, diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index 0c5108932e9..d51ca0d8d0d 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -38,7 +38,7 @@ max-allowed-failures: 0 - shard: statetests-devnet workers: 12 - max-allowed-failures: 0 + max-allowed-failures: 1925 - shard: blocktests-stable-sequential workers: 12 max-allowed-failures: 0 @@ -49,7 +49,7 @@ - shard: blocktests-devnet workers: 12 # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-allowed-failures: 21877 + max-allowed-failures: 2242 exec3-parallel: true - shard: enginextests-stable-sequential workers: 8 @@ -124,7 +124,7 @@ - shard: zkevm-witness workers: 8 # TODO: reduce to 0 as tests-zkevm@v0.6.2 support lands. - max-allowed-failures: 22031 + max-allowed-failures: 2246 - shard: blocktests-stable-race-pre-cancun-sequential workers: 12 max-allowed-failures: 0 @@ -164,10 +164,10 @@ - shard: blocktests-devnet-race-amsterdam workers: 12 # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-allowed-failures: 21789 + max-allowed-failures: 2242 exec3-parallel: true run: 'fork_Amsterdam' - shard: zkevm-witness-race workers: 8 # TODO: reduce to 0 as tests-zkevm@v0.6.2 support lands. - max-allowed-failures: 22031 + max-allowed-failures: 2246 From 1118d2794fe37a8eb27f798c630cb0a0e7aae8b1 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Fri, 17 Jul 2026 06:29:44 +0000 Subject: [PATCH 05/13] fix ci --- .github/workflows/test-hive-eest.yml | 2 +- execution/tests/testutil/state_test_util.go | 9 ++++++--- tools/eest-spec-shards.yml | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-hive-eest.yml b/.github/workflows/test-hive-eest.yml index 81ff1444f41..ba07c147d7b 100644 --- a/.github/workflows/test-hive-eest.yml +++ b/.github/workflows/test-hive-eest.yml @@ -103,7 +103,7 @@ jobs: extra-hive-flags: "--sim.loglevel=3 --client.checktimelimit=300s" erigon-extra-flags: "--experimental.bal" # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-failures: 3532 + max-failures: 597 exec_mode: parallel steps: - name: Clean docker system diff --git a/execution/tests/testutil/state_test_util.go b/execution/tests/testutil/state_test_util.go index f73eaf2c2de..cb71199b89e 100644 --- a/execution/tests/testutil/state_test_util.go +++ b/execution/tests/testutil/state_test_util.go @@ -95,7 +95,7 @@ type stTransaction struct { GasPrice *math.HexOrDecimal256 `json:"gasPrice"` MaxFeePerGas *math.HexOrDecimal256 `json:"maxFeePerGas"` MaxPriorityFeePerGas *math.HexOrDecimal256 `json:"maxPriorityFeePerGas"` - Nonce math.HexOrDecimal64 `json:"nonce"` + Nonce math.HexOrDecimal256 `json:"nonce"` GasLimit []math.HexOrDecimal64 `json:"gasLimit"` PrivateKey hexutil.Bytes `json:"secretKey"` To string `json:"to"` @@ -590,7 +590,10 @@ func toMessage(tx stTransaction, ps stPostState, baseFee *uint256.Int) (protocol feeCap = big.Int(*gasPrice) tipCap = big.Int(*gasPrice) } - + nonce := (*big.Int)(&tx.Nonce) + if !nonce.IsUint64() { + return nil, fmt.Errorf("invalid txn nonce (overflowed) %q", nonce) + } gpi := big.Int(*gasPrice) gasPriceInt := uint256.NewInt(gpi.Uint64()) @@ -602,7 +605,7 @@ func toMessage(tx stTransaction, ps stPostState, baseFee *uint256.Int) (protocol msg := types.NewMessage( from, to, - uint64(tx.Nonce), + nonce.Uint64(), value, uint64(gasLimit), gasPriceInt, diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index 0c5108932e9..48f0d1a3124 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -38,7 +38,7 @@ max-allowed-failures: 0 - shard: statetests-devnet workers: 12 - max-allowed-failures: 0 + max-allowed-failures: 1925 - shard: blocktests-stable-sequential workers: 12 max-allowed-failures: 0 From 3e93e8e919db1a779108eefc0abeff1c606aca88 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:46:44 +0000 Subject: [PATCH 06/13] tidy --- tools/eest-spec-shards.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index 48f0d1a3124..adb11d861cb 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -38,6 +38,7 @@ max-allowed-failures: 0 - shard: statetests-devnet workers: 12 + # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. max-allowed-failures: 1925 - shard: blocktests-stable-sequential workers: 12 From 01fefb7c1d9e4732c5ab065eb95a9571423677c3 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:08:49 +0000 Subject: [PATCH 07/13] fix EIP-8282 failing last 4 tests due to unnecessary inits in test runs --- .../execmoduletester/exec_module_tester.go | 14 ----- execution/tests/blockgen/chain_makers.go | 57 ------------------- tools/eest-spec-shards.yml | 8 +-- 3 files changed, 4 insertions(+), 75 deletions(-) diff --git a/execution/execmodule/execmoduletester/exec_module_tester.go b/execution/execmodule/execmoduletester/exec_module_tester.go index e0e4344f463..5ed9cb62658 100644 --- a/execution/execmodule/execmoduletester/exec_module_tester.go +++ b/execution/execmodule/execmoduletester/exec_module_tester.go @@ -563,20 +563,6 @@ func New(tb testing.TB, opts ...Option) *ExecModuleTester { } } - // Deploy Amsterdam system contracts (EIP-8282) at genesis whenever Amsterdam is - // scheduled — a later fork transition must still find deployed code. These are - // required for the Merge engine's FinalizeAndAssemble to process builder - // deposit and exit requests. - if gspec.Config.AmsterdamTime != nil { - if err := blockgen.InitAmsterdamPreDeploys(mock.DB, gspec.Config, mock.Log); err != nil { - if tb != nil { - tb.Fatal(err) - } else { - panic(err) - } - } - } - blockWriter := blockio.NewBlockWriter() mock.Address = crypto.PubkeyToAddress(mock.Key.PublicKey) diff --git a/execution/tests/blockgen/chain_makers.go b/execution/tests/blockgen/chain_makers.go index 6e9f628eed6..600301dfe99 100644 --- a/execution/tests/blockgen/chain_makers.go +++ b/execution/tests/blockgen/chain_makers.go @@ -363,14 +363,6 @@ var withdrawalRequestCodeHash = accounts.InternCodeHash(crypto.Keccak256Hash(wit var consolidationRequestCode = common.Hex2Bytes("3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd") var consolidationRequestCodeHash = accounts.InternCodeHash(crypto.Keccak256Hash(consolidationRequestCode)) -// EIP-8282 builder deposit contract runtime bytecode -var builderDepositRequestCode = misc.BuilderDepositRequestCode -var builderDepositRequestCodeHash = accounts.InternCodeHash(crypto.Keccak256Hash(builderDepositRequestCode)) - -// EIP-8282 builder exit contract runtime bytecode -var builderExitRequestCode = misc.BuilderExitRequestCode -var builderExitRequestCodeHash = accounts.InternCodeHash(crypto.Keccak256Hash(builderExitRequestCode)) - func InitPraguePreDeploys(db kv.TemporalRwDB, config *chain.Config, logger log.Logger) error { ctx := context.Background() withdrawalAddr := config.GetWithdrawalRequestContract() @@ -418,55 +410,6 @@ func InitPraguePreDeploys(db kv.TemporalRwDB, config *chain.Config, logger log.L return domains.Commit(ctx, tx) } -// InitAmsterdamPreDeploys deploys the EIP-8282 builder deposit and exit -// system contracts into the state database for test chains with Amsterdam active. -func InitAmsterdamPreDeploys(db kv.TemporalRwDB, config *chain.Config, logger log.Logger) error { - ctx := context.Background() - builderDepositAddr := config.GetBuilderDepositContract() - builderExitAddr := config.GetBuilderExitContract() - tx, err := db.BeginTemporalRw(ctx) - if err != nil { - return err - } - defer tx.Rollback() - - domains, err := execctx.NewSharedDomains(ctx, tx, logger) - if err != nil { - return err - } - defer domains.Close() - latestTxNum, _, err := domains.SeekCommitment(ctx, tx) - if err != nil { - return err - } - stateWriter := state.NewWriter(domains.AsPutDel(tx), nil, latestTxNum) - - err = stateWriter.UpdateAccountData(builderDepositAddr, &accounts.Account{}, &accounts.Account{ - CodeHash: builderDepositRequestCodeHash, - Nonce: 1, - }) - if err != nil { - return err - } - err = stateWriter.UpdateAccountCode(builderDepositAddr, 0, builderDepositRequestCodeHash, builderDepositRequestCode) - if err != nil { - return err - } - err = stateWriter.UpdateAccountData(builderExitAddr, &accounts.Account{}, &accounts.Account{ - CodeHash: builderExitRequestCodeHash, - Nonce: 1, - }) - if err != nil { - return err - } - err = stateWriter.UpdateAccountCode(builderExitAddr, 0, builderExitRequestCodeHash, builderExitRequestCode) - if err != nil { - return err - } - - return domains.Commit(ctx, tx) -} - // GenerateChain creates a chain of n blocks. The first block's // parent will be the provided parent. db is used to store // intermediate states and should contain the parent's state trie. diff --git a/tools/eest-spec-shards.yml b/tools/eest-spec-shards.yml index aca46a2d672..24229cf5c70 100644 --- a/tools/eest-spec-shards.yml +++ b/tools/eest-spec-shards.yml @@ -50,7 +50,7 @@ - shard: blocktests-devnet workers: 12 # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-allowed-failures: 2242 + max-allowed-failures: 2238 exec3-parallel: true - shard: enginextests-stable-sequential workers: 8 @@ -125,7 +125,7 @@ - shard: zkevm-witness workers: 8 # TODO: reduce to 0 as tests-zkevm@v0.6.2 support lands. - max-allowed-failures: 2246 + max-allowed-failures: 2242 - shard: blocktests-stable-race-pre-cancun-sequential workers: 12 max-allowed-failures: 0 @@ -165,10 +165,10 @@ - shard: blocktests-devnet-race-amsterdam workers: 12 # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-allowed-failures: 2242 + max-allowed-failures: 2238 exec3-parallel: true run: 'fork_Amsterdam' - shard: zkevm-witness-race workers: 8 # TODO: reduce to 0 as tests-zkevm@v0.6.2 support lands. - max-allowed-failures: 2246 + max-allowed-failures: 2242 From 2bb0726381856ae49f87f7f9fd41d4151cb357da Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Fri, 17 Jul 2026 12:30:16 +0000 Subject: [PATCH 08/13] fix EIP-8282 make test-all --- db/snapshotsync/freezeblocks/dump_test.go | 1 + execution/abi/bind/backends/simulated.go | 7 +- execution/bal/regenerator_test.go | 7 +- .../execmodule/exec_module_devp2p_test.go | 2 + execution/execmodule/exec_module_test.go | 89 +++++++++++++++---- .../execmodule/exec_module_unwind_gap_test.go | 14 ++- .../execmoduletester/exec_module_tester.go | 53 ++++++++--- execution/verify/history_verify_test.go | 2 + rpc/gasprice/gasprice_test.go | 13 ++- rpc/jsonrpc/eth_block_access_list_test.go | 7 +- rpc/jsonrpc/eth_call_test.go | 7 +- rpc/jsonrpc/trace_filtering_test.go | 24 ++++- 12 files changed, 184 insertions(+), 42 deletions(-) diff --git a/db/snapshotsync/freezeblocks/dump_test.go b/db/snapshotsync/freezeblocks/dump_test.go index cfe6572946f..bfb50ad3b94 100644 --- a/db/snapshotsync/freezeblocks/dump_test.go +++ b/db/snapshotsync/freezeblocks/dump_test.go @@ -281,6 +281,7 @@ func createDumpTestKV(t *testing.T, chainConfig *chain.Config, chainSize int) *e execmoduletester.WithGenesisSpec(gspec), execmoduletester.WithKey(key), execmoduletester.WithPruneMode(prune.DefaultMode), + execmoduletester.WithAmsterdamBuilderContracts(), ) // Generate testing blocks diff --git a/execution/abi/bind/backends/simulated.go b/execution/abi/bind/backends/simulated.go index f4abfed3e7b..c2138c005ff 100644 --- a/execution/abi/bind/backends/simulated.go +++ b/execution/abi/bind/backends/simulated.go @@ -103,7 +103,12 @@ func NewSimulatedBackendWithConfig(t *testing.T, alloc types.GenesisAlloc, confi engine = ethash.NewFaker() } //SimulatedBackend - it's remote blockchain node. This is reason why it has own `MockSentry` and own `DB` (even if external unit-test have one already) - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(&genesis), execmoduletester.WithEngine(engine)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(&genesis), + execmoduletester.WithEngine(engine), + execmoduletester.WithAmsterdamBuilderContracts(), + ) backend := &SimulatedBackend{ m: m, diff --git a/execution/bal/regenerator_test.go b/execution/bal/regenerator_test.go index 2ed381fc38c..032bbc8394f 100644 --- a/execution/bal/regenerator_test.go +++ b/execution/bal/regenerator_test.go @@ -45,7 +45,12 @@ func TestRegeneratorReproducesCanonicalBlockAccessLists(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) storingInitCode := []byte{0x60, 0x01, 0x60, 0x00, 0x55, 0x00} // PUSH1 1, PUSH1 0, SSTORE, STOP diff --git a/execution/execmodule/exec_module_devp2p_test.go b/execution/execmodule/exec_module_devp2p_test.go index a4241c57339..e6b30e975d0 100644 --- a/execution/execmodule/exec_module_devp2p_test.go +++ b/execution/execmodule/exec_module_devp2p_test.go @@ -72,6 +72,7 @@ func TestGetBlockReceiptsFrozenBlocks(t *testing.T) { }), execmoduletester.WithKey(devp2pTestKey), execmoduletester.WithSentryProtocol(direct.ETH70), + execmoduletester.WithAmsterdamBuilderContracts(), ) signer := types.LatestSignerForChainID(nil) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, frozenChainLength, func(i int, block *blockgen.BlockGen) { @@ -265,6 +266,7 @@ func TestGetBlockAccessListsResponseMatrix(t *testing.T) { }), execmoduletester.WithKey(keyA), execmoduletester.WithSentryProtocol(direct.ETH71), + execmoduletester.WithAmsterdamBuilderContracts(), ) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) diff --git a/execution/execmodule/exec_module_test.go b/execution/execmodule/exec_module_test.go index 08cab900c92..eca39c653b2 100644 --- a/execution/execmodule/exec_module_test.go +++ b/execution/execmodule/exec_module_test.go @@ -77,6 +77,7 @@ func TestValidateChainWithLastTxNumOfBlockAtStepBoundary(t *testing.T) { execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithStepSize(stepSize), + execmoduletester.WithAmsterdamBuilderContracts(), ) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( @@ -143,7 +144,12 @@ func TestValidateChainAndUpdateForkChoiceWithSideForksThatGoBackAndForwardInHeig senderAddr2: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) longerFork, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( types.NewTransaction(uint64(i), senderAddr, uint256.NewInt(1_000), 50000, uint256.NewInt(m.Genesis.BaseFee().Uint64()), nil), @@ -205,7 +211,12 @@ func TestValidateForkPayloadOffNonTipCanonicalBlockWithCache(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) to := common.Address{0xaa} baseFee := m.Genesis.BaseFee().Uint64() mkTx := func(nonce, amount uint64) types.Transaction { @@ -274,7 +285,12 @@ func TestUpdateForkChoiceRecoversWhenStateAheadOfTxNums(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 10, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( types.NewTransaction(uint64(i), senderAddr, uint256.NewInt(1_000), 50000, uint256.NewInt(m.Genesis.BaseFee().Uint64()), nil), @@ -359,7 +375,12 @@ func TestUpdateForkChoiceForwardExecutesAfterStateAheadRecovery(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 15, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( types.NewTransaction(uint64(i), senderAddr, uint256.NewInt(1_000), 50000, uint256.NewInt(m.Genesis.BaseFee().Uint64()), nil), @@ -445,13 +466,17 @@ func TestReorgBackAndForwardIntoCanonicalChain(t *testing.T) { {name: "bg-commit", opt: execmoduletester.WithFcuBackgroundCommit()}, } for _, mode := range modes { - opts := []execmoduletester.Option{execmoduletester.WithGenesisSpec(&types.Genesis{Config: chain.AllProtocolChanges})} + opts := []execmoduletester.Option{ + execmoduletester.WithGenesisSpec(&types.Genesis{Config: chain.AllProtocolChanges}), + execmoduletester.WithAmsterdamBuilderContracts(), + } if mode.opt != nil { opts = append(opts, mode.opt) } t.Run(mode.name, func(t *testing.T) { ctx := t.Context() m := execmoduletester.New(t, opts...) + m.ExecModule.WaitIdle(ctx) const chainLen = 9 const reorgBackTo = 5 @@ -918,10 +943,12 @@ func TestAssembleBlockGasOverflow(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithTxPool(), + execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1231,10 +1258,12 @@ func TestAssembleBlockAmsterdamForkTransition(t *testing.T) { Ethash: new(chain.EthashConfig), } - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithTxPool(), execmoduletester.WithChainConfig(cfg), execmoduletester.WithExperimentalBAL(), + execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1351,7 +1380,12 @@ func TestGetPayloadBodiesRegenerateBlockAccessLists(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { @@ -1418,7 +1452,12 @@ func TestGetPayloadBodiesNonCanonicalBlockAccessList(t *testing.T) { addrB: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKeyA)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKeyA), + execmoduletester.WithAmsterdamBuilderContracts(), + ) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) canonical, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { @@ -1589,10 +1628,12 @@ func TestAssembleBlockStateGasLimit(t *testing.T) { }, } - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithTxPool(), + execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1680,10 +1721,12 @@ func TestAssembleBlockStateGasLimitSSTORE(t *testing.T) { }, } - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithTxPool(), + execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1826,10 +1869,12 @@ func TestAssembleBlockGasPoolSnapshotRestoreBug(t *testing.T) { Alloc: alloc, } - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(keys[0]), execmoduletester.WithTxPool(), + execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1928,10 +1973,12 @@ func TestAssembleBlockGasPoolMultiBatchInitBug(t *testing.T) { Alloc: alloc, } - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(keys[0]), execmoduletester.WithTxPool(), + execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -2034,9 +2081,11 @@ func TestEIP8246NoBurnLogWhenCoinbaseSelfDestructs(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), ) baseFee := m.Genesis.BaseFee().Uint64() @@ -2113,7 +2162,12 @@ func TestInsertBlocksWithBatchedFCU(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) const totalBlocks = 30 const batchSize = 10 @@ -2186,6 +2240,7 @@ func runBatchedFCUBadBlockRecovery(t *testing.T, bgCommit bool) { opts := []execmoduletester.Option{ execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), } if bgCommit { opts = append(opts, execmoduletester.WithFcuBackgroundCommit()) @@ -2513,7 +2568,8 @@ func runBALFoldAheadChangeset(t *testing.T, foldAhead, shadow bool) balFoldResul privKey, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") require.NoError(t, err) senderAddr := crypto.PubkeyToAddress(privKey.PublicKey) - m := execmoduletester.New(t, + m := execmoduletester.New( + t, execmoduletester.WithKey(privKey), execmoduletester.WithGenesisSpec(&types.Genesis{ Config: chain.AllProtocolChanges, // Amsterdam-at-0 → every block carries a BAL @@ -2522,6 +2578,7 @@ func runBALFoldAheadChangeset(t *testing.T, foldAhead, shadow bool) balFoldResul execmoduletester.WithExperimentalBAL(), execmoduletester.WithAlwaysGenerateChangesets(false), execmoduletester.WithMaxReorgDepth(maxReorgDepth), + execmoduletester.WithAmsterdamBuilderContracts(), ) // AllProtocolChanges is post-London, so txs need a fee cap above the base fee diff --git a/execution/execmodule/exec_module_unwind_gap_test.go b/execution/execmodule/exec_module_unwind_gap_test.go index 6d1acff3a93..4a88d8678e4 100644 --- a/execution/execmodule/exec_module_unwind_gap_test.go +++ b/execution/execmodule/exec_module_unwind_gap_test.go @@ -65,7 +65,12 @@ func TestUpdateForkChoiceBadBlockMidBatchThenRecovery(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) const chainLen = 13 const committedTo = 10 chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, chainLen, func(i int, b *blockgen.BlockGen) { @@ -181,7 +186,12 @@ func TestUpdateForkChoiceBadBlockAtLongBatchTailThenRecovery(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) const chainLen = 35 const committedTo = 26 const badHeight = 35 // tail of the never-validated segment (index badHeight-1) diff --git a/execution/execmodule/execmoduletester/exec_module_tester.go b/execution/execmodule/execmoduletester/exec_module_tester.go index 5ed9cb62658..048e3f8193e 100644 --- a/execution/execmodule/execmoduletester/exec_module_tester.go +++ b/execution/execmodule/execmoduletester/exec_module_tester.go @@ -59,6 +59,7 @@ import ( "github.com/erigontech/erigon/execution/exec" "github.com/erigontech/erigon/execution/execmodule" "github.com/erigontech/erigon/execution/execmodule/chainreader" + "github.com/erigontech/erigon/execution/protocol/misc" "github.com/erigontech/erigon/execution/protocol/rules" "github.com/erigontech/erigon/execution/protocol/rules/ethash" "github.com/erigontech/erigon/execution/protocol/rules/merge" @@ -337,6 +338,12 @@ func WithChainConfig(cfg *chain.Config) Option { } } +func WithAmsterdamBuilderContracts() Option { + return func(opts *options) { + opts.amsterdamBuilderContracts = true + } +} + func WithFcuBackgroundCommit() Option { return func(opts *options) { opts.fcuBackgroundCommit = true @@ -375,20 +382,21 @@ func WithSentryProtocol(protocol uint) Option { } type options struct { - stepSize *uint64 - experimentalBAL bool - genesis *types.Genesis - chainConfig *chain.Config - key *ecdsa.PrivateKey - engine rules.Engine - pruneMode *prune.Mode - withTxPool bool - enableDomains []kv.Domain - fcuBackgroundCommit bool - fcuBackgroundPrune bool - alwaysGenerateChangesets *bool - maxReorgDepth *uint64 - sentryProtocol uint + stepSize *uint64 + experimentalBAL bool + genesis *types.Genesis + chainConfig *chain.Config + key *ecdsa.PrivateKey + engine rules.Engine + pruneMode *prune.Mode + withTxPool bool + enableDomains []kv.Domain + fcuBackgroundCommit bool + fcuBackgroundPrune bool + alwaysGenerateChangesets *bool + maxReorgDepth *uint64 + sentryProtocol uint + amsterdamBuilderContracts bool } func applyOptions(opts []Option) options { @@ -413,6 +421,12 @@ func applyOptions(opts []Option) options { address: {Balance: big.NewInt(1 * common.Ether)}, }, } + if opt.genesis.Config.IsAmsterdam(opt.genesis.Timestamp) { + addAmsterdamBuilderContracts(opt.genesis) + } + } + if opt.amsterdamBuilderContracts { + addAmsterdamBuilderContracts(opt.genesis) } // engine depends on genesis if opt.engine == nil { @@ -428,6 +442,17 @@ func applyOptions(opts []Option) options { return opt } +func addAmsterdamBuilderContracts(genesis *types.Genesis) { + if genesis.Config.AmsterdamTime == nil { + return + } + if genesis.Alloc == nil { + genesis.Alloc = types.GenesisAlloc{} + } + genesis.Alloc[genesis.Config.GetBuilderDepositContract().Value()] = types.GenesisAccount{Balance: new(big.Int), Code: misc.BuilderDepositRequestCode, Nonce: 1} + genesis.Alloc[genesis.Config.GetBuilderExitContract().Value()] = types.GenesisAccount{Balance: new(big.Int), Code: misc.BuilderExitRequestCode, Nonce: 1} +} + // New creates an ExecModuleTester. When called with no options, it uses // sensible defaults (TestChainBerlinConfig, 1 Ether alloc, ethash.NewFaker, etc.). // Use With* options to customise. diff --git a/execution/verify/history_verify_test.go b/execution/verify/history_verify_test.go index dbf8bbec4fa..e5f05dda233 100644 --- a/execution/verify/history_verify_test.go +++ b/execution/verify/history_verify_test.go @@ -51,6 +51,7 @@ func TestHistoryVerification_SimpleBlocks(t *testing.T) { execmoduletester.WithKey(key), execmoduletester.WithStepSize(stepSize), execmoduletester.WithoutExperimentalBAL(), + execmoduletester.WithAmsterdamBuilderContracts(), ) ctx := context.Background() logger := log.New() @@ -137,6 +138,7 @@ func TestHistoryVerification_WithUserTransactions(t *testing.T) { execmoduletester.WithKey(key), execmoduletester.WithStepSize(stepSize), execmoduletester.WithoutExperimentalBAL(), + execmoduletester.WithAmsterdamBuilderContracts(), ) ctx := context.Background() logger := log.New() diff --git a/rpc/gasprice/gasprice_test.go b/rpc/gasprice/gasprice_test.go index 085dd23b4fb..4466fa3761f 100644 --- a/rpc/gasprice/gasprice_test.go +++ b/rpc/gasprice/gasprice_test.go @@ -366,7 +366,12 @@ func TestSuggestTipCap_SparseBlocks(t *testing.T) { Alloc: types.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, } signer := types.LatestSigner(gspec.Config) - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec), execmoduletester.WithKey(key)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(gspec), + execmoduletester.WithKey(key), + execmoduletester.WithAmsterdamBuilderContracts(), + ) // 10 blocks: only the last one (index 9) has a transaction; all others are empty. const totalBlocks = 10 @@ -414,7 +419,11 @@ func TestSuggestTipCap_AllEmptyBlocks(t *testing.T) { } gspec := &types.Genesis{Config: chain.AllProtocolChanges} - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(gspec), + execmoduletester.WithAmsterdamBuilderContracts(), + ) const totalBlocks = 5 ch, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, totalBlocks, func(_ int, b *blockgen.BlockGen) { diff --git a/rpc/jsonrpc/eth_block_access_list_test.go b/rpc/jsonrpc/eth_block_access_list_test.go index 5672380fb98..a538b53aa5c 100644 --- a/rpc/jsonrpc/eth_block_access_list_test.go +++ b/rpc/jsonrpc/eth_block_access_list_test.go @@ -50,7 +50,12 @@ func TestGetBlockAccessListRegeneratesPrunedBAL(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(genesis), + execmoduletester.WithKey(privKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { diff --git a/rpc/jsonrpc/eth_call_test.go b/rpc/jsonrpc/eth_call_test.go index d645232f900..b558b1c2429 100644 --- a/rpc/jsonrpc/eth_call_test.go +++ b/rpc/jsonrpc/eth_call_test.go @@ -693,7 +693,12 @@ func fundedBankGenesis(t *testing.T, cfg *chain.Config) (m *execmoduletester.Exe gspec.GasLimit = 60_000_000 } - m = execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec), execmoduletester.WithKey(bankKey)) + m = execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(gspec), + execmoduletester.WithKey(bankKey), + execmoduletester.WithAmsterdamBuilderContracts(), + ) return m, bankKey, bankAddress } diff --git a/rpc/jsonrpc/trace_filtering_test.go b/rpc/jsonrpc/trace_filtering_test.go index e0504590450..d4c55be4749 100644 --- a/rpc/jsonrpc/trace_filtering_test.go +++ b/rpc/jsonrpc/trace_filtering_test.go @@ -172,7 +172,11 @@ func chainWithWithdrawal(t *testing.T, withdrawalAddr common.Address, withdrawal Config: chain.AllProtocolChanges, Alloc: types.GenesisAlloc{withdrawalAddr: {Balance: bankFunds}}, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(gspec), + execmoduletester.WithAmsterdamBuilderContracts(), + ) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{ Index: 0, @@ -307,7 +311,11 @@ func TestReplayBlockTransactionsMultiWithdrawalSameAddr(t *testing.T) { Config: chain.AllProtocolChanges, Alloc: types.GenesisAlloc{withdrawalAddr: {Balance: testBankFunds()}}, } - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(gspec), + execmoduletester.WithAmsterdamBuilderContracts(), + ) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{Index: 0, Validator: 42, Address: withdrawalAddr, Amount: wd1Gwei}) b.AddWithdrawal(&types.Withdrawal{Index: 1, Validator: 43, Address: withdrawalAddr, Amount: wd2Gwei}) @@ -354,7 +362,11 @@ func TestReplayBlockTransactionsWithdrawalNewAddress(t *testing.T) { // Address intentionally absent from genesis alloc. newAddr := common.HexToAddress("0xaaaabbbbccccddddeeeeffffaaaabbbbccccdddd") gspec := &types.Genesis{Config: chain.AllProtocolChanges} - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(gspec), + execmoduletester.WithAmsterdamBuilderContracts(), + ) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{Index: 0, Validator: 42, Address: newAddr, Amount: withdrawalGwei}) }) @@ -398,7 +410,11 @@ func TestReplayBlockTransactionsMultiWithdrawalNewAddress(t *testing.T) { ) newAddr := common.HexToAddress("0x1111222233334444555566667777888899990000") gspec := &types.Genesis{Config: chain.AllProtocolChanges} - m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) + m := execmoduletester.New( + t, + execmoduletester.WithGenesisSpec(gspec), + execmoduletester.WithAmsterdamBuilderContracts(), + ) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{Index: 0, Validator: 1, Address: newAddr, Amount: wd1Gwei}) b.AddWithdrawal(&types.Withdrawal{Index: 1, Validator: 2, Address: newAddr, Amount: wd2Gwei}) From 6810282a37761adad39abc045f8669616be3bf36 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Mon, 20 Jul 2026 12:49:51 +0000 Subject: [PATCH 09/13] set correct hive eest max failures --- .github/workflows/test-hive-eest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-hive-eest.yml b/.github/workflows/test-hive-eest.yml index ba07c147d7b..81ff1444f41 100644 --- a/.github/workflows/test-hive-eest.yml +++ b/.github/workflows/test-hive-eest.yml @@ -103,7 +103,7 @@ jobs: extra-hive-flags: "--sim.loglevel=3 --client.checktimelimit=300s" erigon-extra-flags: "--experimental.bal" # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-failures: 597 + max-failures: 3532 exec_mode: parallel steps: - name: Clean docker system From 2a2e586f1efee36478a8e734c22917dcb29de802 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Mon, 20 Jul 2026 13:14:51 +0000 Subject: [PATCH 10/13] flip to always add amsterdam contracts in genesis, option to skip --- db/snapshotsync/freezeblocks/dump_test.go | 1 - execution/abi/bind/backends/simulated.go | 7 +- execution/bal/regenerator_test.go | 7 +- .../execmodule/exec_module_devp2p_test.go | 2 - execution/execmodule/exec_module_test.go | 88 ++++--------------- .../execmodule/exec_module_unwind_gap_test.go | 14 +-- .../execmoduletester/exec_module_tester.go | 51 ++++++----- execution/tests/testutil/block_test_util.go | 1 + execution/verify/history_verify_test.go | 2 - rpc/gasprice/gasprice_test.go | 13 +-- rpc/jsonrpc/eth_block_access_list_test.go | 7 +- rpc/jsonrpc/eth_call_test.go | 7 +- rpc/jsonrpc/trace_filtering_test.go | 24 +---- 13 files changed, 57 insertions(+), 167 deletions(-) diff --git a/db/snapshotsync/freezeblocks/dump_test.go b/db/snapshotsync/freezeblocks/dump_test.go index bfb50ad3b94..cfe6572946f 100644 --- a/db/snapshotsync/freezeblocks/dump_test.go +++ b/db/snapshotsync/freezeblocks/dump_test.go @@ -281,7 +281,6 @@ func createDumpTestKV(t *testing.T, chainConfig *chain.Config, chainSize int) *e execmoduletester.WithGenesisSpec(gspec), execmoduletester.WithKey(key), execmoduletester.WithPruneMode(prune.DefaultMode), - execmoduletester.WithAmsterdamBuilderContracts(), ) // Generate testing blocks diff --git a/execution/abi/bind/backends/simulated.go b/execution/abi/bind/backends/simulated.go index c2138c005ff..f4abfed3e7b 100644 --- a/execution/abi/bind/backends/simulated.go +++ b/execution/abi/bind/backends/simulated.go @@ -103,12 +103,7 @@ func NewSimulatedBackendWithConfig(t *testing.T, alloc types.GenesisAlloc, confi engine = ethash.NewFaker() } //SimulatedBackend - it's remote blockchain node. This is reason why it has own `MockSentry` and own `DB` (even if external unit-test have one already) - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(&genesis), - execmoduletester.WithEngine(engine), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(&genesis), execmoduletester.WithEngine(engine)) backend := &SimulatedBackend{ m: m, diff --git a/execution/bal/regenerator_test.go b/execution/bal/regenerator_test.go index 032bbc8394f..2ed381fc38c 100644 --- a/execution/bal/regenerator_test.go +++ b/execution/bal/regenerator_test.go @@ -45,12 +45,7 @@ func TestRegeneratorReproducesCanonicalBlockAccessLists(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) storingInitCode := []byte{0x60, 0x01, 0x60, 0x00, 0x55, 0x00} // PUSH1 1, PUSH1 0, SSTORE, STOP diff --git a/execution/execmodule/exec_module_devp2p_test.go b/execution/execmodule/exec_module_devp2p_test.go index e6b30e975d0..a4241c57339 100644 --- a/execution/execmodule/exec_module_devp2p_test.go +++ b/execution/execmodule/exec_module_devp2p_test.go @@ -72,7 +72,6 @@ func TestGetBlockReceiptsFrozenBlocks(t *testing.T) { }), execmoduletester.WithKey(devp2pTestKey), execmoduletester.WithSentryProtocol(direct.ETH70), - execmoduletester.WithAmsterdamBuilderContracts(), ) signer := types.LatestSignerForChainID(nil) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, frozenChainLength, func(i int, block *blockgen.BlockGen) { @@ -266,7 +265,6 @@ func TestGetBlockAccessListsResponseMatrix(t *testing.T) { }), execmoduletester.WithKey(keyA), execmoduletester.WithSentryProtocol(direct.ETH71), - execmoduletester.WithAmsterdamBuilderContracts(), ) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) diff --git a/execution/execmodule/exec_module_test.go b/execution/execmodule/exec_module_test.go index eca39c653b2..4c15ddf9979 100644 --- a/execution/execmodule/exec_module_test.go +++ b/execution/execmodule/exec_module_test.go @@ -77,7 +77,6 @@ func TestValidateChainWithLastTxNumOfBlockAtStepBoundary(t *testing.T) { execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithStepSize(stepSize), - execmoduletester.WithAmsterdamBuilderContracts(), ) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( @@ -144,12 +143,7 @@ func TestValidateChainAndUpdateForkChoiceWithSideForksThatGoBackAndForwardInHeig senderAddr2: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) longerFork, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( types.NewTransaction(uint64(i), senderAddr, uint256.NewInt(1_000), 50000, uint256.NewInt(m.Genesis.BaseFee().Uint64()), nil), @@ -211,12 +205,7 @@ func TestValidateForkPayloadOffNonTipCanonicalBlockWithCache(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) to := common.Address{0xaa} baseFee := m.Genesis.BaseFee().Uint64() mkTx := func(nonce, amount uint64) types.Transaction { @@ -285,12 +274,7 @@ func TestUpdateForkChoiceRecoversWhenStateAheadOfTxNums(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 10, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( types.NewTransaction(uint64(i), senderAddr, uint256.NewInt(1_000), 50000, uint256.NewInt(m.Genesis.BaseFee().Uint64()), nil), @@ -375,12 +359,7 @@ func TestUpdateForkChoiceForwardExecutesAfterStateAheadRecovery(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 15, func(i int, b *blockgen.BlockGen) { tx, err := types.SignTx( types.NewTransaction(uint64(i), senderAddr, uint256.NewInt(1_000), 50000, uint256.NewInt(m.Genesis.BaseFee().Uint64()), nil), @@ -466,10 +445,7 @@ func TestReorgBackAndForwardIntoCanonicalChain(t *testing.T) { {name: "bg-commit", opt: execmoduletester.WithFcuBackgroundCommit()}, } for _, mode := range modes { - opts := []execmoduletester.Option{ - execmoduletester.WithGenesisSpec(&types.Genesis{Config: chain.AllProtocolChanges}), - execmoduletester.WithAmsterdamBuilderContracts(), - } + opts := []execmoduletester.Option{execmoduletester.WithGenesisSpec(&types.Genesis{Config: chain.AllProtocolChanges})} if mode.opt != nil { opts = append(opts, mode.opt) } @@ -943,12 +919,10 @@ func TestAssembleBlockGasOverflow(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithTxPool(), - execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1258,12 +1232,10 @@ func TestAssembleBlockAmsterdamForkTransition(t *testing.T) { Ethash: new(chain.EthashConfig), } - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithTxPool(), execmoduletester.WithChainConfig(cfg), execmoduletester.WithExperimentalBAL(), - execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1380,12 +1352,7 @@ func TestGetPayloadBodiesRegenerateBlockAccessLists(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { @@ -1452,12 +1419,7 @@ func TestGetPayloadBodiesNonCanonicalBlockAccessList(t *testing.T) { addrB: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKeyA), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKeyA)) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) canonical, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { @@ -1628,12 +1590,10 @@ func TestAssembleBlockStateGasLimit(t *testing.T) { }, } - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithTxPool(), - execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1721,12 +1681,10 @@ func TestAssembleBlockStateGasLimitSSTORE(t *testing.T) { }, } - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), execmoduletester.WithTxPool(), - execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1869,12 +1827,10 @@ func TestAssembleBlockGasPoolSnapshotRestoreBug(t *testing.T) { Alloc: alloc, } - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(keys[0]), execmoduletester.WithTxPool(), - execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -1973,12 +1929,10 @@ func TestAssembleBlockGasPoolMultiBatchInitBug(t *testing.T) { Alloc: alloc, } - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(keys[0]), execmoduletester.WithTxPool(), - execmoduletester.WithAmsterdamBuilderContracts(), ) exec := m.ExecModule txpool := m.TxPoolGrpcServer @@ -2081,11 +2035,9 @@ func TestEIP8246NoBurnLogWhenCoinbaseSelfDestructs(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), ) baseFee := m.Genesis.BaseFee().Uint64() @@ -2162,12 +2114,7 @@ func TestInsertBlocksWithBatchedFCU(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) const totalBlocks = 30 const batchSize = 10 @@ -2240,7 +2187,6 @@ func runBatchedFCUBadBlockRecovery(t *testing.T, bgCommit bool) { opts := []execmoduletester.Option{ execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), } if bgCommit { opts = append(opts, execmoduletester.WithFcuBackgroundCommit()) @@ -2568,8 +2514,7 @@ func runBALFoldAheadChangeset(t *testing.T, foldAhead, shadow bool) balFoldResul privKey, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") require.NoError(t, err) senderAddr := crypto.PubkeyToAddress(privKey.PublicKey) - m := execmoduletester.New( - t, + m := execmoduletester.New(t, execmoduletester.WithKey(privKey), execmoduletester.WithGenesisSpec(&types.Genesis{ Config: chain.AllProtocolChanges, // Amsterdam-at-0 → every block carries a BAL @@ -2578,7 +2523,6 @@ func runBALFoldAheadChangeset(t *testing.T, foldAhead, shadow bool) balFoldResul execmoduletester.WithExperimentalBAL(), execmoduletester.WithAlwaysGenerateChangesets(false), execmoduletester.WithMaxReorgDepth(maxReorgDepth), - execmoduletester.WithAmsterdamBuilderContracts(), ) // AllProtocolChanges is post-London, so txs need a fee cap above the base fee diff --git a/execution/execmodule/exec_module_unwind_gap_test.go b/execution/execmodule/exec_module_unwind_gap_test.go index 4a88d8678e4..6d1acff3a93 100644 --- a/execution/execmodule/exec_module_unwind_gap_test.go +++ b/execution/execmodule/exec_module_unwind_gap_test.go @@ -65,12 +65,7 @@ func TestUpdateForkChoiceBadBlockMidBatchThenRecovery(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) const chainLen = 13 const committedTo = 10 chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, chainLen, func(i int, b *blockgen.BlockGen) { @@ -186,12 +181,7 @@ func TestUpdateForkChoiceBadBlockAtLongBatchTailThenRecovery(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) const chainLen = 35 const committedTo = 26 const badHeight = 35 // tail of the never-validated segment (index badHeight-1) diff --git a/execution/execmodule/execmoduletester/exec_module_tester.go b/execution/execmodule/execmoduletester/exec_module_tester.go index 048e3f8193e..eecc17e96a7 100644 --- a/execution/execmodule/execmoduletester/exec_module_tester.go +++ b/execution/execmodule/execmoduletester/exec_module_tester.go @@ -338,9 +338,9 @@ func WithChainConfig(cfg *chain.Config) Option { } } -func WithAmsterdamBuilderContracts() Option { +func WithoutAmsterdamBuilderContracts() Option { return func(opts *options) { - opts.amsterdamBuilderContracts = true + opts.skipAmsterdamBuilderContracts = true } } @@ -382,21 +382,21 @@ func WithSentryProtocol(protocol uint) Option { } type options struct { - stepSize *uint64 - experimentalBAL bool - genesis *types.Genesis - chainConfig *chain.Config - key *ecdsa.PrivateKey - engine rules.Engine - pruneMode *prune.Mode - withTxPool bool - enableDomains []kv.Domain - fcuBackgroundCommit bool - fcuBackgroundPrune bool - alwaysGenerateChangesets *bool - maxReorgDepth *uint64 - sentryProtocol uint - amsterdamBuilderContracts bool + stepSize *uint64 + experimentalBAL bool + genesis *types.Genesis + chainConfig *chain.Config + key *ecdsa.PrivateKey + engine rules.Engine + pruneMode *prune.Mode + withTxPool bool + enableDomains []kv.Domain + fcuBackgroundCommit bool + fcuBackgroundPrune bool + alwaysGenerateChangesets *bool + maxReorgDepth *uint64 + sentryProtocol uint + skipAmsterdamBuilderContracts bool } func applyOptions(opts []Option) options { @@ -421,11 +421,8 @@ func applyOptions(opts []Option) options { address: {Balance: big.NewInt(1 * common.Ether)}, }, } - if opt.genesis.Config.IsAmsterdam(opt.genesis.Timestamp) { - addAmsterdamBuilderContracts(opt.genesis) - } } - if opt.amsterdamBuilderContracts { + if !opt.skipAmsterdamBuilderContracts { addAmsterdamBuilderContracts(opt.genesis) } // engine depends on genesis @@ -449,8 +446,16 @@ func addAmsterdamBuilderContracts(genesis *types.Genesis) { if genesis.Alloc == nil { genesis.Alloc = types.GenesisAlloc{} } - genesis.Alloc[genesis.Config.GetBuilderDepositContract().Value()] = types.GenesisAccount{Balance: new(big.Int), Code: misc.BuilderDepositRequestCode, Nonce: 1} - genesis.Alloc[genesis.Config.GetBuilderExitContract().Value()] = types.GenesisAccount{Balance: new(big.Int), Code: misc.BuilderExitRequestCode, Nonce: 1} + genesis.Alloc[genesis.Config.GetBuilderDepositContract().Value()] = types.GenesisAccount{ + Balance: new(big.Int), + Code: misc.BuilderDepositRequestCode, + Nonce: 1, + } + genesis.Alloc[genesis.Config.GetBuilderExitContract().Value()] = types.GenesisAccount{ + Balance: new(big.Int), + Code: misc.BuilderExitRequestCode, + Nonce: 1, + } } // New creates an ExecModuleTester. When called with no options, it uses diff --git a/execution/tests/testutil/block_test_util.go b/execution/tests/testutil/block_test_util.go index 78bc20e9397..5a2149a1ab8 100644 --- a/execution/tests/testutil/block_test_util.go +++ b/execution/tests/testutil/block_test_util.go @@ -227,6 +227,7 @@ func (bt *BlockTest) newTester(tb testing.TB) (*execmoduletester.ExecModuleTeste mOpts := []execmoduletester.Option{ execmoduletester.WithGenesisSpec(bt.genesis(config)), execmoduletester.WithEngine(engine), + execmoduletester.WithoutAmsterdamBuilderContracts(), } if bt.ExperimentalBAL { mOpts = append(mOpts, execmoduletester.WithExperimentalBAL()) diff --git a/execution/verify/history_verify_test.go b/execution/verify/history_verify_test.go index e5f05dda233..dbf8bbec4fa 100644 --- a/execution/verify/history_verify_test.go +++ b/execution/verify/history_verify_test.go @@ -51,7 +51,6 @@ func TestHistoryVerification_SimpleBlocks(t *testing.T) { execmoduletester.WithKey(key), execmoduletester.WithStepSize(stepSize), execmoduletester.WithoutExperimentalBAL(), - execmoduletester.WithAmsterdamBuilderContracts(), ) ctx := context.Background() logger := log.New() @@ -138,7 +137,6 @@ func TestHistoryVerification_WithUserTransactions(t *testing.T) { execmoduletester.WithKey(key), execmoduletester.WithStepSize(stepSize), execmoduletester.WithoutExperimentalBAL(), - execmoduletester.WithAmsterdamBuilderContracts(), ) ctx := context.Background() logger := log.New() diff --git a/rpc/gasprice/gasprice_test.go b/rpc/gasprice/gasprice_test.go index 4466fa3761f..085dd23b4fb 100644 --- a/rpc/gasprice/gasprice_test.go +++ b/rpc/gasprice/gasprice_test.go @@ -366,12 +366,7 @@ func TestSuggestTipCap_SparseBlocks(t *testing.T) { Alloc: types.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, } signer := types.LatestSigner(gspec.Config) - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(gspec), - execmoduletester.WithKey(key), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec), execmoduletester.WithKey(key)) // 10 blocks: only the last one (index 9) has a transaction; all others are empty. const totalBlocks = 10 @@ -419,11 +414,7 @@ func TestSuggestTipCap_AllEmptyBlocks(t *testing.T) { } gspec := &types.Genesis{Config: chain.AllProtocolChanges} - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(gspec), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) const totalBlocks = 5 ch, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, totalBlocks, func(_ int, b *blockgen.BlockGen) { diff --git a/rpc/jsonrpc/eth_block_access_list_test.go b/rpc/jsonrpc/eth_block_access_list_test.go index a538b53aa5c..5672380fb98 100644 --- a/rpc/jsonrpc/eth_block_access_list_test.go +++ b/rpc/jsonrpc/eth_block_access_list_test.go @@ -50,12 +50,7 @@ func TestGetBlockAccessListRegeneratesPrunedBAL(t *testing.T) { senderAddr: {Balance: new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)}, }, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(genesis), - execmoduletester.WithKey(privKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(genesis), execmoduletester.WithKey(privKey)) signer := types.LatestSignerForChainID(m.ChainConfig.ChainID) baseFee := uint256.NewInt(m.Genesis.BaseFee().Uint64()) chainPack, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, b *blockgen.BlockGen) { diff --git a/rpc/jsonrpc/eth_call_test.go b/rpc/jsonrpc/eth_call_test.go index b558b1c2429..d645232f900 100644 --- a/rpc/jsonrpc/eth_call_test.go +++ b/rpc/jsonrpc/eth_call_test.go @@ -693,12 +693,7 @@ func fundedBankGenesis(t *testing.T, cfg *chain.Config) (m *execmoduletester.Exe gspec.GasLimit = 60_000_000 } - m = execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(gspec), - execmoduletester.WithKey(bankKey), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m = execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec), execmoduletester.WithKey(bankKey)) return m, bankKey, bankAddress } diff --git a/rpc/jsonrpc/trace_filtering_test.go b/rpc/jsonrpc/trace_filtering_test.go index d4c55be4749..e0504590450 100644 --- a/rpc/jsonrpc/trace_filtering_test.go +++ b/rpc/jsonrpc/trace_filtering_test.go @@ -172,11 +172,7 @@ func chainWithWithdrawal(t *testing.T, withdrawalAddr common.Address, withdrawal Config: chain.AllProtocolChanges, Alloc: types.GenesisAlloc{withdrawalAddr: {Balance: bankFunds}}, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(gspec), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{ Index: 0, @@ -311,11 +307,7 @@ func TestReplayBlockTransactionsMultiWithdrawalSameAddr(t *testing.T) { Config: chain.AllProtocolChanges, Alloc: types.GenesisAlloc{withdrawalAddr: {Balance: testBankFunds()}}, } - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(gspec), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{Index: 0, Validator: 42, Address: withdrawalAddr, Amount: wd1Gwei}) b.AddWithdrawal(&types.Withdrawal{Index: 1, Validator: 43, Address: withdrawalAddr, Amount: wd2Gwei}) @@ -362,11 +354,7 @@ func TestReplayBlockTransactionsWithdrawalNewAddress(t *testing.T) { // Address intentionally absent from genesis alloc. newAddr := common.HexToAddress("0xaaaabbbbccccddddeeeeffffaaaabbbbccccdddd") gspec := &types.Genesis{Config: chain.AllProtocolChanges} - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(gspec), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{Index: 0, Validator: 42, Address: newAddr, Amount: withdrawalGwei}) }) @@ -410,11 +398,7 @@ func TestReplayBlockTransactionsMultiWithdrawalNewAddress(t *testing.T) { ) newAddr := common.HexToAddress("0x1111222233334444555566667777888899990000") gspec := &types.Genesis{Config: chain.AllProtocolChanges} - m := execmoduletester.New( - t, - execmoduletester.WithGenesisSpec(gspec), - execmoduletester.WithAmsterdamBuilderContracts(), - ) + m := execmoduletester.New(t, execmoduletester.WithGenesisSpec(gspec)) generated, err := blockgen.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(_ int, b *blockgen.BlockGen) { b.AddWithdrawal(&types.Withdrawal{Index: 0, Validator: 1, Address: newAddr, Amount: wd1Gwei}) b.AddWithdrawal(&types.Withdrawal{Index: 1, Validator: 2, Address: newAddr, Amount: wd2Gwei}) From 00b240cf0a20829e305563f12d6d8dde5fe7a6f9 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Mon, 20 Jul 2026 13:17:05 +0000 Subject: [PATCH 11/13] fix --- .github/workflows/test-hive-eest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-hive-eest.yml b/.github/workflows/test-hive-eest.yml index 81ff1444f41..ba07c147d7b 100644 --- a/.github/workflows/test-hive-eest.yml +++ b/.github/workflows/test-hive-eest.yml @@ -103,7 +103,7 @@ jobs: extra-hive-flags: "--sim.loglevel=3 --client.checktimelimit=300s" erigon-extra-flags: "--experimental.bal" # TODO: reduce to 0 as tests-glamsterdam-devnet@v7.2.0 support lands. - max-failures: 3532 + max-failures: 597 exec_mode: parallel steps: - name: Clean docker system From acad80007ff4aba85620d91c3aa979378eb5ae06 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Mon, 27 Jul 2026 10:57:38 +0000 Subject: [PATCH 12/13] address nit --- execution/execmodule/execmoduletester/exec_module_tester.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/execution/execmodule/execmoduletester/exec_module_tester.go b/execution/execmodule/execmoduletester/exec_module_tester.go index ae188d26b9e..ee8a2f5f270 100644 --- a/execution/execmodule/execmoduletester/exec_module_tester.go +++ b/execution/execmodule/execmoduletester/exec_module_tester.go @@ -446,15 +446,19 @@ func addAmsterdamBuilderContracts(genesis *types.Genesis) { if genesis.Alloc == nil { genesis.Alloc = types.GenesisAlloc{} } + slot := common.Hash{} + sentinel := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") genesis.Alloc[genesis.Config.GetBuilderDepositContract().Value()] = types.GenesisAccount{ Balance: new(big.Int), Code: misc.BuilderDepositRequestCode, Nonce: 1, + Storage: map[common.Hash]common.Hash{slot: sentinel}, } genesis.Alloc[genesis.Config.GetBuilderExitContract().Value()] = types.GenesisAccount{ Balance: new(big.Int), Code: misc.BuilderExitRequestCode, Nonce: 1, + Storage: map[common.Hash]common.Hash{slot: sentinel}, } } From ffab17e31186230371adba9704534e04781140e6 Mon Sep 17 00:00:00 2001 From: taratorio <94537774+taratorio@users.noreply.github.com> Date: Mon, 27 Jul 2026 12:38:42 +0000 Subject: [PATCH 13/13] address nit --- execution/chain/spec/allocs/dev.json | 4 +--- execution/chain/spec/eip8282_test.go | 20 +++++++++++++------ .../execmoduletester/exec_module_tester.go | 5 ++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/execution/chain/spec/allocs/dev.json b/execution/chain/spec/allocs/dev.json index f31559fc083..fb4f86c4327 100644 --- a/execution/chain/spec/allocs/dev.json +++ b/execution/chain/spec/allocs/dev.json @@ -99,9 +99,7 @@ "balance": "0", "nonce": "1", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1461011c575f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146102705760015460088111605257506058565b60089003015b601190600182026001905f5b5f821115607f57810190830284830290049160010191906064565b90939004925050503660b814609f57366102705734610270575f5260205ff35b8034106102705760383567ffffffffffffffff1680633b9aca001161027057633b9aca00029034031061027057600154600101600155600354806006026004015f358155600101602035815560010160403581556001016060358155600101608035815560010160a035905560b85f5f3760b85fa0600101600355005b60035460025480820380604011610131575060405b5f5b8181146101d7578281016006026004018160b8028154815260200181600101548152602001816002015480825260401c67ffffffffffffffff16816010018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c816001015353602001816003015481526020018160040154815260200190600501549052600101610133565b91018092146101e957906002556101f4565b90505f6002555f6003555b36610242575f54600154817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461023057600882820111610238575b50505f610264565b0160089003610264565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5f555f60015560b8025ff35b5f5ffd", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } + "storage": {} }, "0x000064D678505AD48F8CCB093BC65613800E8282": { "balance": "0", diff --git a/execution/chain/spec/eip8282_test.go b/execution/chain/spec/eip8282_test.go index 747f0d74f2c..b754a5000db 100644 --- a/execution/chain/spec/eip8282_test.go +++ b/execution/chain/spec/eip8282_test.go @@ -28,10 +28,13 @@ import ( func TestDeveloperGenesisBuilderContracts(t *testing.T) { genesis := chainspec.DeveloperGenesisBlock() + sentinel := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") tests := []struct { - name string - address common.Address - code []byte + name string + address common.Address + code []byte + slot0 common.Hash + hasSlot0 bool }{ { name: "deposit", @@ -39,9 +42,11 @@ func TestDeveloperGenesisBuilderContracts(t *testing.T) { code: misc.BuilderDepositRequestCode, }, { - name: "exit", - address: common.HexToAddress("0x000064D678505AD48F8CCB093BC65613800E8282"), - code: misc.BuilderExitRequestCode, + name: "exit", + address: common.HexToAddress("0x000064D678505AD48F8CCB093BC65613800E8282"), + code: misc.BuilderExitRequestCode, + slot0: sentinel, + hasSlot0: true, }, } for _, tt := range tests { @@ -52,6 +57,9 @@ func TestDeveloperGenesisBuilderContracts(t *testing.T) { require.True(t, ok) require.Equal(t, uint64(1), account.Nonce) require.Equal(t, tt.code, account.Code) + slot0, ok := account.Storage[common.Hash{}] + require.Equal(t, tt.hasSlot0, ok) + require.Equal(t, tt.slot0, slot0) }, ) } diff --git a/execution/execmodule/execmoduletester/exec_module_tester.go b/execution/execmodule/execmoduletester/exec_module_tester.go index ee8a2f5f270..b6d57a75102 100644 --- a/execution/execmodule/execmoduletester/exec_module_tester.go +++ b/execution/execmodule/execmoduletester/exec_module_tester.go @@ -446,14 +446,13 @@ func addAmsterdamBuilderContracts(genesis *types.Genesis) { if genesis.Alloc == nil { genesis.Alloc = types.GenesisAlloc{} } - slot := common.Hash{} - sentinel := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") genesis.Alloc[genesis.Config.GetBuilderDepositContract().Value()] = types.GenesisAccount{ Balance: new(big.Int), Code: misc.BuilderDepositRequestCode, Nonce: 1, - Storage: map[common.Hash]common.Hash{slot: sentinel}, } + slot := common.Hash{} + sentinel := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") genesis.Alloc[genesis.Config.GetBuilderExitContract().Value()] = types.GenesisAccount{ Balance: new(big.Int), Code: misc.BuilderExitRequestCode,