Skip to content

Commit

Permalink
devnet-6: Update EIP-7702: update EXTCODE* opcodes to act on full 'de…
Browse files Browse the repository at this point in the history
…legation designator' (#3021)
  • Loading branch information
jangko authored Jan 25, 2025
1 parent 49523c5 commit c11f20f
Show file tree
Hide file tree
Showing 8 changed files with 13 additions and 150 deletions.
7 changes: 0 additions & 7 deletions nimbus/core/eip7702.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
23 changes: 0 additions & 23 deletions nimbus/db/ledger.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
37 changes: 1 addition & 36 deletions nimbus/evm/computation.nim
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 3 additions & 7 deletions nimbus/evm/evmc_api.nim
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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.}
Expand Down Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions nimbus/evm/interpreter/op_handlers/oph_defs.nim
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -82,9 +82,6 @@ const
VmOpCancunAndLater* =
VmOpShanghaiAndLater - {FkShanghai}

VmOpPragueAndLater* =
VmOpCancunAndLater - {FkCancun}

# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------
67 changes: 5 additions & 62 deletions nimbus/evm/interpreter/op_handlers/oph_envinfo.nim
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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
# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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
Expand Down
6 changes: 1 addition & 5 deletions nimbus/transaction/evmc_host_glue.nim
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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 =
Expand Down
8 changes: 2 additions & 6 deletions nimbus/transaction/host_services.nim
Original file line number Diff line number Diff line change
@@ -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)
Expand Down Expand Up @@ -302,15 +302,11 @@ 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
include ./evmc_host_glue
else:
export
accountExists, getStorage, storage, getBalance, getCodeSize, getCodeHash,
copyCode, selfDestruct, getTxContext, call, getBlockHash, emitLog, getDelegateAddress
copyCode, selfDestruct, getTxContext, call, getBlockHash, emitLog

0 comments on commit c11f20f

Please sign in to comment.