Transaction: Merge entry point for `*...SetupComputation` functions
There are currently six entry points to running an EVM computation, all with slightly different parameters, and expecting slightly different EVM behaviours. First step in merging them is a common `setupComputation` that replaces all the different `*...SetupComputation` functions. This uses the `TransactionHost` type because it's a step towards using that type for all EVM calls using only EVMC. For now an EVMC message is created then translated to EVM-internal `Message`. It is done this way to build up the new interface in stages where all tests pass at each stage. Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
e60ad129a2
commit
297d789d21
|
@ -7,11 +7,76 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
eth/common/eth_types, stint, options, stew/byteutils,
|
||||
eth/common/eth_types, stint, options, stew/byteutils, stew/ranges/ptr_arith,
|
||||
".."/[vm_types, vm_types2, vm_state, vm_computation, utils],
|
||||
".."/[db/db_chain, config, vm_state_transactions, rpc/hexstrings],
|
||||
".."/[db/accounts_cache, transaction, vm_precompiles, vm_gas_costs], eth/trie/db,
|
||||
".."/vm_internals
|
||||
".."/vm_internals,
|
||||
./host_types
|
||||
|
||||
proc hostToComputationMessage(msg: EvmcMessage): Message =
|
||||
Message(
|
||||
kind: CallKind(msg.kind),
|
||||
depth: msg.depth,
|
||||
gas: msg.gas,
|
||||
sender: msg.sender.fromEvmc,
|
||||
contractAddress: msg.destination.fromEvmc,
|
||||
codeAddress: msg.destination.fromEvmc,
|
||||
value: msg.value.fromEvmc,
|
||||
# When input size is zero, input data pointer may be null.
|
||||
data: if msg.input_size <= 0: @[]
|
||||
else: @(makeOpenArray(msg.input_data, msg.input_size.int)),
|
||||
flags: if msg.isStatic: emvcStatic else: emvcNoFlags
|
||||
)
|
||||
|
||||
type
|
||||
CallParams = object
|
||||
vmState: BaseVMState
|
||||
forkOverride: Option[Fork]
|
||||
origin: Option[HostAddress]
|
||||
gasPrice: GasInt
|
||||
gasLimit: GasInt
|
||||
sender: HostAddress
|
||||
to: HostAddress
|
||||
isCreate: bool
|
||||
value: HostValue
|
||||
input: seq[byte]
|
||||
|
||||
proc setupCall(call: CallParams): TransactionHost =
|
||||
let vmState = call.vmState
|
||||
vmState.setupTxContext(
|
||||
origin = call.origin.get(call.sender),
|
||||
gasPrice = call.gasPrice,
|
||||
forkOverride = call.forkOverride
|
||||
)
|
||||
|
||||
let host = TransactionHost(
|
||||
vmState: vmState,
|
||||
msg: EvmcMessage(
|
||||
kind: if call.isCreate: EVMC_CREATE else: EVMC_CALL,
|
||||
# Default: flags: {},
|
||||
# Default: depth: 0,
|
||||
gas: call.gasLimit,
|
||||
destination: call.to.toEvmc,
|
||||
sender: call.sender.toEvmc,
|
||||
value: call.value.toEvmc,
|
||||
)
|
||||
# All other defaults in `TransactionHost` are fine.
|
||||
)
|
||||
|
||||
if call.input.len > 0:
|
||||
host.msg.input_size = call.input.len.csize_t
|
||||
# Must copy the data so the `host.msg.input_data` pointer
|
||||
# remains valid after the end of `call` lifetime.
|
||||
host.input = call.input
|
||||
host.msg.input_data = host.input[0].addr
|
||||
|
||||
let cMsg = hostToComputationMessage(host.msg)
|
||||
host.computation = newComputation(vmState, cMsg)
|
||||
return host
|
||||
|
||||
proc setupComputation(call: CallParams): Computation =
|
||||
return setupCall(call).computation
|
||||
|
||||
type
|
||||
RpcCallData* = object
|
||||
|
|
Loading…
Reference in New Issue