From 5b301643730a0d0721c93b67e46651098713788e Mon Sep 17 00:00:00 2001 From: qu0b Date: Tue, 31 Mar 2026 16:38:51 +0000 Subject: [PATCH 01/21] Add Gloas (bal-devnet-3) support via qu0b/go-eth2-client - Replace go-eth2-client with qu0b fork (eip7928 branch) for non-ePBS Gloas SSZ types - Add Gloas/Fulu/Electra cases to block_utils.go - Supports EIP-7928 (BAL), EIP-7843 (SlotNumber), EIP-7954, EIP-8037 --- go.mod | 3 ++- go.sum | 6 ++---- pkg/clients/consensus/block_utils.go | 26 +++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index b9428546..a98f7cee 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,6 @@ require ( require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/OffchainLabs/go-bitfield v0.0.0-20251031151322-f427d04d8506 // indirect github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect @@ -122,3 +121,5 @@ require ( modernc.org/memory v1.11.0 // indirect modernc.org/sqlite v1.46.1 // indirect ) + +replace github.com/attestantio/go-eth2-client => github.com/qu0b/go-eth2-client v0.0.0-20260211134817-89b1d064a7e5 diff --git a/go.sum b/go.sum index a954be12..4f0cadba 100644 --- a/go.sum +++ b/go.sum @@ -7,14 +7,10 @@ github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/OffchainLabs/go-bitfield v0.0.0-20251031151322-f427d04d8506 h1:d/SJkN8/9Ca+1YmuDiUJxAiV4w/a9S8NcsG7GMQSrVI= -github.com/OffchainLabs/go-bitfield v0.0.0-20251031151322-f427d04d8506/go.mod h1:6TZI4FU6zT8x6ZfWa1J8YQ2NgW0wLV/W3fHRca8ISBo= github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= -github.com/attestantio/go-eth2-client v0.28.0 h1:2zIIIMPvSD+g6h3TgVXsoda/Yw3e+wjo1e8CZEanORU= -github.com/attestantio/go-eth2-client v0.28.0/go.mod h1:PO9sHFCq+1RiG+Eh3eOR2GYvYV64Qzg7idM3kLgCs5k= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= @@ -280,6 +276,8 @@ github.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15 h1:lC8ki github.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15/go.mod h1:8svFBIKKu31YriBG/pNizo9N0Jr9i5PQ+dFkxWg3x5k= github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4= github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs= +github.com/qu0b/go-eth2-client v0.0.0-20260211134817-89b1d064a7e5 h1:KhHr85BKhGb+5q8npUuMTxwcUGvtzk9P3ZnBwd++Tbo= +github.com/qu0b/go-eth2-client v0.0.0-20260211134817-89b1d064a7e5/go.mod h1:fvULSL9WtNskkOB4i+Yyr6BKpNHXvmpGZj9969fCrfY= github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= diff --git a/pkg/clients/consensus/block_utils.go b/pkg/clients/consensus/block_utils.go index 52a352cc..9df2b31f 100644 --- a/pkg/clients/consensus/block_utils.go +++ b/pkg/clients/consensus/block_utils.go @@ -23,10 +23,28 @@ func GetExecutionExtraData(v *spec.VersionedSignedBeaconBlock) ([]byte, error) { return v.Capella.Message.Body.ExecutionPayload.ExtraData, nil case spec.DataVersionDeneb: if v.Deneb == nil || v.Deneb.Message == nil || v.Deneb.Message.Body == nil || v.Deneb.Message.Body.ExecutionPayload == nil { - return nil, errors.New("no denb block") + return nil, errors.New("no deneb block") } return v.Deneb.Message.Body.ExecutionPayload.ExtraData, nil + case spec.DataVersionElectra: + if v.Electra == nil || v.Electra.Message == nil || v.Electra.Message.Body == nil || v.Electra.Message.Body.ExecutionPayload == nil { + return nil, errors.New("no electra block") + } + + return v.Electra.Message.Body.ExecutionPayload.ExtraData, nil + case spec.DataVersionFulu: + if v.Fulu == nil || v.Fulu.Message == nil || v.Fulu.Message.Body == nil || v.Fulu.Message.Body.ExecutionPayload == nil { + return nil, errors.New("no fulu block") + } + + return v.Fulu.Message.Body.ExecutionPayload.ExtraData, nil + case spec.DataVersionGloas: + if v.Gloas == nil || v.Gloas.Message == nil || v.Gloas.Message.Body == nil || v.Gloas.Message.Body.ExecutionPayload == nil { + return nil, errors.New("no gloas block") + } + + return v.Gloas.Message.Body.ExecutionPayload.ExtraData, nil default: return nil, errors.New("unknown version") } @@ -45,6 +63,12 @@ func GetBlockBody(v *spec.VersionedSignedBeaconBlock) any { return v.Capella case spec.DataVersionDeneb: return v.Deneb + case spec.DataVersionElectra: + return v.Electra + case spec.DataVersionFulu: + return v.Fulu + case spec.DataVersionGloas: + return v.Gloas default: return nil } From 046ab547516b99902c18e67980fa3bf0187d5a5e Mon Sep 17 00:00:00 2001 From: qu0b Date: Tue, 31 Mar 2026 16:39:20 +0000 Subject: [PATCH 02/21] trigger CI From 9aa932c22c0cedc4ea50a0174279f789ec702caa Mon Sep 17 00:00:00 2001 From: qu0b Date: Tue, 31 Mar 2026 16:45:11 +0000 Subject: [PATCH 03/21] fix: add nolint for cyclomatic complexity in block_utils --- pkg/clients/consensus/block_utils.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/clients/consensus/block_utils.go b/pkg/clients/consensus/block_utils.go index 9df2b31f..5956981e 100644 --- a/pkg/clients/consensus/block_utils.go +++ b/pkg/clients/consensus/block_utils.go @@ -6,6 +6,7 @@ import ( "github.com/attestantio/go-eth2-client/spec" ) +//nolint:gocyclo // switch over all fork versions func GetExecutionExtraData(v *spec.VersionedSignedBeaconBlock) ([]byte, error) { //nolint:exhaustive // ignore switch v.Version { From 63fce5c9114a624c968606de85957ffe481a967c Mon Sep 17 00:00:00 2001 From: qu0b Date: Tue, 31 Mar 2026 17:06:11 +0000 Subject: [PATCH 04/21] debug: add attestation vote counting logging --- .../check_consensus_attestation_stats/task.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pkg/tasks/check_consensus_attestation_stats/task.go b/pkg/tasks/check_consensus_attestation_stats/task.go index 957c9cfd..92a6df73 100644 --- a/pkg/tasks/check_consensus_attestation_stats/task.go +++ b/pkg/tasks/check_consensus_attestation_stats/task.go @@ -469,21 +469,27 @@ func (t *Task) aggregateEpochVotes(ctx context.Context, epoch uint64) []*epochVo attestationsVersioned, err := blockBody.Attestations() if err != nil { + t.logger.Warnf("aggregateEpochVotes slot %v: Attestations() error: %v", slot, err) continue } + t.logger.Infof("aggregateEpochVotes slot %v: %v attestations, version %v, maxCommittees %v", slot, len(attestationsVersioned), blockBody.Version, specs.MaxCommitteesPerSlot) + for attIdx, att := range attestationsVersioned { attData, err1 := att.Data() if err1 != nil { + t.logger.Warnf("aggregateEpochVotes slot %v att %v: Data() error: %v", slot, attIdx, err1) continue } if uint64(attData.Slot)/specs.SlotsPerEpoch != epoch { + t.logger.Infof("aggregateEpochVotes slot %v att %v: skip epoch mismatch (att epoch %v, want %v)", slot, attIdx, uint64(attData.Slot)/specs.SlotsPerEpoch, epoch) continue } attAggregationBits, err := att.AggregationBits() if err != nil { + t.logger.Warnf("aggregateEpochVotes slot %v att %v: AggregationBits() error: %v", slot, attIdx, err) continue } @@ -495,10 +501,12 @@ func (t *Task) aggregateEpochVotes(ctx context.Context, epoch uint64) []*epochVo // there can now be attestations from all committees aggregated into a single attestation aggregate committeeBits, err := att.CommitteeBits() if err != nil { - t.logger.Debugf("aggregateEpochVotes slot %v failed, can't get committeeBits for attestation %v: %v", slot, attIdx, err) + t.logger.Warnf("aggregateEpochVotes slot %v att %v: CommitteeBits() error: %v", slot, attIdx, err) continue } + t.logger.Infof("aggregateEpochVotes slot %v att %v: electra+ path, committeeBits=%x, aggBitsLen=%v, attSlot=%v", slot, attIdx, []byte(committeeBits), attAggregationBits.Len(), attData.Slot) + aggregationBitsOffset := uint64(0) for committee := uint64(0); committee < specs.MaxCommitteesPerSlot; committee++ { @@ -506,6 +514,13 @@ func (t *Task) aggregateEpochVotes(ctx context.Context, epoch uint64) []*epochVo continue } + attKey := fmt.Sprintf("%v-%v", uint64(attData.Slot), committee) + dutyCount := 0 + if votes.attesterDuties != nil && votes.attesterDuties.duties[attKey] != nil { + dutyCount = len(votes.attesterDuties.duties[attKey]) + } + t.logger.Infof("aggregateEpochVotes slot %v att %v committee %v: key=%v, duties=%v", slot, attIdx, committee, attKey, dutyCount) + voteAmt, voteCnt, committeeSize := t.aggregateAttestationVotes(votes, uint64(attData.Slot), committee, attAggregationBits, 0) voteAmount += voteAmt voteCount += voteCnt From 73f24e63ea4cdeddf6dc53dd61b27bb872f6c2e4 Mon Sep 17 00:00:00 2001 From: qu0b Date: Tue, 31 Mar 2026 17:21:04 +0000 Subject: [PATCH 05/21] fix: Bitvector64 BitAt fails with minimal preset committeeBits go-bitfield's Bitvector64.BitAt() requires exactly 8 bytes but with minimal preset (MAX_COMMITTEES_PER_SLOT=4), committeeBits is only 1 byte in SSZ. This caused all committee bit checks to return false, resulting in 0% attestation vote counts. Work around by checking the raw bytes directly instead of using BitAt(). --- .../check_consensus_attestation_stats/task.go | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/pkg/tasks/check_consensus_attestation_stats/task.go b/pkg/tasks/check_consensus_attestation_stats/task.go index 92a6df73..fb3a704e 100644 --- a/pkg/tasks/check_consensus_attestation_stats/task.go +++ b/pkg/tasks/check_consensus_attestation_stats/task.go @@ -469,27 +469,21 @@ func (t *Task) aggregateEpochVotes(ctx context.Context, epoch uint64) []*epochVo attestationsVersioned, err := blockBody.Attestations() if err != nil { - t.logger.Warnf("aggregateEpochVotes slot %v: Attestations() error: %v", slot, err) continue } - t.logger.Infof("aggregateEpochVotes slot %v: %v attestations, version %v, maxCommittees %v", slot, len(attestationsVersioned), blockBody.Version, specs.MaxCommitteesPerSlot) - for attIdx, att := range attestationsVersioned { attData, err1 := att.Data() if err1 != nil { - t.logger.Warnf("aggregateEpochVotes slot %v att %v: Data() error: %v", slot, attIdx, err1) continue } if uint64(attData.Slot)/specs.SlotsPerEpoch != epoch { - t.logger.Infof("aggregateEpochVotes slot %v att %v: skip epoch mismatch (att epoch %v, want %v)", slot, attIdx, uint64(attData.Slot)/specs.SlotsPerEpoch, epoch) continue } attAggregationBits, err := att.AggregationBits() if err != nil { - t.logger.Warnf("aggregateEpochVotes slot %v att %v: AggregationBits() error: %v", slot, attIdx, err) continue } @@ -501,25 +495,26 @@ func (t *Task) aggregateEpochVotes(ctx context.Context, epoch uint64) []*epochVo // there can now be attestations from all committees aggregated into a single attestation aggregate committeeBits, err := att.CommitteeBits() if err != nil { - t.logger.Warnf("aggregateEpochVotes slot %v att %v: CommitteeBits() error: %v", slot, attIdx, err) + t.logger.Debugf("aggregateEpochVotes slot %v failed, can't get committeeBits for attestation %v: %v", slot, attIdx, err) continue } - t.logger.Infof("aggregateEpochVotes slot %v att %v: electra+ path, committeeBits=%x, aggBitsLen=%v, attSlot=%v", slot, attIdx, []byte(committeeBits), attAggregationBits.Len(), attData.Slot) - aggregationBitsOffset := uint64(0) for committee := uint64(0); committee < specs.MaxCommitteesPerSlot; committee++ { - if !committeeBits.BitAt(committee) { - continue + // Workaround for go-bitfield Bitvector64 requiring exactly 8 bytes. + // With minimal preset, committeeBits may be shorter. Check raw bytes directly. + byteIdx := committee / 8 + bitIdx := committee % 8 + + hasBit := false + if int(byteIdx) < len(committeeBits) { + hasBit = committeeBits[byteIdx]&(1< Date: Tue, 31 Mar 2026 20:04:01 +0000 Subject: [PATCH 06/21] Add bal-devnet-3 EELS playbook with all EIPs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Self-contained playbook that: - Installs Python/uv at runtime - Clones EELS (execution-specs) devnets/bal/3 branch - Runs execute remote against live RPC for all 7 bal-devnet-3 EIPs - Uses --sender-fund-refund-gas-limit=200000 for EIP-8037 state gas - Produces per-EIP JSON/HTML reports Also fixes typo in existing playbook (execution-spec → execution-specs). --- .../bal-devnet-3-eels-tests.yaml | 380 ++++++++++++++++++ .../execution-sec-tests-sequential.yaml | 2 +- 2 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 playbooks/glamsterdam-dev/bal-devnet-3-eels-tests.yaml diff --git a/playbooks/glamsterdam-dev/bal-devnet-3-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-3-eels-tests.yaml new file mode 100644 index 00000000..eba4ad1e --- /dev/null +++ b/playbooks/glamsterdam-dev/bal-devnet-3-eels-tests.yaml @@ -0,0 +1,380 @@ +id: bal-devnet-3-eels-tests +name: "bal-devnet-3: Run EELS execution spec tests (all EIPs)" +timeout: 4h +config: + walletPrivkey: "" + walletSeed: "spectests-bal3" + specTestsBranch: "devnets/bal/3" +tasks: + # install python + deps + - name: run_shell + title: "Install Python and build dependencies" + id: deps + timeout: 10m + config: + shell: bash + command: | + set -e + sudo dpkg --add-architecture amd64 + sudo apt-get update + sudo apt-get install -y build-essential python3 python3-pip python3-dev libc6:amd64 autoconf automake libffi-dev libtool pkg-config + sudo rm /usr/lib/python3*/EXTERNALLY-MANAGED 2>/dev/null || true + pip install uv + + # clone EELS repo + - name: run_shell + title: "Clone EELS (execution-specs)" + id: setup + timeout: 10m + config: + shell: bash + shellArgs: [--login] + envVars: + GIT_BRANCH: specTestsBranch + command: | + set -e + GIT_BRANCH=$(echo $GIT_BRANCH | jq -r) + + EELS_DIR=$(mktemp -d -t eels-bal3-XXXXXXXXXX) + echo "::set-var eelsDir ${EELS_DIR}" + echo "${EELS_DIR}" > $ASSERTOOR_SUMMARY + + git clone https://github.com/ethereum/execution-specs.git \ + --depth 1 --branch ${GIT_BRANCH} --single-branch ${EELS_DIR} + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + uv sync --all-extras + + echo "EELS environment ready at ${EELS_DIR}" + + - name: check_clients_are_healthy + title: "Check if at least one client is ready" + id: clientCheck + timeout: 5m + config: + minClientCount: 1 + + - name: generate_child_wallet + id: specTestsWallet + title: "Generate funded wallet for tests" + config: + prefundMinBalance: 1000000000000000000000000 # 1000000 ETH + configVars: + privateKey: "walletPrivkey" + walletSeed: "walletSeed" + + # wait for gloas activation + - name: get_consensus_specs + id: consensusSpecs + title: "Get consensus chain specs" + - name: check_consensus_slot_range + title: "Wait for Gloas activation" + timeout: 1h + configVars: + minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" + + # run tests per EIP sequentially + - name: run_tasks + title: "Run bal-devnet-3 EELS tests" + id: tests + config: + continueOnFailure: true + tasks: + - name: run_shell + title: "EIP-7708: ETH transfers emit a log" + id: eip7708 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7708_eth_transfer_logs \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7708.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7708.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7708.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7708.json) + echo "EIP-7708: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7778: Block gas accounting without refunds" + id: eip7778 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7778_block_gas_accounting_without_refunds \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7778.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7778.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7778.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7778.json) + echo "EIP-7778: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7843: SLOTNUM opcode" + id: eip7843 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7843_slotnum \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7843.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7843.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7843.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7843.json) + echo "EIP-7843: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7928: Block-level access lists (BAL)" + id: eip7928 + timeout: 2h + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7928_block_level_access_lists \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + -n 16 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7928.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7928.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7928.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7928.json) + echo "EIP-7928: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7954: Increase maximum contract size" + id: eip7954 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7954_increase_max_contract_size \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7954.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7954.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7954.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7954.json) + echo "EIP-7954: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-8024: Backward compatible SWAPN, DUPN, EXCHANGE" + id: eip8024 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip8024_dupn_swapn_exchange \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip8024.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip8024.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip8024.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip8024.json) + echo "EIP-8024: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-8037: State creation gas cost increase" + id: eip8037 + timeout: 2h + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip8037_state_creation_gas_cost_increase \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + -n 16 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip8037.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip8037.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip8037.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip8037.json) + echo "EIP-8037: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + +cleanupTasks: + - name: run_shell + title: "Cleanup EELS temp dir" + config: + shell: bash + envVars: + EELS_DIR: eelsDir + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + if [ ! -z "$EELS_DIR" ] && [ -d "$EELS_DIR" ]; then + rm -rf $EELS_DIR + echo "Cleaned up ${EELS_DIR}" + fi diff --git a/playbooks/glamsterdam-dev/execution-sec-tests-sequential.yaml b/playbooks/glamsterdam-dev/execution-sec-tests-sequential.yaml index 89f14d0c..ac5ebcfb 100644 --- a/playbooks/glamsterdam-dev/execution-sec-tests-sequential.yaml +++ b/playbooks/glamsterdam-dev/execution-sec-tests-sequential.yaml @@ -36,7 +36,7 @@ tasks: config: testFile: /tests/execution-spec-tests-execute.yaml testConfig: - gitRepo: https://github.com/ethereum/execution-spec.git + gitRepo: https://github.com/ethereum/execution-specs.git runTests: false testConfigVars: specTestsPath: "tasks.tempdir.outputs.path" From 4cd9b844e35e16239c2b669eba186b4da4437541 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Sun, 12 Apr 2026 10:31:00 +0200 Subject: [PATCH 07/21] fix: merge conflict --- pkg/tasks/check_consensus_sync_status/task.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pkg/tasks/check_consensus_sync_status/task.go b/pkg/tasks/check_consensus_sync_status/task.go index 0bde1b07..248ad82c 100644 --- a/pkg/tasks/check_consensus_sync_status/task.go +++ b/pkg/tasks/check_consensus_sync_status/task.go @@ -214,13 +214,21 @@ func (t *Task) processClientCheck(client *clients.PoolClient, syncStatus *rpc.Sy } func (t *Task) getClientInfo(client *clients.PoolClient, syncStatus *rpc.SyncStatus) *ClientInfo { - clientInfo := &ClientInfo{ + if syncStatus == nil { + // RPC failed — return skeletal info without dereferencing. + return &ClientInfo{ + Name: client.Config.Name, + Synchronizing: true, // assume unhealthy when status is unknown + SyncHead: 0, + SyncDistance: 0, + } + } + + return &ClientInfo{ Name: client.Config.Name, Synchronizing: syncStatus.IsSyncing, Optimistic: syncStatus.IsOptimistic, SyncHead: syncStatus.HeadSlot, SyncDistance: syncStatus.SyncDistance, } - - return clientInfo } From 5e4691bd7f3b5e62c4f451052857ec771507512e Mon Sep 17 00:00:00 2001 From: qu0b Date: Sun, 26 Apr 2026 11:42:11 +0000 Subject: [PATCH 08/21] Add bal-devnet-4 EELS playbook with all 9 spec-testable EIPs (v5.7.0) Pinned to tests-bal@v5.7.0 (commit 524b446 on devnets/bal/4). Adds new EIP-7976 (calldata floor cost) and EIP-7981 (access list cost) test blocks; carries over 7708/7778/7843/7928/7954/8024/8037 from the bal-devnet-3 playbook. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../bal-devnet-4-eels-tests.yaml | 461 ++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml new file mode 100644 index 00000000..e0b53191 --- /dev/null +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -0,0 +1,461 @@ +id: bal-devnet-4-eels-tests +name: "bal-devnet-4: Run EELS execution spec tests (all EIPs, tests-bal@v5.7.0)" +timeout: 4h +config: + walletPrivkey: "" + walletSeed: "spectests-bal4" + # Pin to the v5.7.0 release tag for determinism (commit 524b446 on devnets/bal/4). + specTestsBranch: "tests-bal@v5.7.0" +tasks: + # install python + deps + - name: run_shell + title: "Install Python and build dependencies" + id: deps + timeout: 10m + config: + shell: bash + command: | + set -e + sudo dpkg --add-architecture amd64 + sudo apt-get update + sudo apt-get install -y build-essential python3 python3-pip python3-dev libc6:amd64 autoconf automake libffi-dev libtool pkg-config + sudo rm /usr/lib/python3*/EXTERNALLY-MANAGED 2>/dev/null || true + pip install uv + + # clone EELS repo + - name: run_shell + title: "Clone EELS (execution-specs)" + id: setup + timeout: 10m + config: + shell: bash + shellArgs: [--login] + envVars: + GIT_BRANCH: specTestsBranch + command: | + set -e + GIT_BRANCH=$(echo $GIT_BRANCH | jq -r) + + EELS_DIR=$(mktemp -d -t eels-bal4-XXXXXXXXXX) + echo "::set-var eelsDir ${EELS_DIR}" + echo "${EELS_DIR}" > $ASSERTOOR_SUMMARY + + git clone https://github.com/ethereum/execution-specs.git \ + --depth 1 --branch ${GIT_BRANCH} --single-branch ${EELS_DIR} + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + uv sync --all-extras + + echo "EELS environment ready at ${EELS_DIR}" + + - name: check_clients_are_healthy + title: "Check if at least one client is ready" + id: clientCheck + timeout: 5m + config: + minClientCount: 1 + + - name: generate_child_wallet + id: specTestsWallet + title: "Generate funded wallet for tests" + config: + prefundMinBalance: 1000000000000000000000000 # 1000000 ETH + configVars: + privateKey: "walletPrivkey" + walletSeed: "walletSeed" + + # wait for gloas activation + - name: get_consensus_specs + id: consensusSpecs + title: "Get consensus chain specs" + - name: check_consensus_slot_range + title: "Wait for Gloas activation" + timeout: 1h + configVars: + minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" + + # run tests per EIP sequentially + - name: run_tasks + title: "Run bal-devnet-4 EELS tests" + id: tests + config: + continueOnFailure: true + tasks: + - name: run_shell + title: "EIP-7708: ETH transfers emit a log (incl. CREATE/CREATE2)" + id: eip7708 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7708_eth_transfer_logs \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7708.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7708.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7708.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7708.json) + echo "EIP-7708: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7778: Block gas accounting without refunds" + id: eip7778 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7778_block_gas_accounting_without_refunds \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7778.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7778.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7778.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7778.json) + echo "EIP-7778: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7843: SLOTNUM opcode" + id: eip7843 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7843_slotnum \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7843.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7843.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7843.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7843.json) + echo "EIP-7843: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7928: Block-level access lists (BAL, uint32 index)" + id: eip7928 + timeout: 2h + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7928_block_level_access_lists \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + -n 16 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7928.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7928.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7928.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7928.json) + echo "EIP-7928: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7954: Increase maximum contract size (24K → 32K)" + id: eip7954 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7954_increase_max_contract_size \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7954.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7954.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7954.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7954.json) + echo "EIP-7954: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7976: Increase calldata floor cost (NEW for devnet-4)" + id: eip7976 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7976_increase_calldata_floor_cost \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7976.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7976.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7976.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7976.json) + echo "EIP-7976: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-7981: Increase access list cost (NEW for devnet-4)" + id: eip7981 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip7981_increase_access_list_cost \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7981.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7981.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7981.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7981.json) + echo "EIP-7981: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-8024: Backward compatible SWAPN, DUPN, EXCHANGE" + id: eip8024 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip8024_dupn_swapn_exchange \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip8024.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip8024.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip8024.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip8024.json) + echo "EIP-8024: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: run_shell + title: "EIP-8037: State creation gas cost increase (dynamic cpsb)" + id: eip8037 + timeout: 2h + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export HOME=${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + + uv run execute remote ./tests/amsterdam/eip8037_state_creation_gas_cost_increase \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + -n 16 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip8037.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip8037.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip8037.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip8037.json) + echo "EIP-8037: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + +cleanupTasks: + - name: run_shell + title: "Cleanup EELS temp dir" + config: + shell: bash + envVars: + EELS_DIR: eelsDir + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + if [ ! -z "$EELS_DIR" ] && [ -d "$EELS_DIR" ]; then + rm -rf $EELS_DIR + echo "Cleaned up ${EELS_DIR}" + fi From 66efe9d6292b1bd396844beb5b68faf9dbae1e83 Mon Sep 17 00:00:00 2001 From: qu0b Date: Sun, 26 Apr 2026 11:58:12 +0000 Subject: [PATCH 09/21] Fix uv PATH ordering in bal-devnet-4 EELS playbook Each task was overriding HOME=${EELS_DIR} BEFORE setting PATH=$PATH:$HOME/.local/bin, so PATH ended up pointing to the empty freshly-created EELS_DIR/.local/bin instead of the user's actual ~/.local/bin where pip-installed uv lives. Result: setup task failed with exit 127 (uv not found) before any EIP test could run. Swap the export order in all 10 task blocks (setup + 9 EIP tasks) so PATH is computed against the original $HOME before HOME is overridden for cache isolation. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../bal-devnet-4-eels-tests.yaml | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml index e0b53191..507cde0f 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -44,8 +44,10 @@ tasks: --depth 1 --branch ${GIT_BRANCH} --single-branch ${EELS_DIR} cd ${EELS_DIR} - export HOME=${EELS_DIR} + # Capture uv on PATH using the original $HOME (where pip --user installed it) + # BEFORE overriding HOME to isolate uv's cache to EELS_DIR. export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv sync --all-extras echo "EELS environment ready at ${EELS_DIR}" @@ -103,8 +105,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip7708_eth_transfer_logs \ --fork=Amsterdam \ @@ -143,8 +145,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip7778_block_gas_accounting_without_refunds \ --fork=Amsterdam \ @@ -183,8 +185,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip7843_slotnum \ --fork=Amsterdam \ @@ -223,8 +225,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip7928_block_level_access_lists \ --fork=Amsterdam \ @@ -264,8 +266,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip7954_increase_max_contract_size \ --fork=Amsterdam \ @@ -304,8 +306,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip7976_increase_calldata_floor_cost \ --fork=Amsterdam \ @@ -344,8 +346,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip7981_increase_access_list_cost \ --fork=Amsterdam \ @@ -384,8 +386,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip8024_dupn_swapn_exchange \ --fork=Amsterdam \ @@ -424,8 +426,8 @@ tasks: PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) cd ${EELS_DIR} - export HOME=${EELS_DIR} export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} uv run execute remote ./tests/amsterdam/eip8037_state_creation_gas_cost_increase \ --fork=Amsterdam \ From 9b2ddffd0c3e60ef9868ea12b41e69295c44e8a8 Mon Sep 17 00:00:00 2001 From: qu0b Date: Sun, 26 Apr 2026 12:06:07 +0000 Subject: [PATCH 10/21] fix(run_shell): inherit os.Environ so spawned shells have HOME/PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit run_shell builds command.Env from scratch with only user-supplied envVars, ASSERTOOR_SUMMARY, and ASSERTOOR_RESULT_DIR. Once command.Env is non-nil, exec.Command stops inheriting the parent process environment (Go's documented behavior), so the spawned shell starts with empty HOME, PATH, USER, etc. This breaks any playbook that relies on standard env. In our bal-devnet EELS playbooks, the script does `export PATH=\$PATH:\$HOME/.local/bin` to pick up pip --user installed binaries (uv) — with HOME="" and PATH="" this resolves to ":/.local/bin" and fails with `uv: command not found` (exit 127). The bal-devnet-3 playbook has the same latent bug. Fix: prepend os.Environ() to command.Env. User-supplied envVars are appended after and still override inherited values. Co-Authored-By: Claude Opus 4.7 (1M context) --- pkg/tasks/run_shell/task.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/tasks/run_shell/task.go b/pkg/tasks/run_shell/task.go index 9ec9efcd..be7b91e2 100644 --- a/pkg/tasks/run_shell/task.go +++ b/pkg/tasks/run_shell/task.go @@ -101,6 +101,12 @@ func (t *Task) Execute(ctx context.Context) error { //nolint:gosec // ignore command := exec.CommandContext(ctx, t.config.Shell, t.config.ShellArgs...) + // Inherit parent environment so spawned shells have HOME/PATH/USER set. + // Without this, scripts like `export PATH=$PATH:$HOME/.local/bin` resolve + // $HOME to "" and never find user-installed binaries (e.g. uv from + // `pip install --user uv`). User-supplied envVars below still override. + command.Env = append(command.Env, os.Environ()...) + stdin, err := command.StdinPipe() if err != nil { cmdLogger.Errorf("failed getting stdin pipe") From 38ccee54e7fe78683f7bdf38bec745fd6229780c Mon Sep 17 00:00:00 2001 From: qu0b Date: Sun, 26 Apr 2026 19:22:48 +0000 Subject: [PATCH 11/21] fix(playbook): prevent apt-get from consuming stdin in deps task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task 1 was silently truncating after "Processing triggers" — pip install uv never ran, and task 2 failed with `bash: line 16: uv: command not found`. Root cause: assertoor pipes the command to bash via stdin, then closes stdin when done writing. apt-get / dpkg post-install scripts can read from stdin in interactive mode; once dpkg consumes the rest of the script bytes, bash sees EOF and exits without reaching `pip install uv`. Fix: set DEBIAN_FRONTEND=noninteractive and explicitly redirect stdin from /dev/null on every apt invocation. Same applies to dpkg --add-architecture. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../glamsterdam-dev/bal-devnet-4-eels-tests.yaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml index 507cde0f..47e08434 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -16,9 +16,15 @@ tasks: shell: bash command: | set -e - sudo dpkg --add-architecture amd64 - sudo apt-get update - sudo apt-get install -y build-essential python3 python3-pip python3-dev libc6:amd64 autoconf automake libffi-dev libtool pkg-config + # apt-get / dpkg can consume stdin during package configure when run via + # assertoor's stdin-pipe shell; that swallows the rest of this script + # silently (script ends before pip install uv). Force non-interactive + # mode and redirect stdin from /dev/null on every apt invocation so + # nothing reads our pipe. + export DEBIAN_FRONTEND=noninteractive + sudo dpkg --add-architecture amd64 < /dev/null + sudo apt-get update < /dev/null + sudo apt-get install -y build-essential python3 python3-pip python3-dev libc6:amd64 autoconf automake libffi-dev libtool pkg-config < /dev/null sudo rm /usr/lib/python3*/EXTERNALLY-MANAGED 2>/dev/null || true pip install uv From 2545ee8f2d6e69e1e1628646d94326a6c86e1430 Mon Sep 17 00:00:00 2001 From: qu0b Date: Sun, 26 Apr 2026 21:06:08 +0000 Subject: [PATCH 12/21] fix(playbook): isolate seed wallet per EIP test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All 9 sequential EIP tests previously shared the same --rpc-seed-key (tasks.specTestsWallet.outputs.childWallet.privkey). When one EIP test's funding tx hung in mempool — e.g. the prior run hit a "Replacement transaction underpriced" error at nonce 0x62 (98) that blocked all 80 remaining tests in EIP-7708 — the shared wallet's nonce became corrupted and every subsequent EIP test inherited the same stuck nonce. Insert a generate_child_wallet task before each EIP run_shell with a unique walletSeed (spectests-bal4-eip7708, ...-eip7778, etc.). Each EIP test now uses its own freshly-funded child wallet derived from walletPrivkey, so nonce collisions across tests are impossible. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../bal-devnet-4-eels-tests.yaml | 90 +++++++++++++++++-- 1 file changed, 81 insertions(+), 9 deletions(-) diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml index 47e08434..b2dda5be 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -91,6 +91,14 @@ tasks: config: continueOnFailure: true tasks: + - name: generate_child_wallet + id: walletEip7708 + title: "Generate fresh wallet for EIP-7708" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip7708" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-7708: ETH transfers emit a log (incl. CREATE/CREATE2)" id: eip7708 @@ -102,7 +110,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip7708.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -131,6 +139,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip7778 + title: "Generate fresh wallet for EIP-7778" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip7778" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-7778: Block gas accounting without refunds" id: eip7778 @@ -142,7 +158,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip7778.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -171,6 +187,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip7843 + title: "Generate fresh wallet for EIP-7843" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip7843" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-7843: SLOTNUM opcode" id: eip7843 @@ -182,7 +206,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip7843.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -211,6 +235,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip7928 + title: "Generate fresh wallet for EIP-7928" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip7928" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-7928: Block-level access lists (BAL, uint32 index)" id: eip7928 @@ -222,7 +254,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip7928.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -252,6 +284,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip7954 + title: "Generate fresh wallet for EIP-7954" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip7954" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-7954: Increase maximum contract size (24K → 32K)" id: eip7954 @@ -263,7 +303,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip7954.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -292,6 +332,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip7976 + title: "Generate fresh wallet for EIP-7976" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip7976" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-7976: Increase calldata floor cost (NEW for devnet-4)" id: eip7976 @@ -303,7 +351,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip7976.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -332,6 +380,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip7981 + title: "Generate fresh wallet for EIP-7981" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip7981" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-7981: Increase access list cost (NEW for devnet-4)" id: eip7981 @@ -343,7 +399,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip7981.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -372,6 +428,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip8024 + title: "Generate fresh wallet for EIP-8024" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip8024" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-8024: Backward compatible SWAPN, DUPN, EXCHANGE" id: eip8024 @@ -383,7 +447,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip8024.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) @@ -412,6 +476,14 @@ tasks: echo "::set-output passed ${PASSED}" echo "::set-output total ${TOTAL}" + - name: generate_child_wallet + id: walletEip8037 + title: "Generate fresh wallet for EIP-8037" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip8037" + configVars: + privateKey: "walletPrivkey" - name: run_shell title: "EIP-8037: State creation gas cost increase (dynamic cpsb)" id: eip8037 @@ -423,7 +495,7 @@ tasks: EELS_DIR: eelsDir CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl - PRIVATE_KEY: tasks.specTestsWallet.outputs.childWallet.privkey + PRIVATE_KEY: tasks.walletEip8037.outputs.childWallet.privkey command: | set -e EELS_DIR=$(echo $EELS_DIR | jq -r) From 54e3b49a2372fcf3b800a39c6bfdc228dac54942 Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 11:27:48 +0000 Subject: [PATCH 13/21] Add EIP-8024 stack_235-only debug playbook --- .../bal-devnet-4-eip8024-stack235-only.yaml | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml new file mode 100644 index 00000000..96768752 --- /dev/null +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml @@ -0,0 +1,122 @@ +id: bal-devnet-4-eip8024-stack235-only +name: "bal-devnet-4: Run EELS EIP-8024 swapn_stack_235 only (debug repro)" +timeout: 1h +config: + walletPrivkey: "" + walletSeed: "spectests-bal4-stack235" + specTestsBranch: "tests-bal@v5.7.0" +tasks: + - name: run_shell + title: "Install Python and build dependencies" + id: deps + timeout: 10m + config: + shell: bash + command: | + set -e + export DEBIAN_FRONTEND=noninteractive + sudo dpkg --add-architecture amd64 < /dev/null + sudo apt-get update < /dev/null + sudo apt-get install -y build-essential python3 python3-pip python3-dev libc6:amd64 autoconf automake libffi-dev libtool pkg-config < /dev/null + sudo rm /usr/lib/python3*/EXTERNALLY-MANAGED 2>/dev/null || true + pip install uv + + - name: run_shell + title: "Clone EELS (execution-specs)" + id: setup + timeout: 10m + config: + shell: bash + shellArgs: [--login] + envVars: + GIT_BRANCH: specTestsBranch + command: | + set -e + GIT_BRANCH=$(echo $GIT_BRANCH | jq -r) + + EELS_DIR=$(mktemp -d -t eels-bal4-XXXXXXXXXX) + echo "::set-var eelsDir ${EELS_DIR}" + echo "${EELS_DIR}" > $ASSERTOOR_SUMMARY + + git clone https://github.com/ethereum/execution-specs.git \ + --depth 1 --branch ${GIT_BRANCH} --single-branch ${EELS_DIR} + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + uv sync --all-extras + + echo "EELS environment ready at ${EELS_DIR}" + + - name: check_clients_are_healthy + title: "Check if at least one client is ready" + id: clientCheck + timeout: 5m + config: + minClientCount: 1 + + - name: get_consensus_specs + id: consensusSpecs + title: "Get consensus chain specs" + + - name: check_consensus_slot_range + title: "Wait for Gloas activation" + timeout: 1h + configVars: + minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" + + - name: generate_child_wallet + id: walletEip8024 + title: "Generate fresh wallet for EIP-8024" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal4-eip8024-stack235" + configVars: + privateKey: "walletPrivkey" + + - name: run_shell + title: "EIP-8024: swapn_stack_235 only" + id: eip8024_stack235 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip8024.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip8024_dupn_swapn_exchange/test_swapn.py \ + -k "test_swapn_basic and swapn_stack_235" \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip8024_stack235.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip8024_stack235.html \ + -v \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip8024_stack235.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip8024_stack235.json) + echo "EIP-8024 swapn_stack_235: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + if [ "${PASSED}" != "${TOTAL}" ]; then + jq '.tests[] | select(.outcome != "passed")' ${ASSERTOOR_RESULT_DIR}/eip8024_stack235.json + exit 1 + fi From 9b874643dab86caf2f571bff9661d568765a33b0 Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 11:44:21 +0000 Subject: [PATCH 14/21] Verify EEST PR #2760 fix: clone from qu0b/execution-specs cherry-pick branch --- .../bal-devnet-4-eip8024-stack235-only.yaml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml index 96768752..cadb9060 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eip8024-stack235-only.yaml @@ -1,10 +1,13 @@ id: bal-devnet-4-eip8024-stack235-only -name: "bal-devnet-4: Run EELS EIP-8024 swapn_stack_235 only (debug repro)" +name: "bal-devnet-4: Run EELS EIP-8024 swapn_stack_235 only (debug repro, EEST PR #2760)" timeout: 1h config: walletPrivkey: "" - walletSeed: "spectests-bal4-stack235" - specTestsBranch: "tests-bal@v5.7.0" + walletSeed: "spectests-bal4-stack235-fix" + # Pinned to qu0b/execution-specs branch that is tests-bal@v5.7.0 with the + # PR #2760 fix cherry-picked on top (EIP-8037 deploy_contract state-gas). + specTestsRepo: "https://github.com/qu0b/execution-specs.git" + specTestsBranch: "qu0b/tests-bal-v5.7.0-deploy-state-gas-fix" tasks: - name: run_shell title: "Install Python and build dependencies" @@ -30,15 +33,17 @@ tasks: shellArgs: [--login] envVars: GIT_BRANCH: specTestsBranch + GIT_REPO: specTestsRepo command: | set -e GIT_BRANCH=$(echo $GIT_BRANCH | jq -r) + GIT_REPO=$(echo $GIT_REPO | jq -r) EELS_DIR=$(mktemp -d -t eels-bal4-XXXXXXXXXX) echo "::set-var eelsDir ${EELS_DIR}" echo "${EELS_DIR}" > $ASSERTOOR_SUMMARY - git clone https://github.com/ethereum/execution-specs.git \ + git clone ${GIT_REPO} \ --depth 1 --branch ${GIT_BRANCH} --single-branch ${EELS_DIR} cd ${EELS_DIR} From ec80ef7c7891c6db272fd14c094540e9f65257bd Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 12:17:40 +0000 Subject: [PATCH 15/21] Bump spamoor to v1.1.18-...20260427075552 + call InitializeBlockStats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-picks the Amsterdam funding-gas fix from upstream (spamoor #217 EIP-8037 gas accounting + #218 cpsbFloor on startup + assertoor #162 InitializeBlockStats) without pulling the whole upstream merge — that pulled go-eth2-client v0.1.0 from ethpandaops, whose Gloas SSZ schema for BLSToExecutionChanges differs from qu0b/go-eth2-client and breaks block decoding on bal-devnet-4. Keeps the existing `replace attestantio/go-eth2-client => qu0b/go-eth2-client` directive so block processing stays compatible with the chain we run. --- go.mod | 15 ++++++++------- go.sum | 30 ++++++++++++++++-------------- pkg/txmgr/spamoor.go | 10 ++++++++++ 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index a98f7cee..29a9db69 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/ethpandaops/assertoor -go 1.25.0 +go 1.25.7 require ( github.com/attestantio/go-eth2-client v0.28.0 github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 - github.com/ethereum/go-ethereum v1.17.1 + github.com/ethereum/go-ethereum v1.17.3-0.20260421080339-499762852cf2 github.com/ethpandaops/ethwallclock v0.4.0 - github.com/ethpandaops/spamoor v1.1.18-0.20260226103249-8d1c1fdd2de0 + github.com/ethpandaops/spamoor v1.1.18-0.20260427075552-dcdec39f6332 github.com/glebarez/go-sqlite v1.22.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/uuid v1.6.0 @@ -45,11 +45,11 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.20.0 // indirect + github.com/bits-and-blooms/bitset v1.24.4 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/consensys/gnark-crypto v0.19.2 // indirect + github.com/consensys/gnark-crypto v0.20.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect - github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.5.0 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -96,6 +96,7 @@ require ( github.com/swaggo/files v1.0.1 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.8.0 // indirect + github.com/traefik/yaegi v0.16.2-0.20260209085605-fcb76d1ece0c // indirect github.com/wealdtech/go-bytesutil v1.2.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect @@ -110,7 +111,7 @@ require ( golang.org/x/net v0.50.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect - golang.org/x/time v0.14.0 // indirect + golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.42.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/protobuf v1.36.11 // indirect diff --git a/go.sum b/go.sum index 4f0cadba..e6f788be 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMG github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= -github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE= +github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= @@ -37,14 +37,14 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80= -github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0= +github.com/consensys/gnark-crypto v0.20.1 h1:PXDUBvk8AzhvWowHLWBEAfUQcV1/aZgWIqD6eMpXmDg= +github.com/consensys/gnark-crypto v0.20.1/go.mod h1:RBWrSgy+IDbGR69RRV313th3M/aZU1ubk2om+qHuTSc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= -github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/crate-crypto/go-eth-kzg v1.5.0 h1:FYRiJMJG2iv+2Dy3fi14SVGjcPteZ5HAAUe4YWlJygc= +github.com/crate-crypto/go-eth-kzg v1.5.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -68,12 +68,12 @@ github.com/ethereum/c-kzg-4844/v2 v2.1.6 h1:xQymkKCT5E2Jiaoqf3v4wsNgjZLY0lRSkZn2 github.com/ethereum/c-kzg-4844/v2 v2.1.6/go.mod h1:8HMkUZ5JRv4hpw/XUrYWSQNAUzhHMg2UDb/U+5m+XNw= github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= -github.com/ethereum/go-ethereum v1.17.1 h1:IjlQDjgxg2uL+GzPRkygGULPMLzcYWncEI7wbaizvho= -github.com/ethereum/go-ethereum v1.17.1/go.mod h1:7UWOVHL7K3b8RfVRea022btnzLCaanwHtBuH1jUCH/I= +github.com/ethereum/go-ethereum v1.17.3-0.20260421080339-499762852cf2 h1:PPbNu5NqmJ6+uo1y43tp1sBOt0a0S1gop5agy6qchMI= +github.com/ethereum/go-ethereum v1.17.3-0.20260421080339-499762852cf2/go.mod h1:KHcRXfGOUfUmKg51IhQ0IowiqZ6PqZf08CMtk0g5K1o= github.com/ethpandaops/ethwallclock v0.4.0 h1:+sgnhf4pk6hLPukP076VxkiLloE4L0Yk1yat+ZyHh1g= github.com/ethpandaops/ethwallclock v0.4.0/go.mod h1:y0Cu+mhGLlem19vnAV2x0hpFS5KZ7oOi2SWYayv9l24= -github.com/ethpandaops/spamoor v1.1.18-0.20260226103249-8d1c1fdd2de0 h1:avoDj2pij57dxnA5dpei0ND8LKVpMttvPo3E0QF/6UE= -github.com/ethpandaops/spamoor v1.1.18-0.20260226103249-8d1c1fdd2de0/go.mod h1:GW6Xjym8fliGk+Si2/dV+7M0RXIJTwW2w/ZHYXnri0A= +github.com/ethpandaops/spamoor v1.1.18-0.20260427075552-dcdec39f6332 h1:EXwsdYQmFzvCmYIExZ+yiRz+eIO+KPPfa6kyxV7KYjs= +github.com/ethpandaops/spamoor v1.1.18-0.20260427075552-dcdec39f6332/go.mod h1:LBTplm930TuSBdpYvV1ICDR5GfL3MkUpH7/P+HvJEEU= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= @@ -321,6 +321,8 @@ github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZ github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +github.com/traefik/yaegi v0.16.2-0.20260209085605-fcb76d1ece0c h1:htRmijmYfl6o44qr+narOX1invzz9J9FnAqCqH7ARio= +github.com/traefik/yaegi v0.16.2-0.20260209085605-fcb76d1ece0c/go.mod h1:4eVhbPb3LnD2VigQjhYbEJ69vDRFdT2HQNrXx8eEwUY= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= @@ -344,8 +346,8 @@ go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -401,8 +403,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/pkg/txmgr/spamoor.go b/pkg/txmgr/spamoor.go index 2f584337..50ed6ec9 100644 --- a/pkg/txmgr/spamoor.go +++ b/pkg/txmgr/spamoor.go @@ -71,6 +71,16 @@ func NewSpamoor(ctx context.Context, logger logrus.FieldLogger, executionPool *e return nil, err } + // Load chain state (gas limit, base fee, Amsterdam activation) once the + // client pool is healthy so subsequent task submissions observe real + // values instead of uninitialized defaults. + initStatsCtx, cancelInitStats := context.WithTimeout(ctx, 30*time.Second) + err = txpool.InitializeBlockStats(initStatsCtx) + cancelInitStats() + if err != nil { + return nil, fmt.Errorf("failed to initialize block stats: %w", err) + } + s.clientPool = clientPool s.txpool = txpool From 44aeb1a76e65faa5ce9e5e8bbbfce699d2f580ef Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 12:38:24 +0000 Subject: [PATCH 16/21] playbook: fix EIP-8037 funding-gas race + skip filler-only slotnum tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two corrections to bal-devnet-4-eels-tests.yaml: 1) Reorder check_consensus_slot_range BEFORE generate_child_wallet. Spamoor's WalletPool.FundingGasFor() reads cpsb from the latest observed block, which is 0 until processBlock receives a post-Gloas block. If we generate the funding tx in the [genesis, first-post-Gloas-block-observed] window on a chain with non-zero gloas_fork_epoch, the funding tx is sized at 21000 gas while geth's tx pool already requires 23333 (110% of intrinsic, post-EIP-8037). Result: 'intrinsic gas too low: gas 21000, minimum needed 23333' on geth. By the time check_consensus_slot_range returns, several post-Gloas blocks have been streamed and spamoor's IsAmsterdam is true, so funding is sized correctly. 2) Deselect test_slotnum_value from EIP-7843 run. The test asserts SSTORE(0, SLOTNUM) returns Environment(slot_number=N), where Environment(slot_number=) is a filler-time hint. In execute mode against a live chain, SLOTNUM returns the actual current beacon slot — so the 5 parameterised cases (slot_zero/one/4096/large/max_u64) fail on every client, not just nethermind. Test is structurally incompatible with execute mode and should be filler-only. test_slotnum_gas_cost still runs. --- .../bal-devnet-4-eels-tests.yaml | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml index b2dda5be..366b80be 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -65,16 +65,15 @@ tasks: config: minClientCount: 1 - - name: generate_child_wallet - id: specTestsWallet - title: "Generate funded wallet for tests" - config: - prefundMinBalance: 1000000000000000000000000 # 1000000 ETH - configVars: - privateKey: "walletPrivkey" - walletSeed: "walletSeed" - - # wait for gloas activation + # Wait for Gloas/Amsterdam activation BEFORE generate_child_wallet. Spamoor's + # WalletPool.FundingGasFor() reads cpsb from the latest observed block, which + # is 0 until processBlock receives a post-Gloas block. If we generate the + # funding tx in the [genesis, first-post-Gloas-block-observed] window on a + # chain with non-zero gloas_fork_epoch, the funding tx is sized at 21000 gas + # while geth's tx pool already requires 23333 (110% of intrinsic, post-EIP-8037). + # Result: "intrinsic gas too low: gas 21000, minimum needed 23333" on geth. + # By the time check_consensus_slot_range returns, several post-Gloas blocks + # have been streamed and spamoor's IsAmsterdam is true. - name: get_consensus_specs id: consensusSpecs title: "Get consensus chain specs" @@ -84,6 +83,15 @@ tasks: configVars: minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" + - name: generate_child_wallet + id: specTestsWallet + title: "Generate funded wallet for tests" + config: + prefundMinBalance: 1000000000000000000000000 # 1000000 ETH + configVars: + privateKey: "walletPrivkey" + walletSeed: "walletSeed" + # run tests per EIP sequentially - name: run_tasks title: "Run bal-devnet-4 EELS tests" @@ -218,6 +226,10 @@ tasks: export PATH=$PATH:$HOME/.local/bin export HOME=${EELS_DIR} + # Skip test_slotnum_value: it asserts SLOTNUM == Environment(slot_number=N), + # but Environment(slot_number=) is a filler-time hint and cannot be honored + # in execute mode against a live chain (SLOTNUM returns the actual current + # beacon slot). Only test_slotnum_gas_cost runs in execute mode. uv run execute remote ./tests/amsterdam/eip7843_slotnum \ --fork=Amsterdam \ --chain-id=${CHAIN_ID} \ @@ -225,6 +237,7 @@ tasks: --rpc-seed-key=${PRIVATE_KEY} \ --seed-account-sweep-amount="100 ether" \ --sender-fund-refund-gas-limit=200000 \ + --deselect tests/amsterdam/eip7843_slotnum/test_slotnum.py::test_slotnum_value \ --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7843.json \ --html=${ASSERTOOR_RESULT_DIR}/eip7843.html \ || true From 9a1de09ee6fd4ad22e8fd1951eee8f0e5db25c96 Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 12:45:39 +0000 Subject: [PATCH 17/21] playbook: 30s buffer between Gloas wait and funding for spamoor sync check_consensus_slot_range returns the moment the wallclock crosses the target epoch, but spamoor's processBlock needs an actual EL block (with BlockAccessListHash != nil) to flip isAmsterdam. Empirically the gap is ~5 sec; add 30s of margin to ensure ~5 post-Gloas EL blocks propagate. --- playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml index 366b80be..ff465e06 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -83,6 +83,15 @@ tasks: configVars: minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" + # check_consensus_slot_range returns the moment the wallclock crosses the + # target epoch, but spamoor's processBlock needs an actual EL block (with + # BlockAccessListHash != nil) to flip isAmsterdam. Pause 30s so at least + # 5 post-Gloas EL blocks (6s slot time) propagate to spamoor's TxPool. + - name: sleep + title: "Let spamoor observe a post-Gloas EL block" + config: + duration: 30s + - name: generate_child_wallet id: specTestsWallet title: "Generate funded wallet for tests" From db950a4a7d5babdc74f5e1d1e9785ab936fe0b47 Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 12:56:54 +0000 Subject: [PATCH 18/21] =?UTF-8?q?playbook:=20pin=20to=20tests-sn=C3=B8bal-?= =?UTF-8?q?devnet-4@v1.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Retarget the bal-devnet-4 EELS playbook from tests-bal@v5.7.0 to the new tests-snøbal-devnet-4@v1.0.0 release on ethereum/execution-specs (commit 28e6130 on devnets/snøbal/4). All 9 EIP test directories present at the new tag; spec/tests now use static cpsb=1174. --- playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml index ff465e06..4110b345 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -1,11 +1,12 @@ id: bal-devnet-4-eels-tests -name: "bal-devnet-4: Run EELS execution spec tests (all EIPs, tests-bal@v5.7.0)" +name: "bal-devnet-4: Run EELS execution spec tests (all EIPs, tests-snøbal-devnet-4@v1.0.0)" timeout: 4h config: walletPrivkey: "" walletSeed: "spectests-bal4" - # Pin to the v5.7.0 release tag for determinism (commit 524b446 on devnets/bal/4). - specTestsBranch: "tests-bal@v5.7.0" + # Pin to the tests-snøbal-devnet-4@v1.0.0 release tag for determinism + # (commit 28e6130 on devnets/snøbal/4). Reverts cpsb to static 1174. + specTestsBranch: "tests-snøbal-devnet-4@v1.0.0" tasks: # install python + deps - name: run_shell From bc3c7e9d9438676d34bc38baebd6469d7c4e9215 Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 13:04:01 +0000 Subject: [PATCH 19/21] spamoor: route to local fork carrying effectiveCpsb fork-race fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * go.mod: replace ethpandaops/spamoor with local /home/ubuntu/repos/spamoor (qu0b/fix/effective-cpsb-fork-race), which drops the racy 'observed pre-Amsterdam head → return 0' branch in WalletPool.effectiveCpsb. EIP-8037 fixes cost_per_state_byte at cpsbFloor=1174, so always returning cpsbFloor when no live cpsb is available is exact post-Amsterdam and only costs over-reservation on truly pre-Amsterdam chains (PR #218 already accepted that tradeoff for the no-head startup case). * pkg/txmgr/spamoor.go: drop the explicit InitializeBlockStats call. The current spamoor master auto-initializes block stats internally via initBlockStats; the public API my earlier surgical merge depended on no longer exists. The fix above removes the need for a synchronous startup refresh anyway — effectiveCpsb is now race-free. * playbooks/.../bal-devnet-4-eels-tests.yaml: revert the playbook reorder + 30s sleep workaround. With the spamoor fix, generate_child_wallet works correctly at any time relative to Gloas activation. --- go.mod | 4 ++ go.sum | 2 - pkg/txmgr/spamoor.go | 10 ----- .../bal-devnet-4-eels-tests.yaml | 37 +++++-------------- 4 files changed, 14 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index 29a9db69..02344abb 100644 --- a/go.mod +++ b/go.mod @@ -124,3 +124,7 @@ require ( ) replace github.com/attestantio/go-eth2-client => github.com/qu0b/go-eth2-client v0.0.0-20260211134817-89b1d064a7e5 + +// Local fork carrying spamoor effectiveCpsb fork-boundary fix +// (qu0b/fix/effective-cpsb-fork-race). Drop once upstreamed. +replace github.com/ethpandaops/spamoor => /home/ubuntu/repos/spamoor diff --git a/go.sum b/go.sum index e6f788be..4cb5e7e2 100644 --- a/go.sum +++ b/go.sum @@ -72,8 +72,6 @@ github.com/ethereum/go-ethereum v1.17.3-0.20260421080339-499762852cf2 h1:PPbNu5N github.com/ethereum/go-ethereum v1.17.3-0.20260421080339-499762852cf2/go.mod h1:KHcRXfGOUfUmKg51IhQ0IowiqZ6PqZf08CMtk0g5K1o= github.com/ethpandaops/ethwallclock v0.4.0 h1:+sgnhf4pk6hLPukP076VxkiLloE4L0Yk1yat+ZyHh1g= github.com/ethpandaops/ethwallclock v0.4.0/go.mod h1:y0Cu+mhGLlem19vnAV2x0hpFS5KZ7oOi2SWYayv9l24= -github.com/ethpandaops/spamoor v1.1.18-0.20260427075552-dcdec39f6332 h1:EXwsdYQmFzvCmYIExZ+yiRz+eIO+KPPfa6kyxV7KYjs= -github.com/ethpandaops/spamoor v1.1.18-0.20260427075552-dcdec39f6332/go.mod h1:LBTplm930TuSBdpYvV1ICDR5GfL3MkUpH7/P+HvJEEU= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= diff --git a/pkg/txmgr/spamoor.go b/pkg/txmgr/spamoor.go index 50ed6ec9..2f584337 100644 --- a/pkg/txmgr/spamoor.go +++ b/pkg/txmgr/spamoor.go @@ -71,16 +71,6 @@ func NewSpamoor(ctx context.Context, logger logrus.FieldLogger, executionPool *e return nil, err } - // Load chain state (gas limit, base fee, Amsterdam activation) once the - // client pool is healthy so subsequent task submissions observe real - // values instead of uninitialized defaults. - initStatsCtx, cancelInitStats := context.WithTimeout(ctx, 30*time.Second) - err = txpool.InitializeBlockStats(initStatsCtx) - cancelInitStats() - if err != nil { - return nil, fmt.Errorf("failed to initialize block stats: %w", err) - } - s.clientPool = clientPool s.txpool = txpool diff --git a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml index 4110b345..8bf8ca24 100644 --- a/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml +++ b/playbooks/glamsterdam-dev/bal-devnet-4-eels-tests.yaml @@ -66,33 +66,6 @@ tasks: config: minClientCount: 1 - # Wait for Gloas/Amsterdam activation BEFORE generate_child_wallet. Spamoor's - # WalletPool.FundingGasFor() reads cpsb from the latest observed block, which - # is 0 until processBlock receives a post-Gloas block. If we generate the - # funding tx in the [genesis, first-post-Gloas-block-observed] window on a - # chain with non-zero gloas_fork_epoch, the funding tx is sized at 21000 gas - # while geth's tx pool already requires 23333 (110% of intrinsic, post-EIP-8037). - # Result: "intrinsic gas too low: gas 21000, minimum needed 23333" on geth. - # By the time check_consensus_slot_range returns, several post-Gloas blocks - # have been streamed and spamoor's IsAmsterdam is true. - - name: get_consensus_specs - id: consensusSpecs - title: "Get consensus chain specs" - - name: check_consensus_slot_range - title: "Wait for Gloas activation" - timeout: 1h - configVars: - minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" - - # check_consensus_slot_range returns the moment the wallclock crosses the - # target epoch, but spamoor's processBlock needs an actual EL block (with - # BlockAccessListHash != nil) to flip isAmsterdam. Pause 30s so at least - # 5 post-Gloas EL blocks (6s slot time) propagate to spamoor's TxPool. - - name: sleep - title: "Let spamoor observe a post-Gloas EL block" - config: - duration: 30s - - name: generate_child_wallet id: specTestsWallet title: "Generate funded wallet for tests" @@ -102,6 +75,16 @@ tasks: privateKey: "walletPrivkey" walletSeed: "walletSeed" + # wait for gloas activation + - name: get_consensus_specs + id: consensusSpecs + title: "Get consensus chain specs" + - name: check_consensus_slot_range + title: "Wait for Gloas activation" + timeout: 1h + configVars: + minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" + # run tests per EIP sequentially - name: run_tasks title: "Run bal-devnet-4 EELS tests" From e2954450c60dc4a089c19663a560a5311e8718f2 Mon Sep 17 00:00:00 2001 From: qu0b Date: Mon, 27 Apr 2026 13:06:17 +0000 Subject: [PATCH 20/21] spamoor: replace -> github.com/qu0b/spamoor for docker build context Local /home/ubuntu/repos path doesn't survive docker build context, so point at the published qu0b/spamoor fork at the same commit (72ac11889a85 on qu0b/fix/effective-cpsb-fork-race). --- go.mod | 4 ++-- go.sum | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 02344abb..d4d6f43d 100644 --- a/go.mod +++ b/go.mod @@ -125,6 +125,6 @@ require ( replace github.com/attestantio/go-eth2-client => github.com/qu0b/go-eth2-client v0.0.0-20260211134817-89b1d064a7e5 -// Local fork carrying spamoor effectiveCpsb fork-boundary fix +// qu0b/spamoor carries effectiveCpsb fork-boundary fix // (qu0b/fix/effective-cpsb-fork-race). Drop once upstreamed. -replace github.com/ethpandaops/spamoor => /home/ubuntu/repos/spamoor +replace github.com/ethpandaops/spamoor => github.com/qu0b/spamoor v0.0.0-20260427130206-72ac11889a85 diff --git a/go.sum b/go.sum index 4cb5e7e2..9a9a21d7 100644 --- a/go.sum +++ b/go.sum @@ -276,6 +276,8 @@ github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkq github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs= github.com/qu0b/go-eth2-client v0.0.0-20260211134817-89b1d064a7e5 h1:KhHr85BKhGb+5q8npUuMTxwcUGvtzk9P3ZnBwd++Tbo= github.com/qu0b/go-eth2-client v0.0.0-20260211134817-89b1d064a7e5/go.mod h1:fvULSL9WtNskkOB4i+Yyr6BKpNHXvmpGZj9969fCrfY= +github.com/qu0b/spamoor v0.0.0-20260427130206-72ac11889a85 h1:RcLGHCjbWlJLNgPTMLOIyWGHbcuJS83ZD6nx0kuOcUA= +github.com/qu0b/spamoor v0.0.0-20260427130206-72ac11889a85/go.mod h1:LBTplm930TuSBdpYvV1ICDR5GfL3MkUpH7/P+HvJEEU= github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= From 507b0ce87db42d41ab9ba4a70f35dc5deccc3af5 Mon Sep 17 00:00:00 2001 From: qu0b Date: Wed, 29 Apr 2026 10:48:07 +0000 Subject: [PATCH 21/21] playbook: add bal-devnet-5 EELS tests pinned to tests-snobal-devnet-5@v8037.0.0 EIP set is unchanged from devnet-4 (7708, 7778, 7843, 7928, 7954, 7976, 7981, 8024, 8037). EIP-8037 reverts to fixed CPSB=1174 and adds frame-end state-gas accounting. WalletSeeds bumped to spectests-bal5-* so v4 and v5 runs against the same chain do not collide. --- .../bal-devnet-5-eels-tests.yaml | 549 ++++++++++++++++++ 1 file changed, 549 insertions(+) create mode 100644 playbooks/glamsterdam-dev/bal-devnet-5-eels-tests.yaml diff --git a/playbooks/glamsterdam-dev/bal-devnet-5-eels-tests.yaml b/playbooks/glamsterdam-dev/bal-devnet-5-eels-tests.yaml new file mode 100644 index 00000000..d113d846 --- /dev/null +++ b/playbooks/glamsterdam-dev/bal-devnet-5-eels-tests.yaml @@ -0,0 +1,549 @@ +id: bal-devnet-5-eels-tests +name: "bal-devnet-5: Run EELS execution spec tests (all EIPs, tests-snobal-devnet-5@v8037.0.0)" +timeout: 4h +config: + walletPrivkey: "" + walletSeed: "spectests-bal5" + # Pin to the tests-snobal-devnet-5@v8037.0.0 release tag for determinism + # (commit 9c0ed45 on devnets/snobal/5). EIP-8037 changes vs devnet-4: + # CPSB stays static at 1174 (dynamic derivation removed) and state gas is + # now charged at frame boundaries (frame-end accounting) instead of inline. + specTestsBranch: "tests-snobal-devnet-5@v8037.0.0" +tasks: + # install python + deps + - name: run_shell + title: "Install Python and build dependencies" + id: deps + timeout: 10m + config: + shell: bash + command: | + set -e + # apt-get / dpkg can consume stdin during package configure when run via + # assertoor's stdin-pipe shell; that swallows the rest of this script + # silently (script ends before pip install uv). Force non-interactive + # mode and redirect stdin from /dev/null on every apt invocation so + # nothing reads our pipe. + export DEBIAN_FRONTEND=noninteractive + sudo dpkg --add-architecture amd64 < /dev/null + sudo apt-get update < /dev/null + sudo apt-get install -y build-essential python3 python3-pip python3-dev libc6:amd64 autoconf automake libffi-dev libtool pkg-config < /dev/null + sudo rm /usr/lib/python3*/EXTERNALLY-MANAGED 2>/dev/null || true + pip install uv + + # clone EELS repo + - name: run_shell + title: "Clone EELS (execution-specs)" + id: setup + timeout: 10m + config: + shell: bash + shellArgs: [--login] + envVars: + GIT_BRANCH: specTestsBranch + command: | + set -e + GIT_BRANCH=$(echo $GIT_BRANCH | jq -r) + + EELS_DIR=$(mktemp -d -t eels-bal5-XXXXXXXXXX) + echo "::set-var eelsDir ${EELS_DIR}" + echo "${EELS_DIR}" > $ASSERTOOR_SUMMARY + + git clone https://github.com/ethereum/execution-specs.git \ + --depth 1 --branch ${GIT_BRANCH} --single-branch ${EELS_DIR} + + cd ${EELS_DIR} + # Capture uv on PATH using the original $HOME (where pip --user installed it) + # BEFORE overriding HOME to isolate uv's cache to EELS_DIR. + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + uv sync --all-extras + + echo "EELS environment ready at ${EELS_DIR}" + + - name: check_clients_are_healthy + title: "Check if at least one client is ready" + id: clientCheck + timeout: 5m + config: + minClientCount: 1 + + - name: generate_child_wallet + id: specTestsWallet + title: "Generate funded wallet for tests" + config: + prefundMinBalance: 1000000000000000000000000 # 1000000 ETH + configVars: + privateKey: "walletPrivkey" + walletSeed: "walletSeed" + + # wait for gloas activation + - name: get_consensus_specs + id: consensusSpecs + title: "Get consensus chain specs" + - name: check_consensus_slot_range + title: "Wait for Gloas activation" + timeout: 1h + configVars: + minEpochNumber: "tasks.consensusSpecs.outputs.specs.GLOAS_FORK_EPOCH" + + # run tests per EIP sequentially + - name: run_tasks + title: "Run bal-devnet-5 EELS tests" + id: tests + config: + continueOnFailure: true + tasks: + - name: generate_child_wallet + id: walletEip7708 + title: "Generate fresh wallet for EIP-7708" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip7708" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-7708: ETH transfers emit a log (incl. CREATE/CREATE2)" + id: eip7708 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip7708.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip7708_eth_transfer_logs \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7708.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7708.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7708.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7708.json) + echo "EIP-7708: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip7778 + title: "Generate fresh wallet for EIP-7778" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip7778" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-7778: Block gas accounting without refunds" + id: eip7778 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip7778.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip7778_block_gas_accounting_without_refunds \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7778.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7778.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7778.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7778.json) + echo "EIP-7778: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip7843 + title: "Generate fresh wallet for EIP-7843" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip7843" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-7843: SLOTNUM opcode" + id: eip7843 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip7843.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + # Skip test_slotnum_value: it asserts SLOTNUM == Environment(slot_number=N), + # but Environment(slot_number=) is a filler-time hint and cannot be honored + # in execute mode against a live chain (SLOTNUM returns the actual current + # beacon slot). Only test_slotnum_gas_cost runs in execute mode. + uv run execute remote ./tests/amsterdam/eip7843_slotnum \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --deselect tests/amsterdam/eip7843_slotnum/test_slotnum.py::test_slotnum_value \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7843.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7843.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7843.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7843.json) + echo "EIP-7843: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip7928 + title: "Generate fresh wallet for EIP-7928" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip7928" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-7928: Block-level access lists (BAL, uint32 index)" + id: eip7928 + timeout: 2h + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip7928.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip7928_block_level_access_lists \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + -n 16 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7928.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7928.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7928.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7928.json) + echo "EIP-7928: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip7954 + title: "Generate fresh wallet for EIP-7954" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip7954" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-7954: Increase maximum contract size (24K → 32K)" + id: eip7954 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip7954.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip7954_increase_max_contract_size \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7954.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7954.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7954.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7954.json) + echo "EIP-7954: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip7976 + title: "Generate fresh wallet for EIP-7976" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip7976" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-7976: Increase calldata floor cost (unchanged from devnet-4)" + id: eip7976 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip7976.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip7976_increase_calldata_floor_cost \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7976.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7976.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7976.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7976.json) + echo "EIP-7976: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip7981 + title: "Generate fresh wallet for EIP-7981" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip7981" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-7981: Increase access list cost (unchanged from devnet-4)" + id: eip7981 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip7981.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip7981_increase_access_list_cost \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip7981.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip7981.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip7981.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip7981.json) + echo "EIP-7981: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip8024 + title: "Generate fresh wallet for EIP-8024" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip8024" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-8024: Backward compatible SWAPN, DUPN, EXCHANGE" + id: eip8024 + timeout: 30m + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip8024.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip8024_dupn_swapn_exchange \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip8024.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip8024.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip8024.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip8024.json) + echo "EIP-8024: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + + - name: generate_child_wallet + id: walletEip8037 + title: "Generate fresh wallet for EIP-8037" + config: + prefundMinBalance: 1000000000000000000000000 # 1M ETH + walletSeed: "spectests-bal5-eip8037" + configVars: + privateKey: "walletPrivkey" + - name: run_shell + title: "EIP-8037: State creation gas cost (static cpsb=1174, frame-end accounting)" + id: eip8037 + timeout: 2h + config: + shell: bash + shellArgs: [--login] + envVars: + EELS_DIR: eelsDir + CHAIN_ID: tasks.consensusSpecs.outputs.specs.DEPOSIT_CHAIN_ID + RPC_ENDPOINT: tasks.clientCheck.outputs.goodClients[0].elRpcUrl + PRIVATE_KEY: tasks.walletEip8037.outputs.childWallet.privkey + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + CHAIN_ID=$(echo $CHAIN_ID | jq -r) + RPC_ENDPOINT=$(echo $RPC_ENDPOINT | jq -r) + PRIVATE_KEY=$(echo $PRIVATE_KEY | jq -r) + + cd ${EELS_DIR} + export PATH=$PATH:$HOME/.local/bin + export HOME=${EELS_DIR} + + uv run execute remote ./tests/amsterdam/eip8037_state_creation_gas_cost_increase \ + --fork=Amsterdam \ + --chain-id=${CHAIN_ID} \ + --rpc-endpoint=${RPC_ENDPOINT} \ + --rpc-seed-key=${PRIVATE_KEY} \ + --seed-account-sweep-amount="100 ether" \ + --sender-fund-refund-gas-limit=200000 \ + -n 16 \ + --json-report --json-report-file=${ASSERTOOR_RESULT_DIR}/eip8037.json \ + --html=${ASSERTOOR_RESULT_DIR}/eip8037.html \ + || true + + TOTAL=$(jq '.tests | length' ${ASSERTOOR_RESULT_DIR}/eip8037.json) + PASSED=$(jq '[.tests[] | select(.outcome == "passed")] | length' ${ASSERTOOR_RESULT_DIR}/eip8037.json) + echo "EIP-8037: ${PASSED}/${TOTAL}" + echo "::set-output passed ${PASSED}" + echo "::set-output total ${TOTAL}" + +cleanupTasks: + - name: run_shell + title: "Cleanup EELS temp dir" + config: + shell: bash + envVars: + EELS_DIR: eelsDir + command: | + set -e + EELS_DIR=$(echo $EELS_DIR | jq -r) + if [ ! -z "$EELS_DIR" ] && [ -d "$EELS_DIR" ]; then + rm -rf $EELS_DIR + echo "Cleaned up ${EELS_DIR}" + fi