all: switch evm tx context in the applyMessage

This commit is contained in:
Gary Rong 2024-11-26 12:32:41 +08:00
parent b4d99e3917
commit 1b79f97417
15 changed files with 22 additions and 78 deletions

View file

@ -253,16 +253,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
statedb.SetTxContext(tx.Hash(), txIndex) statedb.SetTxContext(tx.Hash(), txIndex)
var ( var (
txContext = core.NewEVMTxContext(msg) snapshot = statedb.Snapshot()
snapshot = statedb.Snapshot() prevGas = gaspool.Gas()
prevGas = gaspool.Gas()
) )
if tracer != nil && tracer.OnTxStart != nil { if tracer != nil && tracer.OnTxStart != nil {
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
} }
// (ret []byte, usedGas uint64, failed bool, err error) // (ret []byte, usedGas uint64, failed bool, err error)
evm.SetTxContext(txContext)
msgResult, err := core.ApplyMessage(evm, msg, gaspool) msgResult, err := core.ApplyMessage(evm, msg, gaspool)
if err != nil { if err != nil {
statedb.RevertToSnapshot(snapshot) statedb.RevertToSnapshot(snapshot)

View file

@ -65,7 +65,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
return // Also invalid block, bail out return // Also invalid block, bail out
} }
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
if err := precacheTransaction(msg, gaspool, evm); err != nil { if _, err := ApplyMessage(evm, msg, gaspool); err != nil {
return // Ugh, something went horribly wrong, bail out return // Ugh, something went horribly wrong, bail out
} }
// If we're pre-byzantium, pre-load trie nodes for the intermediate root // If we're pre-byzantium, pre-load trie nodes for the intermediate root
@ -78,14 +78,3 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
statedb.IntermediateRoot(true) statedb.IntermediateRoot(true)
} }
} }
// precacheTransaction attempts to apply a transaction to the given state database
// and uses the input parameters for its environment. The goal is not to execute
// the transaction successfully, rather to warm up touched data slots.
func precacheTransaction(msg *Message, gaspool *GasPool, evm *vm.EVM) error {
// Update the evm with the new transaction context.
evm.SetTxContext(NewEVMTxContext(msg))
// Add addresses to access list if applicable
_, err := ApplyMessage(evm, msg, gaspool)
return err
}

View file

@ -143,17 +143,11 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB,
defer func() { hooks.OnTxEnd(receipt, err) }() defer func() { hooks.OnTxEnd(receipt, err) }()
} }
} }
// Create a new context to be used in the EVM environment.
txContext := NewEVMTxContext(msg)
evm.SetTxContext(txContext)
// Apply the transaction to the current state (included in the env). // Apply the transaction to the current state (included in the env).
result, err := ApplyMessage(evm, msg, gp) result, err := ApplyMessage(evm, msg, gp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Update the state with pending changes. // Update the state with pending changes.
var root []byte var root []byte
if evm.ChainConfig().IsByzantium(blockNumber) { if evm.ChainConfig().IsByzantium(blockNumber) {

View file

@ -187,6 +187,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
// indicates a core error meaning that the message would always fail for that particular // indicates a core error meaning that the message would always fail for that particular
// state and would never be accepted within a block. // state and would never be accepted within a block.
func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, error) { func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, error) {
evm.SetTxContext(NewEVMTxContext(msg))
return NewStateTransition(evm, msg, gp).TransitionDb() return NewStateTransition(evm, msg, gp).TransitionDb()
} }

View file

@ -217,21 +217,19 @@ func execute(ctx context.Context, call *core.Message, opts *Options, gasLimit ui
func run(ctx context.Context, call *core.Message, opts *Options) (*core.ExecutionResult, error) { func run(ctx context.Context, call *core.Message, opts *Options) (*core.ExecutionResult, error) {
// Assemble the call and the call context // Assemble the call and the call context
var ( var (
msgContext = core.NewEVMTxContext(call)
evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil) evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil)
dirtyState = opts.State.Copy() dirtyState = opts.State.Copy()
) )
// Lower the basefee to 0 to avoid breaking EVM // Lower the basefee to 0 to avoid breaking EVM
// invariants (basefee < feecap). // invariants (basefee < feecap).
if msgContext.GasPrice.Sign() == 0 { if call.GasPrice.Sign() == 0 {
evmContext.BaseFee = new(big.Int) evmContext.BaseFee = new(big.Int)
} }
if msgContext.BlobFeeCap != nil && msgContext.BlobFeeCap.BitLen() == 0 { if call.BlobGasFeeCap != nil && call.BlobGasFeeCap.BitLen() == 0 {
evmContext.BlobBaseFee = new(big.Int) evmContext.BlobBaseFee = new(big.Int)
} }
evm := vm.NewEVM(evmContext, dirtyState, opts.Config, vm.Config{NoBaseFee: true}) evm := vm.NewEVM(evmContext, dirtyState, opts.Config, vm.Config{NoBaseFee: true})
evm.SetTxContext(msgContext)
// Monitor the outer context and interrupt the EVM upon cancellation. To avoid // Monitor the outer context and interrupt the EVM upon cancellation. To avoid
// a dangling goroutine until the outer estimation finishes, create an internal // a dangling goroutine until the outer estimation finishes, create an internal
// context for the lifetime of this method call. // context for the lifetime of this method call.

View file

@ -255,8 +255,6 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
} }
// Assemble the transaction call message and return if the requested offset // Assemble the transaction call message and return if the requested offset
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
txContext := core.NewEVMTxContext(msg)
evm.SetTxContext(txContext)
// Not yet the searched for transaction, execute on top of the current state // Not yet the searched for transaction, execute on top of the current state
statedb.SetTxContext(tx.Hash(), idx) statedb.SetTxContext(tx.Hash(), idx)

View file

@ -546,11 +546,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
} }
var ( msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
txContext = core.NewEVMTxContext(msg)
)
evm.SetTxContext(txContext)
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil { if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err) log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err)
@ -708,7 +704,6 @@ txloop:
// Generate the next state snapshot fast without tracing // Generate the next state snapshot fast without tracing
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
evm.SetTxContext(core.NewEVMTxContext(msg))
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil { if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
failed = err failed = err
break txloop break txloop
@ -792,12 +787,11 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
// Prepare the transaction for un-traced execution // Prepare the transaction for un-traced execution
var ( var (
msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee()) msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
txContext = core.NewEVMTxContext(msg) vmConf vm.Config
vmConf vm.Config dump *os.File
dump *os.File writer *bufio.Writer
writer *bufio.Writer err error
err error
) )
// If the transaction needs tracing, swap out the configs // If the transaction needs tracing, swap out the configs
if tx.Hash() == txHash || txHash == (common.Hash{}) { if tx.Hash() == txHash || txHash == (common.Hash{}) {
@ -820,7 +814,6 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
} }
} }
// Execute the transaction and flush any traces to disk // Execute the transaction and flush any traces to disk
evm.SetTxContext(txContext)
statedb.SetTxContext(tx.Hash(), i) statedb.SetTxContext(tx.Hash(), i)
if vmConf.Tracer.OnTxStart != nil { if vmConf.Tracer.OnTxStart != nil {
vmConf.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) vmConf.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
@ -1016,7 +1009,6 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
} }
// The actual TxContext will be created as part of ApplyTransactionWithEVM. // The actual TxContext will be created as part of ApplyTransactionWithEVM.
evm := vm.NewEVM(vmctx, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true}) evm := vm.NewEVM(vmctx, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true})
evm.SetTxContext(vm.TxContext{GasPrice: message.GasPrice, BlobFeeCap: message.BlobGasFeeCap})
// Define a meaningful timeout of a single transaction trace // Define a meaningful timeout of a single transaction trace
if config.Timeout != nil { if config.Timeout != nil {

View file

@ -177,8 +177,6 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
return tx, context, statedb, release, nil return tx, context, statedb, release, nil
} }
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
txContext := core.NewEVMTxContext(msg)
evm.SetTxContext(txContext)
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
} }

View file

@ -133,7 +133,6 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
t.Fatalf("failed to prepare transaction for tracing: %v", err) t.Fatalf("failed to prepare transaction for tracing: %v", err)
} }
evm := vm.NewEVM(context, logState, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) evm := vm.NewEVM(context, logState, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
evm.SetTxContext(core.NewEVMTxContext(msg))
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
if err != nil { if err != nil {
@ -176,6 +175,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
} }
} }
// TODO (@sina) this benchmark has been broken for a while, please fix it.
func BenchmarkTracers(b *testing.B) { func BenchmarkTracers(b *testing.B) {
files, err := os.ReadDir(filepath.Join("testdata", "call_tracer")) files, err := os.ReadDir(filepath.Join("testdata", "call_tracer"))
if err != nil { if err != nil {
@ -206,11 +206,6 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
b.Fatalf("failed to parse testcase input: %v", err) b.Fatalf("failed to parse testcase input: %v", err)
} }
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
origin, _ := signer.Sender(tx)
txContext := vm.TxContext{
Origin: origin,
GasPrice: tx.GasPrice(),
}
context := test.Context.toBlockContext(test.Genesis) context := test.Context.toBlockContext(test.Genesis)
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
if err != nil { if err != nil {
@ -227,12 +222,11 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
b.Fatalf("failed to create call tracer: %v", err) b.Fatalf("failed to create call tracer: %v", err)
} }
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
evm.SetTxContext(txContext)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
snap := state.StateDB.Snapshot() snap := state.StateDB.Snapshot()
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
if _, err = st.TransitionDb(); err != nil { if err != nil {
b.Fatalf("failed to execute transaction: %v", err) b.Fatalf("failed to execute transaction: %v", err)
} }
if _, err = tracer.GetResult(); err != nil { if _, err = tracer.GetResult(); err != nil {
@ -372,12 +366,7 @@ func TestInternals(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("test %v: failed to sign transaction: %v", tc.name, err) t.Fatalf("test %v: failed to sign transaction: %v", tc.name, err)
} }
txContext := vm.TxContext{
Origin: origin,
GasPrice: tx.GasPrice(),
}
evm := vm.NewEVM(context, logState, config, vm.Config{Tracer: tc.tracer.Hooks}) evm := vm.NewEVM(context, logState, config, vm.Config{Tracer: tc.tracer.Hooks})
evm.SetTxContext(txContext)
msg, err := core.TransactionToMessage(tx, signer, big.NewInt(0)) msg, err := core.TransactionToMessage(tx, signer, big.NewInt(0))
if err != nil { if err != nil {
t.Fatalf("test %v: failed to create message: %v", tc.name, err) t.Fatalf("test %v: failed to create message: %v", tc.name, err)

View file

@ -99,7 +99,6 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
return fmt.Errorf("failed to prepare transaction for tracing: %v", err) return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
} }
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
evm.SetTxContext(core.NewEVMTxContext(msg))
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
if err != nil { if err != nil {

View file

@ -107,7 +107,6 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
t.Fatalf("failed to prepare transaction for tracing: %v", err) t.Fatalf("failed to prepare transaction for tracing: %v", err)
} }
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks}) evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
evm.SetTxContext(core.NewEVMTxContext(msg))
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
if err != nil { if err != nil {

View file

@ -47,10 +47,6 @@ func BenchmarkTransactionTrace(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
txContext := vm.TxContext{
Origin: from,
GasPrice: tx.GasPrice(),
}
context := vm.BlockContext{ context := vm.BlockContext{
CanTransfer: core.CanTransfer, CanTransfer: core.CanTransfer,
Transfer: core.Transfer, Transfer: core.Transfer,
@ -90,7 +86,6 @@ func BenchmarkTransactionTrace(b *testing.B) {
//EnableReturnData: false, //EnableReturnData: false,
}) })
evm := vm.NewEVM(context, state.StateDB, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer.Hooks()}) evm := vm.NewEVM(context, state.StateDB, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer.Hooks()})
evm.SetTxContext(txContext)
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
if err != nil { if err != nil {
b.Fatalf("failed to prepare transaction for tracing: %v", err) b.Fatalf("failed to prepare transaction for tracing: %v", err)
@ -101,8 +96,7 @@ func BenchmarkTransactionTrace(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
snap := state.StateDB.Snapshot() snap := state.StateDB.Snapshot()
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) res, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
res, err := st.TransitionDb()
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }

View file

@ -867,7 +867,6 @@ func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *s
if precompiles != nil { if precompiles != nil {
evm.SetPrecompiles(precompiles) evm.SetPrecompiles(precompiles)
} }
evm.SetTxContext(core.NewEVMTxContext(msg))
res, err := applyMessageWithEVM(ctx, evm, msg, timeout, gp) res, err := applyMessageWithEVM(ctx, evm, msg, timeout, gp)
// If an internal state error occurred, let that have precedence. Otherwise, // If an internal state error occurred, let that have precedence. Otherwise,
// a "trie root missing" type of error will masquerade as e.g. "insufficient gas" // a "trie root missing" type of error will masquerade as e.g. "insufficient gas"
@ -1331,17 +1330,17 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
// Apply the transaction with the access list tracer // Apply the transaction with the access list tracer
tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles) tracer := logger.NewAccessListTracer(accessList, args.from(), to, precompiles)
config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true} config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true}
vmenv := b.GetEVM(ctx, statedb, header, &config, nil) evm := b.GetEVM(ctx, statedb, header, &config, nil)
// Lower the basefee to 0 to avoid breaking EVM // Lower the basefee to 0 to avoid breaking EVM
// invariants (basefee < feecap). // invariants (basefee < feecap).
if msg.GasPrice.Sign() == 0 { if msg.GasPrice.Sign() == 0 {
vmenv.Context.BaseFee = new(big.Int) evm.Context.BaseFee = new(big.Int)
} }
if msg.BlobGasFeeCap != nil && msg.BlobGasFeeCap.BitLen() == 0 { if msg.BlobGasFeeCap != nil && msg.BlobGasFeeCap.BitLen() == 0 {
vmenv.Context.BlobBaseFee = new(big.Int) evm.Context.BlobBaseFee = new(big.Int)
} }
vmenv.SetTxContext(core.NewEVMTxContext(msg)) res, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit))
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit))
if err != nil { if err != nil {
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.ToTransaction(types.LegacyTxType).Hash(), err) return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.ToTransaction(types.LegacyTxType).Hash(), err)
} }

View file

@ -207,7 +207,6 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
tracer.reset(tx.Hash(), uint(i)) tracer.reset(tx.Hash(), uint(i))
// EoA check is always skipped, even in validation mode. // EoA check is always skipped, even in validation mode.
msg := call.ToMessage(header.BaseFee, !sim.validate, true) msg := call.ToMessage(header.BaseFee, !sim.validate, true)
evm.SetTxContext(core.NewEVMTxContext(msg))
result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp) result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp)
if err != nil { if err != nil {
txErr := txValidationError(err) txErr := txValidationError(err)

View file

@ -277,7 +277,6 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
} }
// Prepare the EVM. // Prepare the EVM.
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
context.GetHash = vmTestBlockHash context.GetHash = vmTestBlockHash
context.BaseFee = baseFee context.BaseFee = baseFee
@ -294,7 +293,6 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
context.BlobBaseFee = eip4844.CalcBlobFee(*t.json.Env.ExcessBlobGas) context.BlobBaseFee = eip4844.CalcBlobFee(*t.json.Env.ExcessBlobGas)
} }
evm := vm.NewEVM(context, st.StateDB, config, vmconfig) evm := vm.NewEVM(context, st.StateDB, config, vmconfig)
evm.SetTxContext(txContext)
if tracer := vmconfig.Tracer; tracer != nil && tracer.OnTxStart != nil { if tracer := vmconfig.Tracer; tracer != nil && tracer.OnTxStart != nil {
tracer.OnTxStart(evm.GetVMContext(), nil, msg.From) tracer.OnTxStart(evm.GetVMContext(), nil, msg.From)