EVMC: Use the same host interface for nested calls as top-level
Prior to this patch, top-level EVM executions and nested EVM executions did their `getStorage` and other requests using a completely different set of host functions. It was just unfinished, to get top-level "new" EVMC working. This finishes the job - it stops using the old methods. Effect: - Functionality added at the EVMC host level will be used by all EVM calls. (The target here is Beam Sync). - The old set of functions are no longer used, so they can be removed. - When EVMC host call tracing is enabled (`showTxCalls = true`), it traces the calls from nested EVM executions as well as top-level. Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
b783756ff3
commit
8fcd8354b1
|
@ -108,6 +108,7 @@ proc evmcExecComputation*(host: TransactionHost): EvmcResult {.inline.} =
|
||||||
return
|
return
|
||||||
|
|
||||||
let hostContext = cast[evmc_host_context](host)
|
let hostContext = cast[evmc_host_context](host)
|
||||||
|
host.hostInterface = hostInterface.unsafeAddr
|
||||||
|
|
||||||
# Without `{.gcsafe.}:` here, the call via `vm.execute` results in a Nim
|
# Without `{.gcsafe.}:` here, the call via `vm.execute` results in a Nim
|
||||||
# compile-time error in a far away function. Starting here, a cascade of
|
# compile-time error in a far away function. Starting here, a cascade of
|
||||||
|
|
|
@ -112,16 +112,25 @@ proc beforeExecEvmcNested(host: TransactionHost, msg: EvmcMessage): Computation
|
||||||
# contribute to the stack frame of `callEvmcNested` below.
|
# contribute to the stack frame of `callEvmcNested` below.
|
||||||
{.noinline.} =
|
{.noinline.} =
|
||||||
host.showCallEntry(msg)
|
host.showCallEntry(msg)
|
||||||
if msg.kind == EVMC_CREATE or msg.kind == EVMC_CREATE2:
|
let c = if msg.kind == EVMC_CREATE or msg.kind == EVMC_CREATE2:
|
||||||
return beforeExecCreateEvmcNested(host, msg)
|
beforeExecCreateEvmcNested(host, msg)
|
||||||
else:
|
else:
|
||||||
return beforeExecCallEvmcNested(host, msg)
|
beforeExecCallEvmcNested(host, msg)
|
||||||
|
when defined(evmc_enabled):
|
||||||
|
c.host.init(cast[ptr nimbus_host_interface](host.hostInterface),
|
||||||
|
cast[typeof(c.host.context)](host))
|
||||||
|
host.saveComputation.add(host.computation)
|
||||||
|
host.computation = c
|
||||||
|
return c
|
||||||
|
|
||||||
proc afterExecEvmcNested(host: TransactionHost, child: Computation,
|
proc afterExecEvmcNested(host: TransactionHost, child: Computation,
|
||||||
kind: EvmcCallKind): EvmcResult
|
kind: EvmcCallKind): EvmcResult
|
||||||
# This function must be declared with `{.noinline.}` to make sure it doesn't
|
# This function must be declared with `{.noinline.}` to make sure it doesn't
|
||||||
# contribute to the stack frame of `callEvmcNested` below.
|
# contribute to the stack frame of `callEvmcNested` below.
|
||||||
{.noinline.} =
|
{.noinline.} =
|
||||||
|
host.computation = host.saveComputation[^1]
|
||||||
|
host.saveComputation[^1] = nil
|
||||||
|
host.saveComputation.setLen(host.saveComputation.len - 1)
|
||||||
if kind == EVMC_CREATE or kind == EVMC_CREATE2:
|
if kind == EVMC_CREATE or kind == EVMC_CREATE2:
|
||||||
afterExecCreateEvmcNested(host, child, result)
|
afterExecCreateEvmcNested(host, child, result)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -63,6 +63,8 @@ type
|
||||||
touchedAccounts*: HashSet[EthAddress]
|
touchedAccounts*: HashSet[EthAddress]
|
||||||
selfDestructs*: HashSet[EthAddress]
|
selfDestructs*: HashSet[EthAddress]
|
||||||
depth*: int
|
depth*: int
|
||||||
|
saveComputation*: seq[Computation]
|
||||||
|
hostInterface*: ptr evmc_host_interface
|
||||||
|
|
||||||
# These versions of `toEvmc` and `fromEvmc` don't flip big/little-endian like
|
# These versions of `toEvmc` and `fromEvmc` don't flip big/little-endian like
|
||||||
# the older functions in `evmc_helpers`. New code only flips with _explicit_
|
# the older functions in `evmc_helpers`. New code only flips with _explicit_
|
||||||
|
|
Loading…
Reference in New Issue