mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-24 19:19:21 +00:00
[skip ci] simplify EVM message creation
This commit is contained in:
parent
727b477fca
commit
40ddbca1ee
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user