diff --git a/nimbus/transaction/evmc_host_glue.nim b/nimbus/transaction/evmc_host_glue.nim index 96cc065e0..b1f936123 100644 --- a/nimbus/transaction/evmc_host_glue.nim +++ b/nimbus/transaction/evmc_host_glue.nim @@ -64,6 +64,14 @@ proc emitLog(p: evmc_host_context, address: var evmc_address, toHost(p).emitLog(address.fromEvmc, data, data_size, cast[ptr HostTopic](topics), topics_count) +proc accessAccount(p: evmc_host_context, + address: var evmc_address): evmc_access_status {.cdecl.} = + toHost(p).accessAccount(address.fromEvmc) + +proc accessStorage(p: evmc_host_context, address: var evmc_address, + key: var evmc_bytes32): evmc_access_status {.cdecl.} = + toHost(p).accessStorage(address.fromEvmc, key.fromEvmc) + proc evmcGetHostInterface(): ref evmc_host_interface = var theHostInterface {.global, threadvar.}: ref evmc_host_interface if theHostInterface.isNil: @@ -80,6 +88,8 @@ proc evmcGetHostInterface(): ref evmc_host_interface = get_tx_context: getTxContext, get_block_hash: getBlockHash, emit_log: emitLog, + access_account: accessAccount, + access_storage: accessStorage, ) return theHostInterface diff --git a/nimbus/transaction/host_services.nim b/nimbus/transaction/host_services.nim index f0dd40358..9245fc6b5 100644 --- a/nimbus/transaction/host_services.nim +++ b/nimbus/transaction/host_services.nim @@ -272,6 +272,23 @@ proc emitLog(host: TransactionHost, address: HostAddress, host.computation.logEntries.add(log) #host.logEntries.add(log) +proc accessAccount(host: TransactionHost, address: HostAddress): EvmcAccessStatus {.show.} = + host.vmState.mutateStateDB: + if not db.inAccessList(address): + db.accessList(address) + return EVMC_ACCESS_COLD + else: + return EVMC_ACCESS_WARM + +proc accessStorage(host: TransactionHost, address: HostAddress, + key: HostKey): EvmcAccessStatus {.show.} = + host.vmState.mutateStateDB: + if not db.inAccessList(address, key): + db.accessList(address, key) + return EVMC_ACCESS_COLD + else: + return EVMC_ACCESS_WARM + when use_evmc_glue: {.pop: inline.} const included_from_host_services = true diff --git a/nimbus/transaction/host_types.nim b/nimbus/transaction/host_types.nim index 73eca3dd9..5b81f3c91 100644 --- a/nimbus/transaction/host_types.nim +++ b/nimbus/transaction/host_types.nim @@ -46,6 +46,7 @@ type EvmcStatusCode* = evmc_status_code EvmcCallKind* = evmc_call_kind EvmcStorageStatus* = evmc_storage_status + EvmcAccessStatus* = evmc_access_status EvmcTxContext* = evmc_tx_context EvmcMessage* = evmc_message EvmcResult* = evmc_result @@ -95,4 +96,4 @@ template isStatic*(msg: EvmcMessage): bool = # `evmc_flags` won't export the flags, `evmc_flag_bit_shifts` must be used. export evmc_status_code, evmc_call_kind, - evmc_flag_bit_shifts, evmc_storage_status + evmc_flag_bit_shifts, evmc_storage_status, evmc_access_status diff --git a/nimbus/vm/evmc_api.nim b/nimbus/vm/evmc_api.nim index 789af5f84..fb73d3647 100644 --- a/nimbus/vm/evmc_api.nim +++ b/nimbus/vm/evmc_api.nim @@ -66,6 +66,10 @@ type emit_log*: proc(context: evmc_host_context, address: EthAddress, data: ptr byte, data_size: uint, topics: ptr evmc_bytes32, topics_count: uint) {.cdecl, gcsafe.} + access_account*: proc(context: evmc_host_context, + address: EthAddress): evmc_access_status {.cdecl, gcsafe.} + access_storage*: proc(context: evmc_host_context, address: EthAddress, + key: var evmc_bytes32): evmc_access_status {.cdecl, gcsafe.} 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.} @@ -139,6 +143,15 @@ proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte], proc call*(ctx: HostContext, msg: nimbus_message): nimbus_result {.inline.} = ctx.host.call(ctx.context, msg.unsafeAddr) +proc accessAccount*(ctx: HostContext, + address: EthAddress): evmc_access_status {.inline.} = + ctx.host.access_account(ctx.context, address) + +proc accessStorage*(ctx: HostContext, address: EthAddress, + key: Uint256): evmc_access_status {.inline.} = + var key = toEvmc(key) + ctx.host.access_storage(ctx.context, address, key) + #proc vmHost*(vmState: BaseVMState, gasPrice: GasInt, origin: EthAddress): HostContext = # let host = nim_host_get_interface() # let context = nim_host_create_context(cast[pointer](vmState), gasPrice, toEvmc(origin)) diff --git a/nimbus/vm/evmc_host.nim b/nimbus/vm/evmc_host.nim index 692a915f8..12abf1285 100644 --- a/nimbus/vm/evmc_host.nim +++ b/nimbus/vm/evmc_host.nim @@ -124,6 +124,24 @@ proc hostEmitLogImpl(ctx: Computation, address: EthAddress, log.address = address ctx.addLogEntry(log) +proc hostAccessAccountImpl(ctx: Computation, address: EthAddress): evmc_access_status {.cdecl.} = + ctx.vmState.mutateStateDB: + if not db.inAccessList(address): + db.accessList(address) + return EVMC_ACCESS_COLD + else: + return EVMC_ACCESS_WARM + +proc hostAccessStorageImpl(ctx: Computation, address: EthAddress, + key: var evmc_bytes32): evmc_access_status {.cdecl.} = + let slot = Uint256.fromEvmc(key) + ctx.vmState.mutateStateDB: + if not db.inAccessList(address, slot): + db.accessList(address, slot) + return EVMC_ACCESS_COLD + else: + return EVMC_ACCESS_WARM + proc enterCreateImpl(c: Computation, m: nimbus_message): Computation = # TODO: use evmc_message to evoid copy let childMsg = Message( @@ -215,6 +233,8 @@ proc initHostInterface(): evmc_host_interface = result.get_tx_context = cast[evmc_get_tx_context_fn](hostGetTxContextImpl) result.get_block_hash = cast[evmc_get_block_hash_fn](hostGetBlockHashImpl) result.emit_log = cast[evmc_emit_log_fn](hostEmitLogImpl) + result.access_account = cast[evmc_access_account_fn](hostAccessAccountImpl) + result.access_storage = cast[evmc_access_storage_fn](hostAccessStorageImpl) proc vmSetOptionImpl(vm: ptr evmc_vm, name, value: cstring): evmc_set_option_result {.cdecl.} = return EVMC_SET_OPTION_INVALID_NAME