Skip to content

Commit 0678a13

Browse files
Merge pull request ethereum#32 from ethereum-optimism/jg/custom_rpc_error
Fix daisy chain
2 parents 3433606 + 1a7298c commit 0678a13

File tree

8 files changed

+310
-183
lines changed

8 files changed

+310
-183
lines changed

core/state_transition.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,9 @@ func (st *StateTransition) innerTransitionDb() (*ExecutionResult, error) {
428428
st.state.AddBalance(st.evm.Context.Coinbase, fee)
429429
}
430430

431-
if optimismConfig := st.evm.ChainConfig().Optimism; optimismConfig != nil {
431+
// Hack: Check that we are post bedrock to enable op-geth to be able to create pseudo pre-bedrock blocks (these are pre-bedrock, but don't follow l2 geth rules)
432+
// Note optimismConfig will not be nil if rules.IsOptimismBedrock is true
433+
if optimismConfig := st.evm.ChainConfig().Optimism; optimismConfig != nil && rules.IsOptimismBedrock {
432434
st.state.AddBalance(params.OptimismBaseFeeRecipient, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.evm.Context.BaseFee))
433435
if cost := st.evm.Context.L1CostFunc(st.evm.Context.BlockNumber.Uint64(), st.msg); cost != nil {
434436
st.state.AddBalance(params.OptimismL1FeeRecipient, cost)

eth/tracers/api.go

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ import (
2323
"encoding/json"
2424
"errors"
2525
"fmt"
26+
"math/big"
2627
"os"
2728
"runtime"
2829
"sync"
2930
"time"
3031

31-
"github.com/ethereum/go-ethereum"
3232
"github.com/ethereum/go-ethereum/common"
3333
"github.com/ethereum/go-ethereum/common/hexutil"
3434
"github.com/ethereum/go-ethereum/consensus"
@@ -138,7 +138,7 @@ func (api *API) blockByNumber(ctx context.Context, number rpc.BlockNumber) (*typ
138138
return nil, err
139139
}
140140
if block == nil {
141-
return nil, fmt.Errorf("block #%d %w", number, ethereum.NotFound)
141+
return nil, fmt.Errorf("block #%d not found", number)
142142
}
143143
return block, nil
144144
}
@@ -151,7 +151,7 @@ func (api *API) blockByHash(ctx context.Context, hash common.Hash) (*types.Block
151151
return nil, err
152152
}
153153
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())
155155
}
156156
return block, nil
157157
}
@@ -231,6 +231,7 @@ type txTraceTask struct {
231231
// TraceChain returns the structured logs created during the execution of EVM
232232
// between two blocks (excluding start) and returns them as a JSON object.
233233
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
234235
from, err := api.blockByNumber(ctx, start)
235236
if err != nil {
236237
return nil, err
@@ -456,33 +457,47 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
456457
// EVM and returns them as a JSON object.
457458
func (api *API) TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *TraceConfig) ([]*txTraceResult, error) {
458459
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 {
467461
return nil, err
468462
}
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+
469477
return api.traceBlock(ctx, block, config)
470478
}
471479

472480
// TraceBlockByHash returns the structured logs created during the execution of
473481
// EVM and returns them as a JSON object.
474482
func (api *API) TraceBlockByHash(ctx context.Context, hash common.Hash, config *TraceConfig) ([]*txTraceResult, error) {
475483
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 {
484485
return nil, err
485486
}
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+
486501
return api.traceBlock(ctx, block, config)
487502
}
488503

@@ -532,6 +547,7 @@ func (api *API) StandardTraceBlockToFile(ctx context.Context, hash common.Hash,
532547
// of intermediate roots: the stateroot after each transaction.
533548
func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config *TraceConfig) ([]common.Hash, error) {
534549
block, _ := api.blockByHash(ctx, hash)
550+
// TODO: Cannot get intermediate roots for pre-bedrock block without daisy chain
535551
if block == nil {
536552
// Check in the bad blocks
537553
block = rawdb.ReadBadBlock(api.backend.ChainDb(), hash)
@@ -823,18 +839,24 @@ func containsTx(block *types.Block, hash common.Hash) bool {
823839
// and returns them as a JSON object.
824840
func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
825841
// 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)
827843
if err != nil {
828844
return nil, err
829845
}
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
835857
}
836-
return histResult, err
837858
}
859+
838860
// It shouldn't happen in practice.
839861
if blockNumber == 0 {
840862
return nil, errors.New("genesis is not traceable")
@@ -885,32 +907,14 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
885907
} else {
886908
return nil, errors.New("invalid arguments; neither block nor hash specified")
887909
}
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-
911910
if err != nil {
912911
return nil, err
913912
}
913+
914+
if api.backend.ChainConfig().IsOptimismPreBedrock(block.Number()) {
915+
return nil, errors.New("l2geth does not have a debug_traceCall method")
916+
}
917+
914918
// try to recompute the state
915919
reexec := defaultTraceReexec
916920
if config != nil && config.Reexec != nil {

0 commit comments

Comments
 (0)