Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
45d055a
Use targetGasLimit of engine API PayloadAttributesV4 (#4258)
jangko Jun 17, 2026
634c389
Revert BAL workaround of delegated target in CALL* opcodes (#4257)
jangko Jun 17, 2026
faa366f
Upgrade EEST test fixtures to tests-glamsterdam-devnet@v6.1.0
jangko Jun 22, 2026
5a409be
raise EIP-7954 max code size to 64KiB
jangko Jun 22, 2026
4d8f43e
EIP-8037 strict block-gas inclusion rule
jangko Jun 22, 2026
65aaaa8
EIP-8037 Calldata floor accounting alignment
jangko Jun 22, 2026
305cec0
EIP-8037 refund account creation for existing create targets
jangko Jun 22, 2026
d498ebe
update EIP-8037 to use source based refunds
jangko Jun 22, 2026
73d5919
derive EIP-8037 state gas used from reservoir/spill
jangko Jun 22, 2026
1403579
EIP-8282: Builder Execution Requests
jangko Jun 22, 2026
6c930f7
EIP-7997: Deterministic Factory Contract
jangko Jun 22, 2026
d1acf0c
EIP-8246: Remove SELFDESTRUCT Burn
jangko Jun 22, 2026
6892786
EIP-2780: Resource-based intrinsic transaction gas
jangko Jun 22, 2026
08c34b0
EIP-8038: State-access gas cost update
jangko Jun 23, 2026
aae9ca6
Disable zkevm test due to incompatibility
jangko Jun 29, 2026
da9bf21
Lint
jangko Jun 29, 2026
43246a0
Fix wasm compilation crash
jangko Jun 29, 2026
07f6f41
Add nim issue link to emscripten workaround
jangko Jun 30, 2026
dd7ba61
Fix test ledger
jangko Jun 30, 2026
24b2141
Apply EIP-7997 to Amsterdam genesis
jangko Jun 30, 2026
ec5f167
Add EIP-8282 contract code to test_rpc
jangko Jun 30, 2026
ffd4480
Fix EIP-7997 no-op condition
jangko Jun 30, 2026
77572e0
Update BAL test for EIP-8246 changes
jangko Jun 30, 2026
d085409
Add EIP-8282 contract code to test_txpool
jangko Jun 30, 2026
0902a7f
Add EIP-8282 test to test_rpc
jangko Jun 30, 2026
d62ed0f
Reenable zkevm test and upgrade test fixtures to v0.5.0
jangko Jul 2, 2026
9a49f9f
fix: transaction truncation (#4397)
advaita-saha Jul 3, 2026
0a580d6
fix(txpool): reset vmState before every assembleBlock (#4405)
qu0b Jul 3, 2026
0e4458d
Merge branch 'master' into glamsterdam-devnet-6
jangko Jul 3, 2026
c152a2f
Add eest_txpool_test to Makefile PHONY rule
jangko Jul 3, 2026
2a30edf
Update devnet fixtures to tests-glamsterdam-devnet@v6.1.1
jangko Jul 3, 2026
6500b8f
eest_evmstate_test and eest_t8n_test use devnet fixtures
jangko Jul 3, 2026
9fda0d1
Add missing empty line between makefile rule
jangko Jul 4, 2026
e809e73
Skip more failing zkevm test cases
jangko Jul 4, 2026
a7ac35d
fix(engine): preserve withdrawals for V4 (Amsterdam) payload attribut…
lodekeeper Jul 4, 2026
541580b
Merge branch 'master' into glamsterdam-devnet-6
jangko Jul 4, 2026
ff8c9cb
Bump nim-web3
jangko Jul 4, 2026
806e513
Convert #4409 test into rpc test
jangko Jul 4, 2026
59813e0
Fix transition tool EIP-8282 requests typo
jangko Jul 5, 2026
94195f3
Resolve merge conflict
jangko Jul 5, 2026
53b8d6d
Add slotNumber test to test_engine_api
jangko Jul 6, 2026
5078800
Reduce memleak in eest_txpool
jangko Jul 6, 2026
7b45a01
Merge branch 'master' into glamsterdam-devnet-6
jangko Jul 6, 2026
844f905
Fix comments int eest_txpool
jangko Jul 6, 2026
f0f295d
builds MUST start on forkchoiceState.headBlockHash (#4427)
advaita-saha Jul 7, 2026
78cd0fe
Merge branch 'master' into glamsterdam-devnet-6
jangko Jul 8, 2026
0f839cb
Merge branch 'master' into glamsterdam-devnet-6
jangko Jul 8, 2026
d07a375
parallelEnabled = false in eest_engine_test
jangko Jul 8, 2026
182bc6b
Remove extra txFee assignment due to merge conflict
jangko Jul 8, 2026
2255faf
Skip problematic tests
jangko Jul 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ endif
eest_blockchain \
eest_blockchain_test \
eest_stateless_execution_test \
eest_txpool_test \
eest_full_test \
eest_tool_test \
eest_tool_test \
t8n \
t8n_test \
evmstate \
Expand Down Expand Up @@ -438,6 +439,9 @@ eest_blockchain: | build deps
eest_engine_test: | build deps eest
$(ENV_SCRIPT) nim c -r $(NIM_PARAMS) -d:chronicles_enabled:off -o:build/$@ "tests/eest/$@.nim"

eest_txpool_test: | build deps eest
$(ENV_SCRIPT) nim c -r $(NIM_PARAMS) -d:chronicles_enabled:off -o:build/$@ "tests/eest/$@.nim"

eest_blockchain_test: | build deps eest
$(ENV_SCRIPT) nim c -r $(NIM_PARAMS) -d:chronicles_enabled:off -o:build/$@ "tests/eest/$@.nim"

Expand All @@ -451,6 +455,7 @@ eest_full_test: | build deps eest
eest_tool_test: | build deps eest
$(ENV_SCRIPT) nim c $(NIM_PARAMS) -d:chronicles_enabled:off -o:build/$@ "tests/eest/eest_tool_tests.nim"
build/$@

# builds transition tool
t8n: | build deps
$(ENV_SCRIPT) nim c $(NIM_PARAMS) $(T8N_PARAMS) "tools/t8n/$@.nim"
Expand Down
2 changes: 1 addition & 1 deletion execution_chain/beacon/api_handler/api_forkchoice.nim
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ proc forkchoiceUpdated*(ben: BeaconEngineRef,
let attrs = attrsOpt.value
validateVersion(attrs, com, apiVersion)

let bundle = ben.generateExecutionBundle(attrs).valueOr:
let bundle = ben.generateExecutionBundle(headHash, attrs).valueOr:
error "Failed to create sealing payload", err = error
raise invalidAttr(error)

Expand Down
21 changes: 16 additions & 5 deletions execution_chain/beacon/api_handler/api_newpayload.nim
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,22 @@ func validateExecutionRequest(blockHash: Hash32,
raise invalidParams("newPayload" & $apiVersion &
": " & "Empty data for request type " & $requestType)

if requestType notin [
DEPOSIT_REQUEST_TYPE,
WITHDRAWAL_REQUEST_TYPE,
CONSOLIDATION_REQUEST_TYPE]:
return Opt.some(invalidStatus(blockHash, "Invalid execution request type" & $requestType))
if apiVersion >= Version.V5:
if requestType notin [
DEPOSIT_REQUEST_TYPE,
WITHDRAWAL_REQUEST_TYPE,
CONSOLIDATION_REQUEST_TYPE,
BUILDER_DEPOSIT_REQUEST_TYPE,
BUILDER_EXIT_REQUEST_TYPE]:
return Opt.some(invalidStatus(blockHash,
"newPayload" & $apiVersion & ": Invalid execution request type" & $requestType))
else:
if requestType notin [
DEPOSIT_REQUEST_TYPE,
WITHDRAWAL_REQUEST_TYPE,
CONSOLIDATION_REQUEST_TYPE]:
return Opt.some(invalidStatus(blockHash,
"newPayload" & $apiVersion & ": Invalid execution request type" & $requestType))

previousRequestType = requestType.int
err()
Expand Down
19 changes: 14 additions & 5 deletions execution_chain/beacon/beacon_engine.nim
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,12 @@ const

func setWithdrawals(xp: TxPoolRef, attrs: PayloadAttributes) =
case attrs.version
of Version.V2, Version.V3:
xp.withdrawals = ethWithdrawals attrs.withdrawals.get
else:
of Version.V1:
xp.withdrawals = @[]
of Version.V2 .. Version.V4:
xp.withdrawals = ethWithdrawals attrs.withdrawals.get
of Version.V5, Version.V6:
raiseAssert "unreachable: PayloadAttributes has no V5/V6 variant"

template wrapException(body: untyped): auto =
try:
Expand Down Expand Up @@ -148,17 +150,23 @@ func getPayloadBundle*(ben: BeaconEngineRef, id: Bytes8): Opt[ExecutionBundle] =
# ------------------------------------------------------------------------------
proc generateExecutionBundle*(
ben: BeaconEngineRef,
headHash: Hash32,
attrs: PayloadAttributes
): Result[ExecutionBundle, string] =

wrapException:
let
xp = ben.txPool
headBlock = ben.chain.latestHeader
# Build on the forkchoiceUpdated headBlockHash: `chain.latest` tracks the
# most recently imported block, which may be a sibling of the requested
# head when multiple valid payloads exist at the same height.
headBlock = ben.chain.headerByHash(headHash).valueOr:
return err("payload build parent not found: " & headHash.short)

xp.prevRandao = attrs.prevRandao
xp.timestamp = ethTime attrs.timestamp
xp.feeRecipient = attrs.suggestedFeeRecipient
xp.targetGasLimit = u64 attrs.targetGasLimit

if attrs.parentBeaconBlockRoot.isSome:
xp.parentBeaconBlockRoot = attrs.parentBeaconBlockRoot.get
Expand All @@ -173,7 +181,8 @@ proc generateExecutionBundle*(

# someBaseFee = true: make sure bundle.blk.header
# have the same blockHash with generated payload
let bundle = xp.assembleBlock(someBaseFee = true).valueOr:
let bundle = xp.assembleBlock(someBaseFee = true,
parentHash = headHash).valueOr:
return err(error)

if bundle.blk.header.extraData.len > 32:
Expand Down
6 changes: 3 additions & 3 deletions execution_chain/block_access_list/bal_tracker.nim
Original file line number Diff line number Diff line change
Expand Up @@ -434,11 +434,11 @@ proc handleInTransactionSelfDestruct*(
tracker.pendingCallFrame.storageReads.incl(storageKey)
tracker.pendingCallFrame.storageChanges.del(storageKey)

tracker.pendingCallFrame.balanceChanges.del(address)
tracker.pendingCallFrame.nonceChanges.del(address)
tracker.pendingCallFrame.codeChanges.del(address)

tracker.trackBalanceChange(address, 0.u256)

tracker.trackNonceChange(address, 0)
tracker.trackCodeChange(address, @[])

proc normalizePendingCallFrameChanges*(tracker: BlockAccessListTrackerRef) =
## Normalize balance, nonce, code and storage changes for the current
Expand Down
5 changes: 5 additions & 0 deletions execution_chain/common/common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,11 @@ func isOsakaOrLater*(com: CommonRef, t: EthTime): bool =
func isAmsterdamOrLater*(com: CommonRef, t: EthTime): bool =
com.config.amsterdamTime.isSome and t >= com.config.amsterdamTime.value

func amsterdamTransition*(com: CommonRef, parentTime, t: EthTime): bool =
com.config.amsterdamTime.isSome and
t >= com.config.amsterdamTime.value and
parentTime < com.config.amsterdamTime.value

func isBogotaOrLater*(com: CommonRef, t: EthTime): bool =
com.config.bogotaTime.isSome and t >= com.config.bogotaTime.value

Expand Down
10 changes: 7 additions & 3 deletions execution_chain/common/genesis.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import
eth/eip1559,
eth/common/[blocks, hashes, accounts, headers, addresses],
../db/[ledger, core_db],
../core/eip7997,
../constants,
../utils/utils,
./chain_config
Expand All @@ -23,7 +24,7 @@ import
# Public functions
# ------------------------------------------------------------------------------

proc writeGenesisAlloc*(alloc: GenesisAlloc, db: CoreDbTxRef): Hash32 =
proc writeGenesisAlloc*(alloc: GenesisAlloc, db: CoreDbTxRef, enableEIP7997: bool = false): Hash32 =
let ledger = LedgerRef.init(db)

for address, account in alloc:
Expand All @@ -34,6 +35,9 @@ proc writeGenesisAlloc*(alloc: GenesisAlloc, db: CoreDbTxRef): Hash32 =
for k, v in account.storage:
ledger.setStorage(address, k, v)

if enableEIP7997:
ledger.applyEip7997()

ledger.persist()
ledger.getStateRoot()

Expand All @@ -43,7 +47,7 @@ proc writeGenesis*(g: Genesis, db: CoreDbTxRef, fork: HardFork): Header =
##
## The function returns the `Genesis` block header.
##
let stateRoot = writeGenesisAlloc(g.alloc, db)
let stateRoot = writeGenesisAlloc(g.alloc, db, fork >= Amsterdam)

result = Header(
nonce: g.nonce,
Expand All @@ -53,7 +57,7 @@ proc writeGenesis*(g: Genesis, db: CoreDbTxRef, fork: HardFork): Header =
difficulty: g.difficulty,
mixHash: g.mixHash,
coinbase: g.coinbase,
stateRoot:stateRoot,
stateRoot: stateRoot,
parentHash: GENESIS_PARENT_HASH,
transactionsRoot: EMPTY_ROOT_HASH,
receiptsRoot: EMPTY_ROOT_HASH,
Expand Down
4 changes: 2 additions & 2 deletions execution_chain/conf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ type

gasLimit* {.
desc: "Desired gas limit when building an execution payload"
defaultValue: DEFAULT_GAS_LIMIT
name: "gas-limit" .}: uint64
defaultValue: none(uint64)
name: "gas-limit" .}: Option[uint64]

# https://eips.ethereum.org/EIPS/eip-7872
maxBlobs* {.
Expand Down
14 changes: 8 additions & 6 deletions execution_chain/constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,18 @@ const
# size when creating a new contract.
EIP3860_MAX_INITCODE_SIZE* = 2 * EIP170_MAX_CODE_SIZE

# See https://eips.ethereum.org/EIPS/eip-7954.
# - Update contract code size limit of 24KiB(0x6000 bytes) to 32KiB(0x8000 bytes).
# - Update initcode size limit of 48KiB(0xC000 bytes) to 64KiB(0x10000 bytes).
EIP7954_MAX_CODE_SIZE* = 0x8000
EIP7954_MAX_INITCODE_SIZE* = 0x10000
# See https://eips.ethereum.org/EIPS/eip-7954.
# - Update contract code size limit of 24KiB(0x6000 bytes) to 64KiB(0x10000 bytes).
# - Update initcode size limit of 48KiB(0xC000 bytes) to 128KiB(0x20000 bytes).
EIP7954_MAX_CODE_SIZE* = 0x10000
EIP7954_MAX_INITCODE_SIZE* = 2 * EIP7954_MAX_CODE_SIZE

# See EIP-7702 (https://eips.ethereum.org/EIPS/eip-7702). When an EOA delegates
# via a SETCODE transaction its code is set to a "delegation designator": the
# 3-byte prefix 0xef0100 followed by the 20-byte delegate address (23 bytes).
EIP7702_DELEGATION_PREFIX* = [0xEF.byte, 0x01, 0x00]
EIP7702_DELEGATION_SIZE* = 23

# EIP
MaxPrecompilesAddr* = 0xFFFF

Expand Down Expand Up @@ -118,6 +118,8 @@ const
HISTORY_STORAGE_ADDRESS* = address"0x0000F90827F1C53a10cb7A02335B175320002935"
WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS* = address"0x00000961Ef480Eb55e80D19ad83579A64c007002"
CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS* = address"0x0000BBdDc7CE488642fb579F8B00f3a590007251"
BUILDER_DEPOSIT_CONTRACT_ADDRESS* = address"0x0000884D2AA32EAA155F59A2F24EFA73D9008282"
BUILDER_EXIT_CONTRACT_ADDRESS* = address"0x000014574A74C805590AFF9499FC7A690F008282"

MAX_BLOCK_SIZE* = 10_485_760 # 10 MiB
SAFETY_MARGIN* = 2_097_152 # 2 MiB
Expand Down
34 changes: 34 additions & 0 deletions execution_chain/core/eip7997.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Nimbus
# Copyright (c) 2026 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.

{.push raises: [], gcsafe.}

import
eth/common/[addresses, hashes],
stew/byteutils,
../db/ledger

const
FactoryAddress = address"0x4e59b44847b379578588920cA78FbF26c0B4956C"
FactoryCode = hexToSeqByte"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"
FactoryCodeHash = hashes.keccak256(FactoryCode)

proc applyEip7997*(ledger: LedgerRef) =
let codeHash = ledger.getCodeHash(FactoryAddress)
if codeHash == FactoryCodeHash:
# It's a no-op on chain that already have factory at the FactoryAddress.
return

# Although this code only called once during fork transition,
# if using the constant above, sometimes it will crash
# when interacting with CodeBytesRef sink in test environment.
let factoryCode = FactoryCode
ledger.setCode(FactoryAddress, factoryCode)
ledger.setNonce(FactoryAddress, 1)
3 changes: 2 additions & 1 deletion execution_chain/core/eip8037.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
const
STATE_BYTES_PER_NEW_ACCOUNT* = 120
STATE_BYTES_PER_AUTH_BASE* = 23
REGULAR_PER_AUTH_BASE_COST* = 7500
REGULAR_PER_AUTH_BASE_COST* = 7816
STATE_BYTES_PER_STORAGE_SET* = 64
COST_PER_STATE_BYTE* = 1530
CREATE_ACCOUNT_STATE_GAS* = COST_PER_STATE_BYTE * STATE_BYTES_PER_NEW_ACCOUNT
STATE_GAS_STORAGE_SET* = COST_PER_STATE_BYTE * STATE_BYTES_PER_STORAGE_SET
SYSTEM_MAX_SSTORES_PER_CALL = 16
SYSTEM_STATE_GAS_RESERVOIR* = STATE_BYTES_PER_STORAGE_SET * COST_PER_STATE_BYTE * SYSTEM_MAX_SSTORES_PER_CALL
AUTH_BASE_STATE_GAS* = STATE_BYTES_PER_AUTH_BASE * COST_PER_STATE_BYTE
Loading
Loading