Skip to content

Commit 40ad6be

Browse files
authored
eth/tracers: fix precompile move feat for debug_traceCall (ethereum#31348)
`debug_traceCall` was ignoring the override `movePrecompileToAddress`. Now it is at feature-parity with eth_call.
1 parent d85f796 commit 40ad6be

File tree

2 files changed

+58
-11
lines changed

2 files changed

+58
-11
lines changed

eth/tracers/api.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
279279
TxIndex: i,
280280
TxHash: tx.Hash(),
281281
}
282-
res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, task.statedb, config)
282+
res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, task.statedb, config, nil)
283283
if err != nil {
284284
task.results[i] = &txTraceResult{TxHash: tx.Hash(), Error: err.Error()}
285285
log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err)
@@ -632,7 +632,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
632632
TxIndex: i,
633633
TxHash: tx.Hash(),
634634
}
635-
res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, statedb, config)
635+
res, err := api.traceTx(ctx, tx, msg, txctx, blockCtx, statedb, config, nil)
636636
if err != nil {
637637
return nil, err
638638
}
@@ -676,7 +676,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
676676
// concurrent use.
677677
// See: https://github.com/ethereum/go-ethereum/issues/29114
678678
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
679-
res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config)
679+
res, err := api.traceTx(ctx, txs[task.index], msg, txctx, blockCtx, task.statedb, config, nil)
680680
if err != nil {
681681
results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()}
682682
continue
@@ -894,7 +894,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
894894
TxIndex: int(index),
895895
TxHash: hash,
896896
}
897-
return api.traceTx(ctx, tx, msg, txctx, vmctx, statedb, config)
897+
return api.traceTx(ctx, tx, msg, txctx, vmctx, statedb, config, nil)
898898
}
899899

900900
// TraceCall lets you trace a given eth_call. It collects the structured logs
@@ -907,10 +907,11 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
907907
func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceCallConfig) (interface{}, error) {
908908
// Try to retrieve the specified block
909909
var (
910-
err error
911-
block *types.Block
912-
statedb *state.StateDB
913-
release StateReleaseFunc
910+
err error
911+
block *types.Block
912+
statedb *state.StateDB
913+
release StateReleaseFunc
914+
precompiles vm.PrecompiledContracts
914915
)
915916
if hash, ok := blockNrOrHash.Hash(); ok {
916917
block, err = api.blockByHash(ctx, hash)
@@ -952,7 +953,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
952953
config.BlockOverrides.Apply(&vmctx)
953954
rules := api.backend.ChainConfig().Rules(vmctx.BlockNumber, vmctx.Random != nil, vmctx.Time)
954955

955-
precompiles := vm.ActivePrecompiledContracts(rules)
956+
precompiles = vm.ActivePrecompiledContracts(rules)
956957
if err := config.StateOverrides.Apply(statedb, precompiles); err != nil {
957958
return nil, err
958959
}
@@ -977,13 +978,13 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
977978
if config != nil {
978979
traceConfig = &config.TraceConfig
979980
}
980-
return api.traceTx(ctx, tx, msg, new(Context), vmctx, statedb, traceConfig)
981+
return api.traceTx(ctx, tx, msg, new(Context), vmctx, statedb, traceConfig, precompiles)
981982
}
982983

983984
// traceTx configures a new tracer according to the provided configuration, and
984985
// executes the given message in the provided environment. The return value will
985986
// be tracer dependent.
986-
func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
987+
func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig, precompiles vm.PrecompiledContracts) (interface{}, error) {
987988
var (
988989
tracer *Tracer
989990
err error
@@ -1009,6 +1010,9 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
10091010
}
10101011
tracingStateDB := state.NewHookedState(statedb, tracer.Hooks)
10111012
evm := vm.NewEVM(vmctx, tracingStateDB, api.backend.ChainConfig(), vm.Config{Tracer: tracer.Hooks, NoBaseFee: true})
1013+
if precompiles != nil {
1014+
evm.SetPrecompiles(precompiles)
1015+
}
10121016

10131017
// Define a meaningful timeout of a single transaction trace
10141018
if config.Timeout != nil {

eth/tracers/api_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ func TestTracingWithOverrides(t *testing.T) {
642642
t.Parallel()
643643
// Initialize test accounts
644644
accounts := newAccounts(3)
645+
ecRecoverAddress := common.HexToAddress("0x0000000000000000000000000000000000000001")
645646
storageAccount := common.Address{0x13, 37}
646647
genesis := &core.Genesis{
647648
Config: params.TestChainConfig,
@@ -940,6 +941,48 @@ func TestTracingWithOverrides(t *testing.T) {
940941
},
941942
want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000055"}`,
942943
},
944+
{ // Call to precompile ECREC (0x01), but code was modified to add 1 to input
945+
blockNumber: rpc.LatestBlockNumber,
946+
call: ethapi.TransactionArgs{
947+
From: &randomAccounts[0].addr,
948+
To: &ecRecoverAddress,
949+
Data: newRPCBytes(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")),
950+
},
951+
config: &TraceCallConfig{
952+
StateOverrides: &override.StateOverride{
953+
randomAccounts[0].addr: override.OverrideAccount{
954+
Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether))),
955+
},
956+
ecRecoverAddress: override.OverrideAccount{
957+
// The code below adds one to input
958+
Code: newRPCBytes(common.Hex2Bytes("60003560010160005260206000f3")),
959+
MovePrecompileTo: &randomAccounts[2].addr,
960+
},
961+
},
962+
},
963+
want: `{"gas":21167,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000002"}`,
964+
},
965+
{ // Call to ECREC Precompiled on a different address, expect the original behaviour of ECREC precompile
966+
blockNumber: rpc.LatestBlockNumber,
967+
call: ethapi.TransactionArgs{
968+
From: &randomAccounts[0].addr,
969+
To: &randomAccounts[2].addr, // Moved EcRecover
970+
Data: newRPCBytes(common.Hex2Bytes("82f3df49d3645876de6313df2bbe9fbce593f21341a7b03acdb9423bc171fcc9000000000000000000000000000000000000000000000000000000000000001cba13918f50da910f2d55a7ea64cf716ba31dad91856f45908dde900530377d8a112d60f36900d18eb8f9d3b4f85a697b545085614509e3520e4b762e35d0d6bd")),
971+
},
972+
config: &TraceCallConfig{
973+
StateOverrides: &override.StateOverride{
974+
randomAccounts[0].addr: override.OverrideAccount{
975+
Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether))),
976+
},
977+
ecRecoverAddress: override.OverrideAccount{
978+
// The code below adds one to input
979+
Code: newRPCBytes(common.Hex2Bytes("60003560010160005260206000f3")),
980+
MovePrecompileTo: &randomAccounts[2].addr, // Move EcRecover to this address
981+
},
982+
},
983+
},
984+
want: `{"gas":25664,"failed":false,"returnValue":"000000000000000000000000c6e93f4c1920eaeaa1e699f76a7a8c18e3056074"}`,
985+
},
943986
}
944987
for i, tc := range testSuite {
945988
result, err := api.TraceCall(context.Background(), tc.call, rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, tc.config)

0 commit comments

Comments
 (0)