mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-24 11:11:59 +00:00
EVMC: Add missing EIP-2929 (Berlin) functions to EVMC host
The update for London (EIP-1559) in 1cdb30df ("bump nim-emvc with evmc revision 8.0.0 to 9.0.0") really bumped EVMC ABI version from 7.5 up to 9. In other words, it skipped Berlin, going direct from Istanbul to London. That was accompanied by EVMC changes in 05e9b891 ("EIP-3198: add baseFee op code in nim-evm"), which added the API changes needed for London. But the missing Berlin functions weren't added in the move to London. As a result, our EVMC host became incompatible with Berlin, London, and really all revisions of the ABI, and if a third party EVM was loaded, it crashed. This commit adds the missing Berlin host support, and makes our ABI binary-compatible with real EVMC again. Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
7972e7a55c
commit
74f53c7761
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user