-
-
Save karalabe/fdf7c431fceabc7f2e15ac6f041d6800 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/eth/tracers/api.go b/eth/tracers/api.go | |
index dd90af9b0..75ab40347 100644 | |
--- a/eth/tracers/api.go | |
+++ b/eth/tracers/api.go | |
@@ -169,6 +169,13 @@ type StdTraceConfig struct { | |
TxHash common.Hash | |
} | |
+// txTraceContext is the contextual infos about a transaction before it gets run. | |
+type txTraceContext struct { | |
+ index int // Index of the transaction within the block | |
+ hash common.Hash // Hash of the transaction | |
+ block common.Hash // Hash of the block containing the transaction | |
+} | |
+ | |
// txTraceResult is the result of a single transaction trace. | |
type txTraceResult struct { | |
Result interface{} `json:"result,omitempty"` // Trace results produced by the tracer | |
@@ -266,7 +273,12 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config | |
// Trace all the transactions contained within | |
for i, tx := range task.block.Transactions() { | |
msg, _ := tx.AsMessage(signer) | |
- res, err := api.traceTx(ctx, msg, blockCtx, task.statedb, config) | |
+ txctx := &txTraceContext{ | |
+ index: i, | |
+ hash: tx.Hash(), | |
+ block: task.block.Hash(), | |
+ } | |
+ res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config) | |
if err != nil { | |
task.results[i] = &txTraceResult{Error: err.Error()} | |
log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err) | |
@@ -486,8 +498,12 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac | |
// Fetch and execute the next transaction trace tasks | |
for task := range jobs { | |
msg, _ := txs[task.index].AsMessage(signer) | |
- task.statedb.Prepare(txs[task.index].Hash(), blockHash, task.index) | |
- res, err := api.traceTx(ctx, msg, blockCtx, task.statedb, config) | |
+ txctx := &txTraceContext{ | |
+ index: task.index, | |
+ hash: txs[task.index].Hash(), | |
+ block: blockHash, | |
+ } | |
+ res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config) | |
if err != nil { | |
results[task.index] = &txTraceResult{Error: err.Error()} | |
continue | |
@@ -504,9 +520,8 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac | |
// Generate the next state snapshot fast without tracing | |
msg, _ := tx.AsMessage(signer) | |
- txContext := core.NewEVMTxContext(msg) | |
statedb.Prepare(tx.Hash(), block.Hash(), i) | |
- vmenv := vm.NewEVM(blockCtx, txContext, statedb, api.backend.ChainConfig(), vm.Config{}) | |
+ vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) | |
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil { | |
failed = err | |
break | |
@@ -681,7 +696,12 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config * | |
} | |
defer release() | |
- return api.traceTx(ctx, msg, vmctx, statedb, config) | |
+ txctx := &txTraceContext{ | |
+ index: int(index), | |
+ hash: hash, | |
+ block: blockHash, | |
+ } | |
+ return api.traceTx(ctx, msg, txctx, vmctx, statedb, config) | |
} | |
// TraceCall lets you trace a given eth_call. It collects the structured logs | |
@@ -716,17 +736,14 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHa | |
// Execute the trace | |
msg := args.ToMessage(api.backend.RPCGasCap()) | |
vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) | |
- // We call Prepare here with dummy values -- since we're doing a call and not | |
- // actually executing a tx, not much else to do. The Prepare call initializes | |
- // a new AccessList. | |
- statedb.Prepare(common.Hash{}, common.Hash{}, 0) | |
- return api.traceTx(ctx, msg, vmctx, statedb, config) | |
+ | |
+ return api.traceTx(ctx, msg, new(txTraceContext), vmctx, statedb, config) | |
} | |
// traceTx configures a new tracer according to the provided configuration, and | |
// executes the given message in the provided environment. The return value will | |
// be tracer dependent. | |
-func (api *API) traceTx(ctx context.Context, message core.Message, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) { | |
+func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTraceContext, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) { | |
// Assemble the structured logger or the JavaScript tracer | |
var ( | |
tracer vm.Tracer | |
@@ -762,8 +779,10 @@ func (api *API) traceTx(ctx context.Context, message core.Message, vmctx vm.Bloc | |
} | |
// Run the transaction with tracing enabled. | |
vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Debug: true, Tracer: tracer}) | |
+ | |
// Call Prepare to clear out the statedb access list | |
- statedb.Prepare(common.Hash{}, common.Hash{}, 0) | |
+ statedb.Prepare(txctx.hash, txctx.block, txctx.index) | |
+ | |
result, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas())) | |
if err != nil { | |
return nil, fmt.Errorf("tracing failed: %v", err) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment