From c7e1cb61eecf9aab0417ed2f91b9067ac4884c2f Mon Sep 17 00:00:00 2001 From: Jamie Lokier Date: Mon, 3 May 2021 19:14:54 +0100 Subject: [PATCH] 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 --- nimbus/p2p/executor.nim | 20 +------------------- nimbus/transaction/call_evm.nim | 30 ++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/nimbus/p2p/executor.nim b/nimbus/p2p/executor.nim index 41b9c995f..63b2d43d8 100644 --- a/nimbus/p2p/executor.nim +++ b/nimbus/p2p/executor.nim @@ -54,26 +54,8 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta trace "Sender", sender 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): - var c = txSetupComputation(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 + result = txCallEvm(tx, sender, vmState, fork) vmState.cumulativeGasUsed += result diff --git a/nimbus/transaction/call_evm.nim b/nimbus/transaction/call_evm.nim index 2c0ed6901..09f41365f 100644 --- a/nimbus/transaction/call_evm.nim +++ b/nimbus/transaction/call_evm.nim @@ -150,7 +150,7 @@ proc rpcEstimateGas*(call: RpcCallData, header: BlockHeader, chain: BaseChainDB, let refund = min(c.getGasRefund(), maxRefund) 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) assert gas >= 0 @@ -174,9 +174,35 @@ proc txSetupComputation*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta result = newComputation(vmState, msg) 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 refund = min(c.getGasRefund(), maxRefund) c.gasMeter.returnGas(refund) c.vmState.mutateStateDB: 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