@@ -23,12 +23,12 @@ import (
23
23
"encoding/json"
24
24
"errors"
25
25
"fmt"
26
+ "math/big"
26
27
"os"
27
28
"runtime"
28
29
"sync"
29
30
"time"
30
31
31
- "github.com/ethereum/go-ethereum"
32
32
"github.com/ethereum/go-ethereum/common"
33
33
"github.com/ethereum/go-ethereum/common/hexutil"
34
34
"github.com/ethereum/go-ethereum/consensus"
@@ -138,7 +138,7 @@ func (api *API) blockByNumber(ctx context.Context, number rpc.BlockNumber) (*typ
138
138
return nil , err
139
139
}
140
140
if block == nil {
141
- return nil , fmt .Errorf ("block #%d %w " , number , ethereum . NotFound )
141
+ return nil , fmt .Errorf ("block #%d not found " , number )
142
142
}
143
143
return block , nil
144
144
}
@@ -151,7 +151,7 @@ func (api *API) blockByHash(ctx context.Context, hash common.Hash) (*types.Block
151
151
return nil , err
152
152
}
153
153
if block == nil {
154
- return nil , fmt .Errorf ("block %s %w " , hash .Hex (), ethereum . NotFound )
154
+ return nil , fmt .Errorf ("block %s not found " , hash .Hex ())
155
155
}
156
156
return block , nil
157
157
}
@@ -231,6 +231,7 @@ type txTraceTask struct {
231
231
// TraceChain returns the structured logs created during the execution of EVM
232
232
// between two blocks (excluding start) and returns them as a JSON object.
233
233
func (api * API ) TraceChain (ctx context.Context , start , end rpc.BlockNumber , config * TraceConfig ) (* rpc.Subscription , error ) { // Fetch the block interval that we want to trace
234
+ // TODO: Need to implement a fallback for this
234
235
from , err := api .blockByNumber (ctx , start )
235
236
if err != nil {
236
237
return nil , err
@@ -456,33 +457,47 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
456
457
// EVM and returns them as a JSON object.
457
458
func (api * API ) TraceBlockByNumber (ctx context.Context , number rpc.BlockNumber , config * TraceConfig ) ([]* txTraceResult , error ) {
458
459
block , err := api .blockByNumber (ctx , number )
459
- if errors .Is (err , ethereum .NotFound ) && api .backend .HistoricalRPCService () != nil {
460
- var histResult []* txTraceResult
461
- err = api .backend .HistoricalRPCService ().CallContext (ctx , & histResult , "debug_traceBlockByNumber" , number , config )
462
- if err != nil && err .Error () == "not found" {
463
- return nil , fmt .Errorf ("block #%d %w" , number , ethereum .NotFound )
464
- }
465
- return histResult , err
466
- } else if err != nil {
460
+ if err != nil {
467
461
return nil , err
468
462
}
463
+
464
+ if api .backend .ChainConfig ().IsOptimismPreBedrock (block .Number ()) {
465
+ if api .backend .HistoricalRPCService () != nil {
466
+ var histResult []* txTraceResult
467
+ err = api .backend .HistoricalRPCService ().CallContext (ctx , & histResult , "debug_traceBlockByNumber" , number , config )
468
+ if err != nil {
469
+ return nil , fmt .Errorf ("historical backend error: %w" , err )
470
+ }
471
+ return histResult , nil
472
+ } else {
473
+ return nil , rpc .ErrNoHistoricalFallback
474
+ }
475
+ }
476
+
469
477
return api .traceBlock (ctx , block , config )
470
478
}
471
479
472
480
// TraceBlockByHash returns the structured logs created during the execution of
473
481
// EVM and returns them as a JSON object.
474
482
func (api * API ) TraceBlockByHash (ctx context.Context , hash common.Hash , config * TraceConfig ) ([]* txTraceResult , error ) {
475
483
block , err := api .blockByHash (ctx , hash )
476
- if errors .Is (err , ethereum .NotFound ) && api .backend .HistoricalRPCService () != nil {
477
- var histResult []* txTraceResult
478
- err = api .backend .HistoricalRPCService ().CallContext (ctx , & histResult , "debug_traceBlockByHash" , hash , config )
479
- if err != nil && err .Error () == "not found" {
480
- return nil , fmt .Errorf ("block #%d %w" , hash , ethereum .NotFound )
481
- }
482
- return histResult , err
483
- } else if err != nil {
484
+ if err != nil {
484
485
return nil , err
485
486
}
487
+
488
+ if api .backend .ChainConfig ().IsOptimismPreBedrock (block .Number ()) {
489
+ if api .backend .HistoricalRPCService () != nil {
490
+ var histResult []* txTraceResult
491
+ err = api .backend .HistoricalRPCService ().CallContext (ctx , & histResult , "debug_traceBlockByHash" , hash , config )
492
+ if err != nil {
493
+ return nil , fmt .Errorf ("historical backend error: %w" , err )
494
+ }
495
+ return histResult , nil
496
+ } else {
497
+ return nil , rpc .ErrNoHistoricalFallback
498
+ }
499
+ }
500
+
486
501
return api .traceBlock (ctx , block , config )
487
502
}
488
503
@@ -532,6 +547,7 @@ func (api *API) StandardTraceBlockToFile(ctx context.Context, hash common.Hash,
532
547
// of intermediate roots: the stateroot after each transaction.
533
548
func (api * API ) IntermediateRoots (ctx context.Context , hash common.Hash , config * TraceConfig ) ([]common.Hash , error ) {
534
549
block , _ := api .blockByHash (ctx , hash )
550
+ // TODO: Cannot get intermediate roots for pre-bedrock block without daisy chain
535
551
if block == nil {
536
552
// Check in the bad blocks
537
553
block = rawdb .ReadBadBlock (api .backend .ChainDb (), hash )
@@ -823,18 +839,24 @@ func containsTx(block *types.Block, hash common.Hash) bool {
823
839
// and returns them as a JSON object.
824
840
func (api * API ) TraceTransaction (ctx context.Context , hash common.Hash , config * TraceConfig ) (interface {}, error ) {
825
841
// GetTransaction returns 0 for the blocknumber if the transaction is not found
826
- tx , blockHash , blockNumber , index , err := api .backend .GetTransaction (ctx , hash )
842
+ _ , blockHash , blockNumber , index , err := api .backend .GetTransaction (ctx , hash )
827
843
if err != nil {
828
844
return nil , err
829
845
}
830
- if tx == nil && api .backend .HistoricalRPCService () != nil {
831
- var histResult []* txTraceResult
832
- err = api .backend .HistoricalRPCService ().CallContext (ctx , & histResult , "debug_traceTransaction" , hash , config )
833
- if err != nil && err .Error () == "not found" {
834
- return nil , fmt .Errorf ("transaction %s %w" , hash , ethereum .NotFound )
846
+
847
+ if api .backend .ChainConfig ().IsOptimismPreBedrock (new (big.Int ).SetUint64 (blockNumber )) {
848
+ if api .backend .HistoricalRPCService () != nil {
849
+ var histResult json.RawMessage
850
+ err := api .backend .HistoricalRPCService ().CallContext (ctx , & histResult , "debug_traceTransaction" , hash , config )
851
+ if err != nil {
852
+ return nil , fmt .Errorf ("historical backend error: %w" , err )
853
+ }
854
+ return histResult , nil
855
+ } else {
856
+ return nil , rpc .ErrNoHistoricalFallback
835
857
}
836
- return histResult , err
837
858
}
859
+
838
860
// It shouldn't happen in practice.
839
861
if blockNumber == 0 {
840
862
return nil , errors .New ("genesis is not traceable" )
@@ -885,32 +907,14 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
885
907
} else {
886
908
return nil , errors .New ("invalid arguments; neither block nor hash specified" )
887
909
}
888
-
889
- // If block still holds no value, but we have an error, then one of the two previous conditions
890
- // was entered, meaning:
891
- // 1. blockNrOrHash has either a valid block or hash
892
- // 2. we don't have that block locally
893
- if block == nil && errors .Is (err , ethereum .NotFound ) && api .backend .HistoricalRPCService () != nil {
894
- var histResult json.RawMessage
895
- err = api .backend .HistoricalRPCService ().CallContext (ctx , & histResult , "debug_traceCall" , args , blockNrOrHash , config )
896
- if err != nil && err .Error () == "not found" {
897
- // Not found locally or in history. We need to return different errors based on the input
898
- // in order match geth's native behavior
899
- if hash , ok := blockNrOrHash .Hash (); ok {
900
- return nil , fmt .Errorf ("block %s %w" , hash , ethereum .NotFound )
901
- } else if number , ok := blockNrOrHash .Number (); ok {
902
- return nil , fmt .Errorf ("block #%d %w" , number , ethereum .NotFound )
903
- }
904
- } else if err != nil {
905
- return nil , fmt .Errorf ("error querying historical RPC: %w" , err )
906
- }
907
-
908
- return histResult , nil
909
- }
910
-
911
910
if err != nil {
912
911
return nil , err
913
912
}
913
+
914
+ if api .backend .ChainConfig ().IsOptimismPreBedrock (block .Number ()) {
915
+ return nil , errors .New ("l2geth does not have a debug_traceCall method" )
916
+ }
917
+
914
918
// try to recompute the state
915
919
reexec := defaultTraceReexec
916
920
if config != nil && config .Reexec != nil {
0 commit comments