From c500ae77b1e8f509c405b55bd43e9edfa7bb615e Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Sat, 28 Sep 2024 10:59:55 +0200 Subject: [PATCH] evmc fixes These fixes probably introduce a bit of overhead, which at this point doesn't really matter since we don't use evmc for anything but testing --- nimbus/evm/evmc_api.nim | 82 +++++++++++++++++++------------ nimbus/evm/evmc_helpers.nim | 14 ++++-- nimbus/transaction/host_types.nim | 6 +-- 3 files changed, 63 insertions(+), 39 deletions(-) diff --git a/nimbus/evm/evmc_api.nim b/nimbus/evm/evmc_api.nim index 9f84b8bd51..c2f8ad2c68 100644 --- a/nimbus/evm/evmc_api.nim +++ b/nimbus/evm/evmc_api.nim @@ -61,30 +61,30 @@ type padding* : array[4, byte] nimbus_host_interface* = object - account_exists*: proc(context: evmc_host_context, address: EthAddress): bool {.cdecl, gcsafe, raises: [].} - get_storage*: proc(context: evmc_host_context, address: EthAddress, key: ptr evmc_uint256be): evmc_uint256be {.cdecl, gcsafe, raises: [].} - set_storage*: proc(context: evmc_host_context, address: EthAddress, + account_exists*: proc(context: evmc_host_context, address: ptr evmc_address): bool {.cdecl, gcsafe, raises: [].} + get_storage*: proc(context: evmc_host_context, address: ptr evmc_address, key: ptr evmc_uint256be): evmc_uint256be {.cdecl, gcsafe, raises: [].} + set_storage*: proc(context: evmc_host_context, address: ptr evmc_address, key, value: ptr evmc_uint256be): evmc_storage_status {.cdecl, gcsafe, raises: [].} - get_balance*: proc(context: evmc_host_context, address: EthAddress): evmc_uint256be {.cdecl, gcsafe, raises: [].} - get_code_size*: proc(context: evmc_host_context, address: EthAddress): uint {.cdecl, gcsafe, raises: [].} - get_code_hash*: proc(context: evmc_host_context, address: EthAddress): Hash256 {.cdecl, gcsafe, raises: [].} - copy_code*: proc(context: evmc_host_context, address: EthAddress, + get_balance*: proc(context: evmc_host_context, address: ptr evmc_address): evmc_uint256be {.cdecl, gcsafe, raises: [].} + get_code_size*: proc(context: evmc_host_context, address: ptr evmc_address): uint {.cdecl, gcsafe, raises: [].} + get_code_hash*: proc(context: evmc_host_context, address: ptr evmc_address): evmc_bytes32 {.cdecl, gcsafe, raises: [].} + copy_code*: proc(context: evmc_host_context, address: ptr evmc_address, code_offset: int, buffer_data: ptr byte, buffer_size: int): int {.cdecl, gcsafe, raises: [].} - selfdestruct*: proc(context: evmc_host_context, address, beneficiary: EthAddress) {.cdecl, gcsafe, raises: [].} + selfdestruct*: proc(context: evmc_host_context, address, beneficiary: ptr evmc_address) {.cdecl, gcsafe, raises: [].} call*: proc(context: evmc_host_context, msg: ptr nimbus_message): nimbus_result {.cdecl, gcsafe, raises: [].} get_tx_context*: proc(context: evmc_host_context): nimbus_tx_context {.cdecl, gcsafe, raises: [].} - get_block_hash*: proc(context: evmc_host_context, number: int64): Hash256 {.cdecl, gcsafe, raises: [].} - emit_log*: proc(context: evmc_host_context, address: EthAddress, + get_block_hash*: proc(context: evmc_host_context, number: int64): evmc_bytes32 {.cdecl, gcsafe, raises: [].} + emit_log*: proc(context: evmc_host_context, address: ptr evmc_address, data: ptr byte, data_size: uint, topics: ptr evmc_bytes32, topics_count: uint) {.cdecl, gcsafe, raises: [].} access_account*: proc(context: evmc_host_context, - address: EthAddress): evmc_access_status {.cdecl, gcsafe, raises: [].} - access_storage*: proc(context: evmc_host_context, address: EthAddress, - key: var evmc_bytes32): evmc_access_status {.cdecl, gcsafe, raises: [].} - get_transient_storage*: proc(context: evmc_host_context, address: EthAddress, + address: ptr evmc_address): evmc_access_status {.cdecl, gcsafe, raises: [].} + access_storage*: proc(context: evmc_host_context, address: ptr evmc_address, + key: ptr evmc_bytes32): evmc_access_status {.cdecl, gcsafe, raises: [].} + get_transient_storage*: proc(context: evmc_host_context, address: ptr evmc_address, key: ptr evmc_uint256be): evmc_uint256be {.cdecl, gcsafe, raises: [].} - set_transient_storage*: proc(context: evmc_host_context, address: EthAddress, + set_transient_storage*: proc(context: evmc_host_context, address: ptr evmc_address, key, value: ptr evmc_uint256be) {.cdecl, gcsafe, raises: [].} proc nim_host_get_interface*(): ptr nimbus_host_interface {.importc, cdecl.} @@ -108,45 +108,57 @@ proc getTxContext*(ctx: HostContext): nimbus_tx_context = ctx.host.get_tx_context(ctx.context) proc getBlockHash*(ctx: HostContext, number: BlockNumber): Hash256 = - ctx.host.get_block_hash(ctx.context, number.int64) + Hash256.fromEvmc ctx.host.get_block_hash(ctx.context, number.int64) proc accountExists*(ctx: HostContext, address: EthAddress): bool = - ctx.host.account_exists(ctx.context, address) + var address = toEvmc(address) + ctx.host.account_exists(ctx.context, address.addr) proc getStorage*(ctx: HostContext, address: EthAddress, key: UInt256): UInt256 = - var key = toEvmc(key) - UInt256.fromEvmc ctx.host.get_storage(ctx.context, address, key.addr) + var + address = toEvmc(address) + key = toEvmc(key) + UInt256.fromEvmc ctx.host.get_storage(ctx.context, address.addr, key.addr) proc setStorage*(ctx: HostContext, address: EthAddress, key, value: UInt256): evmc_storage_status = var + address = toEvmc(address) key = toEvmc(key) value = toEvmc(value) - ctx.host.set_storage(ctx.context, address, key.addr, value.addr) + ctx.host.set_storage(ctx.context, address.addr, key.addr, value.addr) proc getBalance*(ctx: HostContext, address: EthAddress): UInt256 = - UInt256.fromEvmc ctx.host.get_balance(ctx.context, address) + var address = toEvmc(address) + UInt256.fromEvmc ctx.host.get_balance(ctx.context, address.addr) proc getCodeSize*(ctx: HostContext, address: EthAddress): uint = - ctx.host.get_code_size(ctx.context, address) + var address = toEvmc(address) + ctx.host.get_code_size(ctx.context, address.addr) proc getCodeHash*(ctx: HostContext, address: EthAddress): Hash256 = - ctx.host.get_code_hash(ctx.context, address) + var address = toEvmc(address) + Hash256.fromEvmc ctx.host.get_code_hash(ctx.context, address.addr) proc copyCode*(ctx: HostContext, address: EthAddress, codeOffset: int = 0): seq[byte] = let size = ctx.getCodeSize(address).int if size - codeOffset > 0: result = newSeq[byte](size - codeOffset) - let read = ctx.host.copy_code(ctx.context, address, + var address = toEvmc(address) + let read = ctx.host.copy_code(ctx.context, address.addr, codeOffset, result[0].addr, result.len) doAssert(read == result.len) proc selfDestruct*(ctx: HostContext, address, beneficiary: EthAddress) = - ctx.host.selfdestruct(ctx.context, address, beneficiary) + var + address = toEvmc(address) + beneficiary = toEvmc(beneficiary) + ctx.host.selfdestruct(ctx.context, address.addr, beneficiary.addr) proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte], topics: ptr evmc_bytes32, topicsCount: int) = - ctx.host.emit_log(ctx.context, address, if data.len > 0: data[0].unsafeAddr else: nil, + var address = toEvmc(address) + ctx.host.emit_log(ctx.context, address.addr, if data.len > 0: data[0].unsafeAddr else: nil, data.len.uint, topics, topicsCount.uint) proc call*(ctx: HostContext, msg: nimbus_message): nimbus_result = @@ -154,23 +166,29 @@ proc call*(ctx: HostContext, msg: nimbus_message): nimbus_result = proc accessAccount*(ctx: HostContext, address: EthAddress): evmc_access_status = - ctx.host.access_account(ctx.context, address) + var address = toEvmc(address) + ctx.host.access_account(ctx.context, address.addr) proc accessStorage*(ctx: HostContext, address: EthAddress, key: UInt256): evmc_access_status = - var key = toEvmc(key) - ctx.host.access_storage(ctx.context, address, key) + var + address = toEvmc(address) + key = toEvmc(key) + ctx.host.access_storage(ctx.context, address.addr, key.addr) proc getTransientStorage*(ctx: HostContext, address: EthAddress, key: UInt256): UInt256 = - var key = toEvmc(key) - UInt256.fromEvmc ctx.host.get_transient_storage(ctx.context, address, key.addr) + var + address = toEvmc(address) + key = toEvmc(key) + UInt256.fromEvmc ctx.host.get_transient_storage(ctx.context, address.addr, key.addr) proc setTransientStorage*(ctx: HostContext, address: EthAddress, key, value: UInt256) = var + address = toEvmc(address) key = toEvmc(key) value = toEvmc(value) - ctx.host.set_transient_storage(ctx.context, address, key.addr, value.addr) + ctx.host.set_transient_storage(ctx.context, address.addr, key.addr, value.addr) # The following two templates put here because the stupid style checker # complaints about block_number vs blockNumber and chain_id vs chainId diff --git a/nimbus/evm/evmc_helpers.nim b/nimbus/evm/evmc_helpers.nim index c816f37709..e3eb2f02fe 100644 --- a/nimbus/evm/evmc_helpers.nim +++ b/nimbus/evm/evmc_helpers.nim @@ -18,9 +18,13 @@ const evmc_native* {.booldefine.} = false func toEvmc*(a: EthAddress): evmc_address {.inline.} = - cast[evmc_address](a) + evmc_address(bytes: a.data) -func toEvmc*(h: Hash256 | ContractSalt): evmc_bytes32 {.inline.} = +func toEvmc*(h: Hash256): evmc_bytes32 {.inline.} = + doAssert sizeof(h) == sizeof(evmc_bytes32) + evmc_bytes32(bytes: h.data) + +func toEvmc*(h: ContractSalt): evmc_bytes32 {.inline.} = doAssert sizeof(h) == sizeof(evmc_bytes32) cast[evmc_bytes32](h) @@ -31,9 +35,11 @@ func toEvmc*(n: UInt256): evmc_uint256be {.inline.} = cast[evmc_uint256be](n.toBytesBE) func fromEvmc*(T: type, n: evmc_bytes32): T {.inline.} = - when T is Hash256 | ContractSalt: + when T is ContractSalt: doAssert sizeof(n) == sizeof(T) cast[T](n) + elif T is Hash32: + Hash32(n.bytes) elif T is UInt256: when evmc_native: cast[UInt256](n) @@ -43,7 +49,7 @@ func fromEvmc*(T: type, n: evmc_bytes32): T {.inline.} = {.error: "cannot convert unsupported evmc type".} func fromEvmc*(a: evmc_address): EthAddress {.inline.} = - cast[EthAddress](a) + EthAddress(a.bytes) when isMainModule: import ../constants diff --git a/nimbus/transaction/host_types.nim b/nimbus/transaction/host_types.nim index 7c2d7ed484..e5e628f55e 100644 --- a/nimbus/transaction/host_types.nim +++ b/nimbus/transaction/host_types.nim @@ -74,16 +74,16 @@ template toEvmc*(n: UInt256): evmc_uint256be = cast[evmc_uint256be](n) template toEvmc*(n: Hash256): evmc_bytes32 = - cast[evmc_bytes32](n) + evmc_bytes32(bytes: n.data) template toEvmc*(address: EthAddress): evmc_address = - cast[evmc_address](address) + evmc_address(bytes: address.data) template fromEvmc*(n: evmc_uint256be): UInt256 = cast[UInt256](n) template fromEvmc*(address: evmc_address): EthAddress = - cast[EthAddress](address) + EthAddress(address.bytes) template flip256*(word256: evmc_uint256be): evmc_uint256be = cast[evmc_uint256be](UInt256.fromBytesBE(word256.bytes).toBytes(cpuEndian))