diff --git a/nimbus/transaction/call_evm.nim b/nimbus/transaction/call_evm.nim index f6c296769..2631fa557 100644 --- a/nimbus/transaction/call_evm.nim +++ b/nimbus/transaction/call_evm.nim @@ -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