From c11f20f8b0d2fc28a52c0bd14961bc9014ffe71e Mon Sep 17 00:00:00 2001 From: andri lim Date: Sat, 25 Jan 2025 21:32:39 +0700 Subject: [PATCH] devnet-6: Update EIP-7702: update EXTCODE* opcodes to act on full 'delegation designator' (#3021) --- nimbus/core/eip7702.nim | 7 -- nimbus/db/ledger.nim | 23 ------- nimbus/evm/computation.nim | 37 +--------- nimbus/evm/evmc_api.nim | 10 +-- .../evm/interpreter/op_handlers/oph_defs.nim | 5 +- .../interpreter/op_handlers/oph_envinfo.nim | 67 ++----------------- nimbus/transaction/evmc_host_glue.nim | 6 +- nimbus/transaction/host_services.nim | 8 +-- 8 files changed, 13 insertions(+), 150 deletions(-) diff --git a/nimbus/core/eip7702.nim b/nimbus/core/eip7702.nim index c549065962..978d95f9aa 100644 --- a/nimbus/core/eip7702.nim +++ b/nimbus/core/eip7702.nim @@ -26,8 +26,6 @@ const const PER_AUTH_BASE_COST* = 12500 PER_EMPTY_ACCOUNT_COST* = 25000 - EIP7702_MAGIC_BYTES* = [0xef.byte, 0x01] - EIP7702_MAGIC_HASH* = hash32"eadcdba66a79ab5dce91622d1d75c8cff5cff0b96944c3bf1072cd08ce018329" func authority*(auth: Authorization): Opt[Address] = const SECP256K1halfN = SECPK1_N div 2 @@ -76,8 +74,3 @@ func parseDelegationAddress*(code: CodeBytesRef): Opt[Address] = return Opt.none(Address) Opt.some(Address(slice[20](code, 3, 22))) - -func isEip7702*(code: CodeBytesRef): bool = - if code.len != 23: - return false - code.hasPrefix(DelegationPrefix) diff --git a/nimbus/db/ledger.nim b/nimbus/db/ledger.nim index 769c133434..89dfe9542f 100644 --- a/nimbus/db/ledger.nim +++ b/nimbus/db/ledger.nim @@ -502,32 +502,12 @@ proc getCodeSize*(ac: LedgerRef, address: Address): int = acc.code.len() -proc resolveCodeHash*(ac: LedgerRef, address: Address): Hash32 = - let (codeHash, code) = ac.getCode(address, true) - if code.isEip7702: - EIP7702_MAGIC_HASH - else: - codeHash - proc resolveCode*(ac: LedgerRef, address: Address): CodeBytesRef = let code = ac.getCode(address) let delegateTo = parseDelegationAddress(code).valueOr: return code ac.getCode(delegateTo) -proc resolveCodeSize*(ac: LedgerRef, address: Address): int = - let code = ac.getCode(address) - if code.isEip7702: - EIP7702_MAGIC_BYTES.len - else: - code.len - -proc getDelegateAddress*(ac: LedgerRef, address: Address): Address = - let code = ac.getCode(address) - let delegateTo = parseDelegationAddress(code).valueOr: - return - delegateTo - proc getCommittedStorage*(ac: LedgerRef, address: Address, slot: UInt256): UInt256 = let acc = ac.getAccount(address, false) if acc.isNil: @@ -957,10 +937,7 @@ proc getTransientStorage*(db: ReadOnlyLedger, address: Address, slot: UInt256): UInt256 = getTransientStorage(distinctBase db, address, slot) proc getAccountProof*(db: ReadOnlyLedger, address: Address): seq[seq[byte]] = getAccountProof(distinctBase db, address) proc getStorageProof*(db: ReadOnlyLedger, address: Address, slots: openArray[UInt256]): seq[seq[seq[byte]]] = getStorageProof(distinctBase db, address, slots) -proc resolveCodeHash*(db: ReadOnlyLedger, address: Address): Hash32 = resolveCodeHash(distinctBase db, address) proc resolveCode*(db: ReadOnlyLedger, address: Address): CodeBytesRef = resolveCode(distinctBase db, address) -proc resolveCodeSize*(db: ReadOnlyLedger, address: Address): int = resolveCodeSize(distinctBase db, address) -proc getDelegateAddress*(db: ReadOnlyLedger, address: Address): Address = getDelegateAddress(distinctBase db, address) # ------------------------------------------------------------------------------ # End diff --git a/nimbus/evm/computation.nim b/nimbus/evm/computation.nim index 1fe6c37d94..db36ba5ab3 100644 --- a/nimbus/evm/computation.nim +++ b/nimbus/evm/computation.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 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) @@ -213,41 +213,6 @@ template getTransientStorage*(c: Computation, slot: UInt256): UInt256 = c.vmState.readOnlyLedger. getTransientStorage(c.msg.contractAddress, slot) -template resolveCodeSize*(c: Computation, address: Address): uint = - when evmc_enabled: - let delegateTo = c.host.getDelegateAddress(address) - if delegateTo == default(common.Address): - c.host.getCodeSize(address) - else: - c.host.getCodeSize(delegateTo) - else: - uint(c.vmState.readOnlyLedger.resolveCodeSize(address)) - -template resolveCodeHash*(c: Computation, address: Address): Hash32= - when evmc_enabled: - let delegateTo = c.host.getDelegateAddress(address) - if delegateTo == default(common.Address): - c.host.getCodeHash(address) - else: - c.host.getCodeHash(delegateTo) - else: - let - db = c.vmState.readOnlyLedger - if not db.accountExists(address) or db.isEmptyAccount(address): - default(Hash32) - else: - db.resolveCodeHash(address) - -template resolveCode*(c: Computation, address: Address): CodeBytesRef = - when evmc_enabled: - let delegateTo = c.host.getDelegateAddress(address) - if delegateTo == default(common.Address): - CodeBytesRef.init(c.host.copyCode(address)) - else: - CodeBytesRef.init(c.host.copyCode(delegateTo)) - else: - c.vmState.readOnlyLedger.resolveCode(address) - func newComputation*(vmState: BaseVMState, keepStack: bool, message: Message, diff --git a/nimbus/evm/evmc_api.nim b/nimbus/evm/evmc_api.nim index 8c7e2ae00e..0b763e846c 100644 --- a/nimbus/evm/evmc_api.nim +++ b/nimbus/evm/evmc_api.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2019-2024 Status Research & Development GmbH +# Copyright (c) 2019-2025 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) @@ -86,9 +86,9 @@ type key: ptr evmc_uint256be): evmc_uint256be {.cdecl, gcsafe, raises: [].} set_transient_storage*: proc(context: evmc_host_context, address: ptr evmc_address, key, value: ptr evmc_uint256be) {.cdecl, gcsafe, raises: [].} - get_delegate_address*: proc(context: evmc_host_context, address: ptr evmc_address): evmc_address + get_delegate_address*: proc(context: evmc_host_context, address: ptr evmc_address): evmc_address {.cdecl, gcsafe, raises: [].} - + proc nim_host_get_interface*(): ptr nimbus_host_interface {.importc, cdecl.} proc nim_host_create_context*(vmstate: pointer, msg: ptr evmc_message): evmc_host_context {.importc, cdecl.} proc nim_host_destroy_context*(ctx: evmc_host_context) {.importc, cdecl.} @@ -192,10 +192,6 @@ proc setTransientStorage*(ctx: HostContext, address: Address, value = toEvmc(value) ctx.host.set_transient_storage(ctx.context, address.addr, key.addr, value.addr) -proc getDelegateAddress*(ctx: HostContext, address: Address): Address = - var address = toEvmc(address) - fromEvmc ctx.host.get_delegate_address(ctx.context, address.addr) - # The following two templates put here because the stupid style checker # complaints about block_number vs blockNumber and chain_id vs chainId # if they are written directly in computation.nim diff --git a/nimbus/evm/interpreter/op_handlers/oph_defs.nim b/nimbus/evm/interpreter/op_handlers/oph_defs.nim index ff545500af..7319542e0f 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_defs.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_defs.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 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) @@ -82,9 +82,6 @@ const VmOpCancunAndLater* = VmOpShanghaiAndLater - {FkShanghai} - VmOpPragueAndLater* = - VmOpCancunAndLater - {FkCancun} - # ------------------------------------------------------------------------------ # End # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim b/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim index 9f8999f39a..1a2cc30248 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2024 Status Research & Development GmbH +# Copyright (c) 2018-2025 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) @@ -152,15 +152,6 @@ proc extCodeSizeEIP2929Op(cpt: VmCpt): EvmResultVoid = cpt.stack.unaryAddress(ecsEIP2929) -proc extCodeSizeEIP7702Op(cpt: VmCpt): EvmResultVoid = - ## 0x3b, Get size of an account's code (EIP-7702) - template ecsEIP7702(address): auto = - let gasCost = cpt.gasEip2929AccountCheck(address) - ? cpt.opcodeGasCost(ExtCodeSize, gasCost, reason = "ExtCodeSize EIP7702") - cpt.resolveCodeSize(address) - - cpt.stack.unaryAddress(ecsEIP7702) - # ----------- proc extCodeCopyOp(cpt: VmCpt): EvmResultVoid = @@ -200,25 +191,6 @@ proc extCodeCopyEIP2929Op(cpt: VmCpt): EvmResultVoid = cpt.memory.writePadded(code.bytes(), memPos, codePos, len) ok() -proc extCodeCopyEIP7702Op(cpt: VmCpt): EvmResultVoid = - ## 0x3c, Copy an account's code to memory (EIP-7702). - ? cpt.stack.lsCheck(4) - let - address = cpt.stack.lsPeekAddress(^1) - memPos = cpt.stack.lsPeekMemRef(^2) - codePos = cpt.stack.lsPeekMemRef(^3) - len = cpt.stack.lsPeekMemRef(^4) - gasCost = cpt.gasCosts[ExtCodeCopy].m_handler(cpt.memory.len, memPos, len) + - cpt.gasEip2929AccountCheck(address) + - cpt.gasEip7702CodeCheck(address) - - cpt.stack.lsShrink(4) - ? cpt.opcodeGasCost(ExtCodeCopy, gasCost, reason = "ExtCodeCopy EIP7702") - - let code = cpt.resolveCode(address) - cpt.memory.writePadded(code.bytes(), memPos, codePos, len) - ok() - # ----------- proc returnDataSizeOp(cpt: VmCpt): EvmResultVoid = @@ -261,14 +233,6 @@ proc extCodeHashEIP2929Op(cpt: VmCpt): EvmResultVoid = cpt.getCodeHash(address) cpt.stack.unaryAddress(echEIP2929) -proc extCodeHashEIP7702Op(cpt: VmCpt): EvmResultVoid = - ## 0x3f, Returns the keccak256 hash of a contract’s code (EIP-7702) - template echEIP7702(address): auto = - let gasCost = cpt.gasEip2929AccountCheck(address) - ? cpt.opcodeGasCost(ExtCodeHash, gasCost, reason = "ExtCodeHash EIP7702") - cpt.resolveCodeHash(address) - cpt.stack.unaryAddress(echEIP7702) - # ------------------------------------------------------------------------------ # Public, op exec table entries # ------------------------------------------------------------------------------ @@ -369,19 +333,12 @@ const (opCode: ExtCodeSize, ## 0x3b, Account code size for Berlin through Cancun - forks: VmOpBerlinAndLater - VmOpPragueAndLater, + forks: VmOpBerlinAndLater, name: "extCodeSizeEIP2929", info: "EIP2929: Get size of an account's code", exec: extCodeSizeEIP2929Op), - (opCode: ExtCodeSize, ## 0x3b, Account code size for Prague and later - forks: VmOpPragueAndLater, - name: "extCodeSizeEIP7702", - info: "EIP7702: Get size of an account's code", - exec: extCodeSizeEIP7702Op), - - (opCode: ExtCodeCopy, ## 0x3c, Account code copy to memory. forks: VmOpAllForks - VmOpBerlinAndLater, name: "extCodeCopy", @@ -390,19 +347,12 @@ const (opCode: ExtCodeCopy, ## 0x3c, Account Code-copy for Berlin through Cancun - forks: VmOpBerlinAndLater - VmOpPragueAndLater, + forks: VmOpBerlinAndLater, name: "extCodeCopyEIP2929", info: "EIP2929: Copy an account's code to memory", exec: extCodeCopyEIP2929Op), - (opCode: ExtCodeCopy, ## 0x3c, Account code copy for Prague and later - forks: VmOpPragueAndLater, - name: "extCodeCopyEIP7702", - info: "EIP7702: Copy an account's code to memory", - exec: extCodeCopyEIP7702Op), - - (opCode: ReturnDataSize, ## 0x3d, Previous call output data size forks: VmOpByzantiumAndLater, name: "returnDataSize", @@ -426,17 +376,10 @@ const (opCode: ExtCodeHash, ## 0x3f, Contract hash for Berlin through Cancun - forks: VmOpBerlinAndLater - VmOpPragueAndLater, + forks: VmOpBerlinAndLater, name: "extCodeHashEIP2929", info: "EIP2929: Returns the keccak256 hash of a contract’s code", - exec: extCodeHashEIP2929Op), - - - (opCode: ExtCodeHash, ## 0x3f, Contract hash for Prague and later - forks: VmOpPragueAndLater, - name: "extCodeHashEIP7702", - info: "EIP7702: Returns the keccak256 hash of a contract’s code", - exec: extCodeHashEIP7702Op)] + exec: extCodeHashEIP2929Op)] # ------------------------------------------------------------------------------ # End diff --git a/nimbus/transaction/evmc_host_glue.nim b/nimbus/transaction/evmc_host_glue.nim index 2d034ded90..921a6bd1c4 100644 --- a/nimbus/transaction/evmc_host_glue.nim +++ b/nimbus/transaction/evmc_host_glue.nim @@ -1,6 +1,6 @@ # Nimbus - Binary compatibility on the host side of the EVMC API interface # -# Copyright (c) 2019-2024 Status Research & Development GmbH +# Copyright (c) 2019-2025 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) @@ -90,9 +90,6 @@ proc setTransientStorage(p: evmc_host_context, address: var evmc_address, key, value: var evmc_bytes32) {.cdecl.} = toHost(p).setTransientStorage(address.fromEvmc, key.flip256.fromEvmc, value.flip256.fromEvmc) -proc getDelegateAddress(p: evmc_hosT_context, address: var evmc_address): evmc_address {.cdecl.} = - toHost(p).getDelegateAddress(address.fromEvmc).toEvmc - let hostInterface = evmc_host_interface( account_exists: accountExists, get_storage: getStorage, @@ -110,7 +107,6 @@ let hostInterface = evmc_host_interface( access_storage: accessStorage, get_transient_storage: getTransientStorage, set_transient_storage: setTransientStorage, - get_delegate_address: getDelegateAddress, ) proc evmcExecComputation*(host: TransactionHost): EvmcResult = diff --git a/nimbus/transaction/host_services.nim b/nimbus/transaction/host_services.nim index 44dd9b6cb0..7a6105aa0b 100644 --- a/nimbus/transaction/host_services.nim +++ b/nimbus/transaction/host_services.nim @@ -1,6 +1,6 @@ # Nimbus - Services available to EVM code that is run for a transaction # -# Copyright (c) 2019-2024 Status Research & Development GmbH +# Copyright (c) 2019-2025 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) @@ -302,10 +302,6 @@ proc setTransientStorage(host: TransactionHost, address: HostAddress, host.vmState.mutateLedger: db.setTransientStorage(address, key, newVal) -proc getDelegateAddress(host: TransactionHost, address: HostAddress): HostAddress {.show.} = - let db = host.vmState.readOnlyLedger - db.getDelegateAddress(address) - when use_evmc_glue: {.pop: inline.} const included_from_host_services {.used.} = true @@ -313,4 +309,4 @@ when use_evmc_glue: else: export accountExists, getStorage, storage, getBalance, getCodeSize, getCodeHash, - copyCode, selfDestruct, getTxContext, call, getBlockHash, emitLog, getDelegateAddress + copyCode, selfDestruct, getTxContext, call, getBlockHash, emitLog