Skip to content

Commit 599bcca

Browse files
committed
Fully switch to DEFAULT_HEADER in VM.runTx() to avoid drawing in block code
1 parent 6a803a1 commit 599bcca

File tree

1 file changed

+23
-30
lines changed

1 file changed

+23
-30
lines changed

packages/vm/src/runTx.ts

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cliqueSigner, createEmptyBlock } from '@ethereumjs/block'
1+
import { cliqueSigner, createBlockHeader } from '@ethereumjs/block'
22
import { ConsensusType, Hardfork } from '@ethereumjs/common'
33
import { RLP } from '@ethereumjs/rlp'
44
import { Blob4844Tx, Capability, isBlob4844Tx } from '@ethereumjs/tx'
@@ -51,6 +51,8 @@ import type {
5151
const debug = debugDefault('vm:tx')
5252
const debugGas = debugDefault('vm:tx:gas')
5353

54+
const DEFAULT_HEADER = createBlockHeader()
55+
5456
let enableProfiler = false
5557
const initLabel = 'EVM journal init, address/slot warming, fee validation'
5658
const balanceNonceLabel = 'Balance/Nonce checks and update'
@@ -80,10 +82,7 @@ export async function runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
8082
console.time(entireTxLabel)
8183
}
8284

83-
// create a reasonable default if no block is given
84-
opts.block = opts.block ?? createEmptyBlock({}, { common: vm.common })
85-
86-
if (opts.skipHardForkValidation !== true) {
85+
if (opts.skipHardForkValidation !== true && opts.block !== undefined) {
8786
// If block and tx don't have a same hardfork, set tx hardfork to block
8887
if (opts.tx.common.hardfork() !== opts.block.common.hardfork()) {
8988
opts.tx.common.setHardfork(opts.block.common.hardfork())
@@ -95,7 +94,8 @@ export async function runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
9594
}
9695
}
9796

98-
if (opts.skipBlockGasLimitValidation !== true && opts.block.header.gasLimit < opts.tx.gasLimit) {
97+
const gasLimit = opts.block?.header.gasLimit ?? DEFAULT_HEADER.gasLimit
98+
if (opts.skipBlockGasLimitValidation !== true && gasLimit < opts.tx.gasLimit) {
9999
const msg = _errorMsg('tx has a higher gas limit than the block', vm, opts.block, opts.tx)
100100
throw new Error(msg)
101101
}
@@ -198,10 +198,6 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
198198

199199
const { tx, block } = opts
200200

201-
if (!block) {
202-
throw new Error('block required')
203-
}
204-
205201
/**
206202
* The `beforeTx` event
207203
*
@@ -232,7 +228,8 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
232228
vm.evm.journal.addAlwaysWarmAddress(bytesToUnprefixedHex(tx.to.bytes))
233229
}
234230
if (vm.common.isActivatedEIP(3651)) {
235-
vm.evm.journal.addAlwaysWarmAddress(bytesToUnprefixedHex(block.header.coinbase.bytes))
231+
const coinbase = block?.header.coinbase.bytes ?? DEFAULT_HEADER.coinbase.bytes
232+
vm.evm.journal.addAlwaysWarmAddress(bytesToUnprefixedHex(coinbase))
236233
}
237234
}
238235

@@ -260,7 +257,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
260257
// Ensure that the user was willing to at least pay the base fee
261258
// assert transaction.max_fee_per_gas >= block.base_fee_per_gas
262259
const maxFeePerGas = 'maxFeePerGas' in tx ? tx.maxFeePerGas : tx.gasPrice
263-
const baseFeePerGas = block.header.baseFeePerGas!
260+
const baseFeePerGas = block?.header.baseFeePerGas ?? DEFAULT_HEADER.baseFeePerGas!
264261
if (maxFeePerGas < baseFeePerGas) {
265262
const msg = _errorMsg(
266263
`Transaction's ${
@@ -296,7 +293,8 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
296293
}
297294

298295
// Check balance against upfront tx cost
299-
const upFrontCost = tx.getUpfrontCost(block.header.baseFeePerGas)
296+
const baseFeePerGas = block?.header.baseFeePerGas ?? DEFAULT_HEADER.baseFeePerGas
297+
const upFrontCost = tx.getUpfrontCost(baseFeePerGas)
300298
if (balance < upFrontCost) {
301299
if (opts.skipBalance === true && fromAccount.balance < upFrontCost) {
302300
if (tx.supports(Capability.EIP1559FeeMarket) === false) {
@@ -339,16 +337,7 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
339337
maxCost += totalblobGas * castTx.maxFeePerBlobGas
340338

341339
// 4844 minimum blobGas price check
342-
if (opts.block === undefined) {
343-
const msg = _errorMsg(
344-
`Block option must be supplied to compute blob gas price`,
345-
vm,
346-
block,
347-
tx,
348-
)
349-
throw new Error(msg)
350-
}
351-
blobGasPrice = opts.block.header.getBlobGasPrice()
340+
blobGasPrice = opts.block?.header.getBlobGasPrice() ?? DEFAULT_HEADER.getBlobGasPrice()
352341
if (castTx.maxFeePerBlobGas < blobGasPrice) {
353342
const msg = _errorMsg(
354343
`Transaction's maxFeePerBlobGas ${castTx.maxFeePerBlobGas}) is less than block blobGasPrice (${blobGasPrice}).`,
@@ -393,15 +382,15 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
393382
// EIP-1559 tx
394383
if (tx.supports(Capability.EIP1559FeeMarket)) {
395384
// TODO make txs use the new getEffectivePriorityFee
396-
const baseFee = block.header.baseFeePerGas!
385+
const baseFee = block?.header.baseFeePerGas ?? DEFAULT_HEADER.baseFeePerGas!
397386
inclusionFeePerGas = tx.getEffectivePriorityFee(baseFee)
398387

399388
gasPrice = inclusionFeePerGas + baseFee
400389
} else {
401390
// Have to cast as legacy tx since EIP1559 tx does not have gas price
402391
gasPrice = (<LegacyTx>tx).gasPrice
403392
if (vm.common.isActivatedEIP(1559)) {
404-
const baseFee = block.header.baseFeePerGas!
393+
const baseFee = block?.header.baseFeePerGas ?? DEFAULT_HEADER.baseFeePerGas!
405394
inclusionFeePerGas = (<LegacyTx>tx).gasPrice - baseFee
406395
}
407396
}
@@ -588,9 +577,9 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
588577
// Update miner's balance
589578
let miner
590579
if (vm.common.consensusType() === ConsensusType.ProofOfAuthority) {
591-
miner = cliqueSigner(block.header)
580+
miner = cliqueSigner(block?.header ?? DEFAULT_HEADER)
592581
} else {
593-
miner = block.header.coinbase
582+
miner = block?.header.coinbase ?? DEFAULT_HEADER.coinbase
594583
}
595584

596585
let minerAccount = await state.getAccount(miner)
@@ -702,7 +691,10 @@ async function _runTx(vm: VM, opts: RunTxOpts): Promise<RunTxResult> {
702691
}
703692

704693
// Generate the tx receipt
705-
const gasUsed = opts.blockGasUsed !== undefined ? opts.blockGasUsed : block.header.gasUsed
694+
const gasUsed =
695+
opts.blockGasUsed !== undefined
696+
? opts.blockGasUsed
697+
: (block?.header.gasUsed ?? DEFAULT_HEADER.gasUsed)
706698
const cumulativeGasUsed = gasUsed + results.totalGasSpent
707699
results.receipt = await generateTxReceipt(
708700
vm,
@@ -834,8 +826,9 @@ export async function generateTxReceipt(
834826
* @param msg Base error message
835827
* @hidden
836828
*/
837-
function _errorMsg(msg: string, vm: VM, block: Block, tx: TypedTransaction) {
838-
const blockErrorStr = 'errorStr' in block ? block.errorStr() : 'block'
829+
function _errorMsg(msg: string, vm: VM, block: Block | undefined, tx: TypedTransaction) {
830+
const blockOrHeader = block ?? DEFAULT_HEADER
831+
const blockErrorStr = 'errorStr' in blockOrHeader ? blockOrHeader.errorStr() : 'block'
839832
const txErrorStr = 'errorStr' in tx ? tx.errorStr() : 'tx'
840833

841834
const errorMsg = `${msg} (${vm.errorStr()} -> ${blockErrorStr} -> ${txErrorStr})`

0 commit comments

Comments
 (0)