@@ -711,14 +711,53 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Ha
711
711
if config != nil && config .Reexec != nil {
712
712
reexec = * config .Reexec
713
713
}
714
- msg , vmctx , statedb , err := api .computeTxEnv (blockHash , int (index ), reexec )
714
+ // Retrieve the block
715
+ block := api .eth .blockchain .GetBlockByHash (blockHash )
716
+ if block == nil {
717
+ return nil , fmt .Errorf ("block %#x not found" , blockHash )
718
+ }
719
+ msg , vmctx , statedb , err := api .computeTxEnv (block , int (index ), reexec )
715
720
if err != nil {
716
721
return nil , err
717
722
}
718
723
// Trace the transaction and return
719
724
return api .traceTx (ctx , msg , vmctx , statedb , config )
720
725
}
721
726
727
+ // TraceCall lets you trace a given eth_call. It collects the structured logs created during the execution of EVM
728
+ // if the given transaction was added on top of the provided block and returns them as a JSON object.
729
+ // You can provide -2 as a block number to trace on top of the pending block.
730
+ func (api * PrivateDebugAPI ) TraceCall (ctx context.Context , args ethapi.CallArgs , blockNrOrHash rpc.BlockNumberOrHash , config * TraceConfig ) (interface {}, error ) {
731
+ // First try to retrieve the state
732
+ statedb , header , err := api .eth .APIBackend .StateAndHeaderByNumberOrHash (ctx , blockNrOrHash )
733
+ if err != nil {
734
+ // Try to retrieve the specified block
735
+ var block * types.Block
736
+ if hash , ok := blockNrOrHash .Hash (); ok {
737
+ block = api .eth .blockchain .GetBlockByHash (hash )
738
+ } else if number , ok := blockNrOrHash .Number (); ok {
739
+ block = api .eth .blockchain .GetBlockByNumber (uint64 (number ))
740
+ }
741
+ if block == nil {
742
+ return nil , fmt .Errorf ("block %v not found: %v" , blockNrOrHash , err )
743
+ }
744
+ // try to recompute the state
745
+ reexec := defaultTraceReexec
746
+ if config != nil && config .Reexec != nil {
747
+ reexec = * config .Reexec
748
+ }
749
+ _ , _ , statedb , err = api .computeTxEnv (block , 0 , reexec )
750
+ if err != nil {
751
+ return nil , err
752
+ }
753
+ }
754
+
755
+ // Execute the trace
756
+ msg := args .ToMessage (api .eth .APIBackend .RPCGasCap ())
757
+ vmctx := core .NewEVMContext (msg , header , api .eth .blockchain , nil )
758
+ return api .traceTx (ctx , msg , vmctx , statedb , config )
759
+ }
760
+
722
761
// traceTx configures a new tracer according to the provided configuration, and
723
762
// executes the given message in the provided environment. The return value will
724
763
// be tracer dependent.
@@ -786,12 +825,8 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
786
825
}
787
826
788
827
// computeTxEnv returns the execution environment of a certain transaction.
789
- func (api * PrivateDebugAPI ) computeTxEnv (blockHash common. Hash , txIndex int , reexec uint64 ) (core.Message , vm.Context , * state.StateDB , error ) {
828
+ func (api * PrivateDebugAPI ) computeTxEnv (block * types. Block , txIndex int , reexec uint64 ) (core.Message , vm.Context , * state.StateDB , error ) {
790
829
// Create the parent state database
791
- block := api .eth .blockchain .GetBlockByHash (blockHash )
792
- if block == nil {
793
- return nil , vm.Context {}, nil , fmt .Errorf ("block %#x not found" , blockHash )
794
- }
795
830
parent := api .eth .blockchain .GetBlock (block .ParentHash (), block .NumberU64 ()- 1 )
796
831
if parent == nil {
797
832
return nil , vm.Context {}, nil , fmt .Errorf ("parent %#x not found" , block .ParentHash ())
@@ -824,5 +859,5 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int, ree
824
859
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
825
860
statedb .Finalise (vmenv .ChainConfig ().IsEIP158 (block .Number ()))
826
861
}
827
- return nil , vm.Context {}, nil , fmt .Errorf ("transaction index %d out of range for block %#x" , txIndex , blockHash )
862
+ return nil , vm.Context {}, nil , fmt .Errorf ("transaction index %d out of range for block %#x" , txIndex , block . Hash () )
828
863
}
0 commit comments