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:
parent
bf6569bdeb
commit
8b4f5a1103
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue