diff --git a/nimbus/db/ledger.nim b/nimbus/db/ledger.nim index e145dc431..f0521e77b 100644 --- a/nimbus/db/ledger.nim +++ b/nimbus/db/ledger.nim @@ -521,6 +521,12 @@ proc resolveCodeSize*(ac: LedgerRef, address: Address): int = return code.len ac.getCodeSize(delegateTo) +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: @@ -953,6 +959,7 @@ proc getStorageProof*(db: ReadOnlyStateDB, address: Address, slots: openArray[UI proc resolveCodeHash*(db: ReadOnlyStateDB, address: Address): Hash32 = resolveCodeHash(distinctBase db, address) proc resolveCode*(db: ReadOnlyStateDB, address: Address): CodeBytesRef = resolveCode(distinctBase db, address) proc resolveCodeSize*(db: ReadOnlyStateDB, address: Address): int = resolveCodeSize(distinctBase db, address) +proc getDelegateAddress*(db: ReadOnlyStateDB, address: Address): Address = getDelegateAddress(distinctBase db, address) # ------------------------------------------------------------------------------ # End diff --git a/nimbus/evm/computation.nim b/nimbus/evm/computation.nim index c1c2ddfe0..fe82fecd6 100644 --- a/nimbus/evm/computation.nim +++ b/nimbus/evm/computation.nim @@ -226,13 +226,21 @@ template getTransientStorage*(c: Computation, slot: UInt256): UInt256 = template resolveCodeSize*(c: Computation, address: Address): uint = when evmc_enabled: - c.host.getCodeSize(address) + let delegateTo = c.host.getDelegateAddress(address) + if delegateTo == default(common.Address): + c.host.getCodeSize(address) + else: + c.host.getCodeSize(delegateTo) else: uint(c.vmState.readOnlyStateDB.resolveCodeSize(address)) template resolveCodeHash*(c: Computation, address: Address): Hash32= when evmc_enabled: - c.host.getCodeHash(address) + 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.readOnlyStateDB @@ -243,7 +251,11 @@ template resolveCodeHash*(c: Computation, address: Address): Hash32= template resolveCode*(c: Computation, address: Address): CodeBytesRef = when evmc_enabled: - CodeBytesRef.init(c.host.copyCode(address)) + 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.readOnlyStateDB.resolveCode(address) diff --git a/nimbus/evm/evmc_api.nim b/nimbus/evm/evmc_api.nim index 749d60c8f..8c7e2ae00 100644 --- a/nimbus/evm/evmc_api.nim +++ b/nimbus/evm/evmc_api.nim @@ -86,7 +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 + {.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.} @@ -190,6 +192,10 @@ 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/transaction/evmc_host_glue.nim b/nimbus/transaction/evmc_host_glue.nim index bdb5cf714..d5fb75000 100644 --- a/nimbus/transaction/evmc_host_glue.nim +++ b/nimbus/transaction/evmc_host_glue.nim @@ -90,6 +90,9 @@ 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, @@ -107,6 +110,7 @@ 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 7be5a8dc1..c76291377 100644 --- a/nimbus/transaction/host_services.nim +++ b/nimbus/transaction/host_services.nim @@ -179,10 +179,7 @@ proc getBalance(host: TransactionHost, address: HostAddress): HostBalance {.show proc getCodeSize(host: TransactionHost, address: HostAddress): HostSize {.show.} = # TODO: Check this `HostSize`, it was copied as `uint` from other code. # Note: Old `evmc_host` uses `getCode(address).len` instead. - if host.vmState.fork >= FkPrague: - host.vmState.readOnlyStateDB.resolveCodeSize(address).HostSize - else: - host.vmState.readOnlyStateDB.getCodeSize(address).HostSize + host.vmState.readOnlyStateDB.getCodeSize(address).HostSize proc getCodeHash(host: TransactionHost, address: HostAddress): HostHash {.show.} = let db = host.vmState.readOnlyStateDB @@ -191,10 +188,7 @@ proc getCodeHash(host: TransactionHost, address: HostAddress): HostHash {.show.} if not db.accountExists(address) or db.isEmptyAccount(address): default(HostHash) else: - if host.vmState.fork >= FkPrague: - db.resolveCodeHash(address) - else: - db.getCodeHash(address) + db.getCodeHash(address) proc copyCode(host: TransactionHost, address: HostAddress, code_offset: HostSize, buffer_data: ptr byte, @@ -211,11 +205,7 @@ proc copyCode(host: TransactionHost, address: HostAddress, # # Note, when there is no code, `getCode` result is empty `seq`. It was `nil` # when the DB was first implemented, due to Nim language changes since then. - let code = if host.vmState.fork >= FkPrague: - host.vmState.readOnlyStateDB.resolveCode(address) - else: - host.vmState.readOnlyStateDB.getCode(address) - + let code = host.vmState.readOnlyStateDB.getCode(address) var safe_len: int = code.len # It's safe to assume >= 0. if code_offset >= safe_len.HostSize: @@ -312,6 +302,10 @@ proc setTransientStorage(host: TransactionHost, address: HostAddress, host.vmState.mutateStateDB: db.setTransientStorage(address, key, newVal) +proc getDelegateAddress(host: TransactionHost, address: HostAddress): HostAddress {.show.} = + let db = host.vmState.readOnlyStateDB + db.getDelegateAddress(address) + when use_evmc_glue: {.pop: inline.} const included_from_host_services {.used.} = true @@ -319,4 +313,4 @@ when use_evmc_glue: else: export accountExists, getStorage, storage, getBalance, getCodeSize, getCodeHash, - copyCode, selfDestruct, getTxContext, call, getBlockHash, emitLog + copyCode, selfDestruct, getTxContext, call, getBlockHash, emitLog, getDelegateAddress diff --git a/tools/t8n/testdata/33/exp.json b/tools/t8n/testdata/33/exp.json index af2c4dee7..759b59d8d 100644 --- a/tools/t8n/testdata/33/exp.json +++ b/tools/t8n/testdata/33/exp.json @@ -60,7 +60,7 @@ "gasUsed": "0x15fa9", "currentBaseFee": "0x7", "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "requestsHash": "0x6036c41849da9c076ed79654d434017387a88fb833c2856b32e18218b3341c5f", + "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "requests": [ "0x", "0x",