From 40ddbca1ee4c4057fe498f43ab9cedf8410bf096 Mon Sep 17 00:00:00 2001 From: andri lim Date: Tue, 7 Jan 2020 22:44:38 +0700 Subject: [PATCH] [skip ci] simplify EVM message creation --- nimbus/rpc/p2p.nim | 30 ++++----- nimbus/vm/computation.nim | 23 ------- nimbus/vm/interpreter/opcodes_impl.nim | 90 ++++++++++++-------------- nimbus/vm/message.nim | 87 ------------------------- nimbus/vm_state_transactions.nim | 24 +++---- nimbus/vm_types.nim | 39 ++++------- 6 files changed, 80 insertions(+), 213 deletions(-) diff --git a/nimbus/rpc/p2p.nim b/nimbus/rpc/p2p.nim index ae856fc82..2059a4427 100644 --- a/nimbus/rpc/p2p.nim +++ b/nimbus/rpc/p2p.nim @@ -277,21 +277,21 @@ proc setupEthRpc*(node: EthereumNode, chain: BaseChainDB, rpcsrv: RpcServer) = sender, destination: EthAddress, gasLimit, gasPrice: GasInt, contractCreation: bool): BaseComputation = - let - # Handle optional defaults. - message = newMessage( - gas = gasLimit, - gasPrice = gasPrice, - to = destination, - sender = sender, - value = value, - data = data, - code = vmState.readOnlyStateDB.getCode(destination).toSeq, - contractCreation = contractCreation, - options = newMessageOptions(origin = sender, - createAddress = destination)) - - result = newBaseComputation(vmState, blockNumber, message) + #let + # # Handle optional defaults. + # message = newMessage( + # gas = gasLimit, + # gasPrice = gasPrice, + # to = destination, + # sender = sender, + # value = value, + # data = data, + # code = vmState.readOnlyStateDB.getCode(destination).toSeq, + # contractCreation = contractCreation, + # options = newMessageOptions(origin = sender, + # createAddress = destination)) + # + #result = newBaseComputation(vmState, blockNumber, message) rpcsrv.rpc("eth_call") do(call: EthCall, quantityTag: string) -> HexDataStr: ## Executes a new message call immediately without creating a transaction on the block chain. diff --git a/nimbus/vm/computation.nim b/nimbus/vm/computation.nim index f789b5ec2..43edd430e 100644 --- a/nimbus/vm/computation.nim +++ b/nimbus/vm/computation.nim @@ -76,29 +76,6 @@ proc outputHex*(c: BaseComputation): string = proc isSuicided*(c: BaseComputation, address: EthAddress): bool = result = address in c.accountsToDelete -proc prepareChildMessage*( - c: BaseComputation, - gas: GasInt, - to: EthAddress, - value: UInt256, - data: seq[byte], - code: seq[byte], - contractCreation: bool, - options: MessageOptions = newMessageOptions()): Message = - - var childOptions = options - childOptions.depth = c.msg.depth + 1 - result = newMessage( - gas, - c.msg.gasPrice, - to, - c.msg.origin, - value, - data, - code, - contractCreation, - childOptions) - proc snapshot*(comp: BaseComputation) = comp.dbsnapshot.transaction = comp.vmState.chaindb.db.beginTransaction() comp.dbsnapshot.intermediateRoot = comp.vmState.accountDb.rootHash diff --git a/nimbus/vm/interpreter/opcodes_impl.nim b/nimbus/vm/interpreter/opcodes_impl.nim index a94f82d3f..3fbf314af 100644 --- a/nimbus/vm/interpreter/opcodes_impl.nim +++ b/nimbus/vm/interpreter/opcodes_impl.nim @@ -576,18 +576,20 @@ proc setupCreate(computation: BaseComputation, memPos, len: int, value: Uint256, push: 0 return - let childMsg = prepareChildMessage( - computation, - gas = createMsgGas, - to = CREATE_CONTRACT_ADDRESS, - value = value, - data = @[], - code = callData, - contractCreation = true, - options = MessageOptions(createAddress: contractAddress) + let childMsg = Message( + depth: computation.msg.depth + 1, + gas: createMsgGas, + gasPrice: computation.msg.gasPrice, + origin: computation.msg.origin, + sender: computation.msg.storageAddress, + storageAddress: contractAddress, + codeAddress: CREATE_CONTRACT_ADDRESS, + value: value, + data: @[], + code: callData, + contractCreation: true ) - childMsg.sender = computation.msg.storageAddress result = newBaseComputation( computation.vmState, computation.vmState.blockNumber, @@ -627,13 +629,10 @@ proc callParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, Et memoryInputStartPosition, memoryInputSize, memoryOutputStartPosition, memoryOutputSize) = computation.stack.popInt(5) - let to = codeAddress - let sender = computation.msg.storageAddress - result = (gas, value, - to, - sender, + codeAddress, # contractAddress + computation.msg.storageAddress, # sender codeAddress, memoryInputStartPosition, memoryInputSize, @@ -643,7 +642,7 @@ proc callParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, Et proc callCodeParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) = let gas = computation.stack.popInt() - let to = computation.stack.popAddress() + let codeAddress = computation.stack.popAddress() let (value, memoryInputStartPosition, memoryInputSize, @@ -651,9 +650,9 @@ proc callCodeParams(computation: BaseComputation): (UInt256, UInt256, EthAddress result = (gas, value, - to, - computation.msg.storageAddress, # sender - to, # code_address + computation.msg.storageAddress, # contractAddress + computation.msg.storageAddress, # sender + codeAddress, memoryInputStartPosition, memoryInputSize, memoryOutputStartPosition, @@ -667,14 +666,10 @@ proc delegateCallParams(computation: BaseComputation): (UInt256, UInt256, EthAdd let (memoryInputStartPosition, memoryInputSize, memoryOutputStartPosition, memoryOutputSize) = computation.stack.popInt(4) - let to = computation.msg.storageAddress - let sender = computation.msg.sender - let value = computation.msg.value - result = (gas, - value, - to, - sender, + computation.msg.value, # value + computation.msg.storageAddress, # contractAddress + computation.msg.sender, # sender codeAddress, memoryInputStartPosition, memoryInputSize, @@ -684,16 +679,16 @@ proc delegateCallParams(computation: BaseComputation): (UInt256, UInt256, EthAdd proc staticCallParams(computation: BaseComputation): (UInt256, UInt256, EthAddress, EthAddress, EthAddress, UInt256, UInt256, UInt256, UInt256, MsgFlags) = let gas = computation.stack.popInt() - let to = computation.stack.popAddress() + let codeAddress = computation.stack.popAddress() let (memoryInputStartPosition, memoryInputSize, memoryOutputStartPosition, memoryOutputSize) = computation.stack.popInt(4) result = (gas, 0.u256, # value - to, + codeAddress, # contractAddress computation.msg.storageAddress, # sender - to, # codeAddress + codeAddress, memoryInputStartPosition, memoryInputSize, memoryOutputStartPosition, @@ -702,7 +697,7 @@ proc staticCallParams(computation: BaseComputation): (UInt256, UInt256, EthAddre template genCall(callName: untyped, opCode: Op): untyped = proc `callName Setup`(computation: BaseComputation, callNameStr: string): BaseComputation = - let (gas, value, to, sender, + let (gas, value, contractAddress, sender, codeAddress, memoryInputStartPosition, memoryInputSize, memoryOutputStartPosition, memoryOutputSize, @@ -711,9 +706,9 @@ template genCall(callName: untyped, opCode: Op): untyped = let (memInPos, memInLen, memOutPos, memOutLen) = (memoryInputStartPosition.cleanMemRef, memoryInputSize.cleanMemRef, memoryOutputStartPosition.cleanMemRef, memoryOutputSize.cleanMemRef) let isNewAccount = if getFork(computation) >= FkSpurious: - computation.vmState.readOnlyStateDb.isDeadAccount(to) + computation.vmState.readOnlyStateDb.isDeadAccount(contractAddress) else: - not computation.vmState.readOnlyStateDb.accountExists(to) + not computation.vmState.readOnlyStateDb.accountExists(contractAddress) let (memOffset, memLength) = if calcMemSize(memInPos, memInLen) > calcMemSize(memOutPos, memOutLen): (memInPos, memInLen) @@ -744,24 +739,19 @@ template genCall(callName: untyped, opCode: Op): untyped = callData = computation.memory.read(memInPos, memInLen) code = computation.vmState.readOnlyStateDb.getCode(codeAddress) - var childMsg = prepareChildMessage( - computation, - childGasLimit, - to, - value, - callData, - code.toSeq, - false, - MessageOptions(flags: flags) - ) - - childMsg.sender = sender - - when opCode == CallCode: - childMsg.storageAddress = computation.msg.storageAddress - - when opCode == DelegateCall: - childMsg.codeAddress = codeAddress + var childMsg = Message( + depth: computation.msg.depth + 1, + gas: childGasLimit, + gasPrice: computation.msg.gasPrice, + origin: computation.msg.origin, + sender: sender, + storageAddress: contractAddress, + codeAddress: codeAddress, + value: value, + data: callData, + code: code.toSeq, + contractCreation: false, + flags: flags) var childComp = newBaseComputation( computation.vmState, diff --git a/nimbus/vm/message.nim b/nimbus/vm/message.nim index 54ab47b11..56cf993e3 100644 --- a/nimbus/vm/message.nim +++ b/nimbus/vm/message.nim @@ -9,95 +9,8 @@ import eth/common, ../constants, ../validation, ../vm_types, chronicles -logScope: - topics = "message" - -proc `origin=`*(message: var Message, value: EthAddress) = - message.internalOrigin = value - -proc `codeAddress=`*(message: var Message, value: EthAddress) = - message.internalCodeAddress = value - -proc `storageAddress=`*(message: var Message, value: EthAddress) = - message.internalStorageAddress = value - -proc newMessageOptions*( - origin = ZERO_ADDRESS, - depth: int = 0, - createAddress = ZERO_ADDRESS, - codeAddress = ZERO_ADDRESS, - flags: MsgFlags = static(emvcNoFlags)): MessageOptions = - - result = MessageOptions( - origin: origin, - depth: depth, - createAddress: createAddress, - codeAddress: codeAddress, - flags: flags) - -proc newMessage*( - gas: GasInt, - gasPrice: GasInt, - to: EthAddress, - sender: EthAddress, - value: UInt256, - data: seq[byte], - code: seq[byte], - contractCreation: bool, - options: MessageOptions = newMessageOptions()): Message = - - validateGte(options.depth, minimum=0, title="Message.depth") - - trace "New message", - gas = gas, - gasPrice = gasPrice, - destination = to, - sender = sender, - value = value, - depth = options.depth, - storageAddress = options.createAddress, - codeAddress = options.codeAddress, - contractCreation = contractCreation - - new(result) - result.gas = gas - result.gasPrice = gasPrice - result.destination = to - result.sender = sender - result.value = value - result.data = data - result.depth = options.depth - result.storageAddress = options.createAddress - result.codeAddress = options.codeAddress - result.flags = options.flags - result.code = code - result.contractCreation = contractCreation - - if options.origin != ZERO_ADDRESS: - result.internalOrigin = options.origin - else: - result.internalOrigin = sender - -proc origin*(message: Message): EthAddress = - if message.internalOrigin != ZERO_ADDRESS: - message.internalOrigin - else: - message.sender - proc isOrigin*(message: Message): bool = message.sender == message.origin -proc codeAddress*(message: Message): EthAddress = - if message.internalCodeAddress != ZERO_ADDRESS: - message.internalCodeAddress - else: - message.destination - -proc `storageAddress`*(message: Message): EthAddress = - if message.internalStorageAddress != ZERO_ADDRESS: - message.internalStorageAddress - else: - message.destination - proc isCreate*(message: Message): bool = message.contractCreation diff --git a/nimbus/vm_state_transactions.nim b/nimbus/vm_state_transactions.nim index ded4bf661..c7f900867 100644 --- a/nimbus/vm_state_transactions.nim +++ b/nimbus/vm_state_transactions.nim @@ -44,17 +44,19 @@ proc setupComputation*(vmState: BaseVMState, tx: Transaction, sender, recipient: debug "not enough gas to perform calculation", gas=gas return - let msg = newMessage( - gas = gas, - gasPrice = tx.gasPrice, - to = tx.to, - sender = sender, - value = tx.value, - data = data, - code = code, - tx.isContractCreation, - options = newMessageOptions(origin = sender, - createAddress = recipient)) + let msg = Message( + depth: 0, + gas: gas, + gasPrice: tx.gasPrice, + origin: sender, + sender: sender, + storageAddress: recipient, + codeAddress: tx.to, + value: tx.value, + data: data, + code: code, + contractCreation: tx.isContractCreation + ) result = newBaseComputation(vmState, vmState.blockNumber, msg, some(fork)) doAssert result.isOriginComputation diff --git a/nimbus/vm_types.nim b/nimbus/vm_types.nim index c27cc7a26..2e0012040 100644 --- a/nimbus/vm_types.nim +++ b/nimbus/vm_types.nim @@ -98,30 +98,15 @@ type emvcStatic = 1 Message* = ref object - # A message for VM computation - # https://github.com/ethereum/evmc/blob/master/include/evmc/evmc.h - destination*: EthAddress - sender*: EthAddress - value*: UInt256 - data*: seq[byte] - gas*: GasInt - gasPrice*: GasInt - depth*: int - #kind*: CallKind - flags*: MsgFlags - - # Not in EVMC API - # TODO: Done via callback function (v)table in EVMC - code*: seq[byte] - - internalOrigin*: EthAddress - internalCodeAddress*: EthAddress - internalStorageAddress*: EthAddress - contractCreation*: bool - - MessageOptions* = ref object - origin*: EthAddress - depth*: int - createAddress*: EthAddress - codeAddress*: EthAddress - flags*: MsgFlags + depth*: int + gas*: GasInt + gasPrice*: GasInt + origin*: EthAddress + sender*: EthAddress + storageAddress*: EthAddress + codeAddress*: EthAddress + value*: UInt256 + data*: seq[byte] + code*: seq[byte] + contractCreation*: bool + flags*: MsgFlags