Skip to content

Commit ef4ef60

Browse files
committed
fix: properly init statedb accesslist
refer to: ethereum/go-ethereum#22480
1 parent f96bfcf commit ef4ef60

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

eth/state_accessor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec
218218
}
219219
// Not yet the searched for transaction, execute on top of the current state
220220
vmenv := vm.NewEVM(context, txContext, snapshotdb.Instance(), statedb, eth.blockchain.Config(), vm.Config{})
221+
statedb.Prepare(tx.Hash(), block.Hash(), idx)
221222
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
222223
release()
223224
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)

eth/tracers/api.go

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,13 @@ type StdTraceConfig struct {
171171
TxHash common.Hash
172172
}
173173

174+
// txTraceContext is the contextual infos about a transaction before it gets run.
175+
type txTraceContext struct {
176+
index int // Index of the transaction within the block
177+
hash common.Hash // Hash of the transaction
178+
block common.Hash // Hash of the block containing the transaction
179+
}
180+
174181
// txTraceResult is the result of a single transaction trace.
175182
type txTraceResult struct {
176183
Result interface{} `json:"result,omitempty"` // Trace results produced by the tracer
@@ -269,7 +276,12 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config
269276
// Trace all the transactions contained within
270277
for i, tx := range task.block.Transactions() {
271278
msg, _ := tx.AsMessage(signer)
272-
res, err := api.traceTx(ctx, msg, blockCtx, task.statedb, config)
279+
txctx := &txTraceContext{
280+
index: i,
281+
hash: tx.Hash(),
282+
block: task.block.Hash(),
283+
}
284+
res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config)
273285
if err != nil {
274286
task.results[i] = &txTraceResult{Error: err.Error()}
275287
log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err)
@@ -481,14 +493,22 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
481493
threads = len(txs)
482494
}
483495
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx))
496+
blockHash := block.Hash()
484497
for th := 0; th < threads; th++ {
485498
pend.Add(1)
486499
go func() {
487500
defer pend.Done()
488501
// Fetch and execute the next transaction trace tasks
489502
for task := range jobs {
490503
msg, _ := txs[task.index].AsMessage(signer)
491-
res, err := api.traceTx(ctx, msg, blockCtx, task.statedb, config)
504+
505+
txctx := &txTraceContext{
506+
index: task.index,
507+
hash: txs[task.index].Hash(),
508+
block: blockHash,
509+
}
510+
res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config)
511+
492512
if err != nil {
493513
results[task.index] = &txTraceResult{Error: err.Error()}
494514
continue
@@ -505,9 +525,10 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
505525

506526
// Generate the next state snapshot fast without tracing
507527
msg, _ := tx.AsMessage(signer)
528+
statedb.Prepare(tx.Hash(), block.Hash(), i)
508529
txContext := core.NewEVMTxContext(msg)
509-
510530
vmenv := vm.NewEVM(blockCtx, txContext, snapshotdb.Instance(), statedb, api.backend.ChainConfig(), vm.Config{})
531+
511532
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
512533
failed = err
513534
break
@@ -616,6 +637,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
616637
}
617638
// Execute the transaction and flush any traces to disk
618639
vmenv := vm.NewEVM(vmctx, txContext, snapshotdb.Instance(), statedb, chainConfig, vmConf)
640+
statedb.Prepare(tx.Hash(), block.Hash(), i)
619641
_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
620642
if writer != nil {
621643
writer.Flush()
@@ -673,8 +695,12 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
673695
return nil, err
674696
}
675697
defer release()
676-
677-
return api.traceTx(ctx, msg, vmctx, statedb, config)
698+
txctx := &txTraceContext{
699+
index: int(index),
700+
hash: hash,
701+
block: blockHash,
702+
}
703+
return api.traceTx(ctx, msg, txctx, vmctx, statedb, config)
678704
}
679705

680706
// TraceCall lets you trace a given eth_call. It collects the structured logs
@@ -709,13 +735,14 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHa
709735
// Execute the trace
710736
msg := args.ToMessage(api.backend.RPCGasCap())
711737
vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx))
712-
return api.traceTx(ctx, msg, vmctx, statedb, config)
738+
739+
return api.traceTx(ctx, msg, new(txTraceContext), vmctx, statedb, config)
713740
}
714741

715742
// traceTx configures a new tracer according to the provided configuration, and
716743
// executes the given message in the provided environment. The return value will
717744
// be tracer dependent.
718-
func (api *API) traceTx(ctx context.Context, message core.Message, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
745+
func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTraceContext, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
719746
// Assemble the structured logger or the JavaScript tracer
720747
var (
721748
tracer vm.Tracer
@@ -752,6 +779,9 @@ func (api *API) traceTx(ctx context.Context, message core.Message, vmctx vm.Bloc
752779
// Run the transaction with tracing enabled.
753780
vmenv := vm.NewEVM(vmctx, txContext, snapshotdb.Instance(), statedb, api.backend.ChainConfig(), vm.Config{Debug: true, Tracer: tracer})
754781

782+
// Call Prepare to clear out the statedb access list
783+
statedb.Prepare(txctx.hash, txctx.block, txctx.index)
784+
755785
result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()))
756786
if err != nil {
757787
return nil, fmt.Errorf("tracing failed: %v", err)

0 commit comments

Comments
 (0)