Transaction: Make transaction validation use new function txCallEvm

Split out and move the EVM setup and call in `processTransaction` to
`call_evm`.  This is the last part of the main program which calls the EVM
to be moved.  (There's still test code.)

While we're here, move the EIP2929 access list setup too, as the similarity
to `rpcInitialAccessListEIP2929` is obvious.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
Jamie Lokier 2021-05-03 19:14:54 +01:00
parent 4187eb1959
commit c7e1cb61ee
No known key found for this signature in database
GPG Key ID: CBC25C68435C30A2
2 changed files with 29 additions and 21 deletions

View File

@ -54,26 +54,8 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
trace "Sender", sender trace "Sender", sender
trace "txHash", rlpHash = tx.rlpHash trace "txHash", rlpHash = tx.rlpHash
# EIP2929
if fork >= FkBerlin:
vmState.mutateStateDB:
db.accessList(sender)
if not tx.isContractCreation:
#If it's a create-tx, the destination will be added inside evm.create
db.accessList(tx.getRecipient)
for c in activePrecompiles():
db.accessList(c)
if validateTransaction(vmState, tx, sender, fork): if validateTransaction(vmState, tx, sender, fork):
var c = txSetupComputation(tx, sender, vmState, fork) result = txCallEvm(tx, sender, vmState, fork)
vmState.mutateStateDB:
db.subBalance(sender, tx.gasLimit.u256 * tx.gasPrice.u256)
execComputation(c)
result = tx.gasLimit
if not c.shouldBurnGas:
txRefundGas(tx, sender, c)
result -= c.gasMeter.gasRemaining
vmState.cumulativeGasUsed += result vmState.cumulativeGasUsed += result

View File

@ -150,7 +150,7 @@ proc rpcEstimateGas*(call: RpcCallData, header: BlockHeader, chain: BaseChainDB,
let refund = min(c.getGasRefund(), maxRefund) let refund = min(c.getGasRefund(), maxRefund)
return gasLimit - c.gasMeter.gasRemaining - refund return gasLimit - c.gasMeter.gasRemaining - refund
proc txSetupComputation*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): Computation = proc txSetupComputation(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): Computation =
var gas = tx.gasLimit - tx.intrinsicGas(fork) var gas = tx.gasLimit - tx.intrinsicGas(fork)
assert gas >= 0 assert gas >= 0
@ -174,9 +174,35 @@ proc txSetupComputation*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
result = newComputation(vmState, msg) result = newComputation(vmState, msg)
doAssert result.isOriginComputation doAssert result.isOriginComputation
proc txRefundGas*(tx: Transaction, sender: EthAddress, c: Computation) = proc txRefundgas(tx: Transaction, sender: EthAddress, c: Computation) =
let maxRefund = (tx.gasLimit - c.gasMeter.gasRemaining) div 2 let maxRefund = (tx.gasLimit - c.gasMeter.gasRemaining) div 2
let refund = min(c.getGasRefund(), maxRefund) let refund = min(c.getGasRefund(), maxRefund)
c.gasMeter.returnGas(refund) c.gasMeter.returnGas(refund)
c.vmState.mutateStateDB: c.vmState.mutateStateDB:
db.addBalance(sender, c.gasMeter.gasRemaining.u256 * tx.gasPrice.u256) db.addBalance(sender, c.gasMeter.gasRemaining.u256 * tx.gasPrice.u256)
proc txInitialAccessListEIP2929(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork) =
# EIP2929 initial access list.
if fork >= FkBerlin:
vmState.mutateStateDB:
db.accessList(sender)
# For contract creations the EVM will add the contract address to the
# access list itself, after calculating the new contract address.
if not tx.isContractCreation:
db.accessList(tx.getRecipient())
for c in activePrecompiles():
db.accessList(c)
proc txCallEvm*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): GasInt =
txInitialAccessListEIP2929(tx, sender, vmState, fork)
var c = txSetupComputation(tx, sender, vmState, fork)
vmState.mutateStateDB:
db.subBalance(sender, tx.gasLimit.u256 * tx.gasPrice.u256)
execComputation(c)
if c.shouldBurnGas:
return tx.gasLimit
txRefundGas(tx, sender, c)
return tx.gasLimit - c.gasMeter.gasRemaining