Transaction: Change transactions to go through unified EVM runner

Simplify transaction validations to use `runComputation`; drop other code.

Getting everything right up to this point to pass all the tests was trickier
than it looks.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
Jamie Lokier 2021-05-17 14:01:41 +01:00 committed by zah
parent bf6569bdeb
commit 8b4f5a1103
1 changed files with 7 additions and 46 deletions

View File

@ -113,60 +113,21 @@ proc rpcEstimateGas*(call: RpcCallData, header: BlockHeader, chain: BaseChainDB,
let callResult = rpcRunComputation(vmState, call, gasLimit, some(fork), true)
return callResult.gasUsed
proc txSetupComputation(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): Computation =
var gas = tx.gasLimit - tx.intrinsicGas(fork)
assert gas >= 0
return setupComputation(CallParams(
proc txCallEvm*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): GasInt =
var call = CallParams(
vmState: vmState,
forkOverride: some(fork),
gasPrice: tx.gasPrice,
gasLimit: gas,
gasLimit: tx.gasLimit,
sender: sender,
to: tx.to,
isCreate: tx.isContractCreation,
value: tx.value,
input: tx.payload
))
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(sender))
for c in activePrecompiles():
db.accessList(c)
# EIP2930 optional access list
if tx.txType == AccessListTxType:
for n in tx.accessListTx.accessList:
db.accessList(n.address)
for x in n.storageKeys:
db.accessList(n.address, UInt256.fromBytesBE(x))
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
)
if tx.txType == AccessListTxType:
shallowCopy(call.accessList, tx.accessListTx.accessList)
return runComputation(call).gasUsed
type
AsmResult* = object