From 3518fe99f66533c3ad9f891cfdc1d265bd595bff Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Thu, 19 Jan 2023 17:51:09 -0700 Subject: [PATCH] ethapi/api: updates to optimism daisy chain post-testing --- internal/ethapi/api.go | 86 ++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 42a451356..3b55d9f6c 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -25,6 +25,8 @@ import ( "strings" "time" + "github.com/ethereum/go-ethereum" + "github.com/davecgh/go-spew/spew" "github.com/tyler-smith/go-bip39" @@ -631,12 +633,12 @@ func (s *BlockChainAPI) BlockNumber() hexutil.Uint64 { // given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta // block numbers are also allowed. func (s *BlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { - state, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { + header, err := headerByNumberOrHash(ctx, s.b, blockNrOrHash) + if err != nil { return nil, err } - if header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res hexutil.Big err := s.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getBalance", address, blockNrOrHash) @@ -649,6 +651,11 @@ func (s *BlockChainAPI) GetBalance(ctx context.Context, address common.Address, } } + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if state == nil || err != nil { + return nil, err + } + return (*hexutil.Big)(state.GetBalance(address)), state.Error() } @@ -671,11 +678,11 @@ type StorageResult struct { // GetProof returns the Merkle-proof for a given account and optionally some storage keys. func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) { - state, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { + header, err := headerByNumberOrHash(ctx, s.b, blockNrOrHash) + if err != nil { return nil, err } - if header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res AccountResult err := s.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getProof", address, storageKeys, blockNrOrHash) @@ -687,6 +694,10 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st return nil, rpc.ErrNoHistoricalFallback } } + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if state == nil || err != nil { + return nil, err + } storageTrie, err := state.StorageTrie(address) if err != nil { return nil, err @@ -863,12 +874,12 @@ func (s *BlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash // GetCode returns the code stored at the given address in the state for the given block number. func (s *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { + header, err := headerByNumberOrHash(ctx, s.b, blockNrOrHash) + if err != nil { return nil, err } - if header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res hexutil.Bytes err := s.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getCode", address, blockNrOrHash) @@ -881,6 +892,11 @@ func (s *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blo } } + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if state == nil || err != nil { + return nil, err + } + code := state.GetCode(address) return code, state.Error() } @@ -889,12 +905,12 @@ func (s *BlockChainAPI) GetCode(ctx context.Context, address common.Address, blo // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block // numbers are also allowed. func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, hexKey string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { + header, err := headerByNumberOrHash(ctx, s.b, blockNrOrHash) + if err != nil { return nil, err } - if header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res hexutil.Bytes err := s.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getStorageAt", address, hexKey, blockNrOrHash) @@ -907,6 +923,11 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address } } + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if state == nil || err != nil { + return nil, err + } + key, err := decodeHash(hexKey) if err != nil { return nil, fmt.Errorf("unable to decode storage key: %s", err) @@ -915,6 +936,18 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address return res[:], state.Error() } +// The HeaderByNumberOrHash method returns a nil error and nil header +// if the header is not found, but only for nonexistent block numbers. This is +// different from StateAndHeaderByNumberOrHash. To account for this discrepancy, +// headerOrNumberByHash will properly convert the error into an ethereum.NotFound. +func headerByNumberOrHash(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { + header, err := b.HeaderByNumberOrHash(ctx, blockNrOrHash) + if header == nil { + return nil, fmt.Errorf("header %w", ethereum.NotFound) + } + return header, err +} + // OverrideAccount indicates the overriding fields of account during the execution // of a message call. // Note, state and stateDiff can't be specified at the same time. If state is @@ -1102,8 +1135,12 @@ func (e *revertError) ErrorData() interface{} { // Note, this function doesn't make and changes in the state/blockchain and is // useful to execute and retrieve values. func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) { - header, err := s.b.HeaderByNumberOrHash(ctx, blockNrOrHash) - if err == nil && header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + header, err := headerByNumberOrHash(ctx, s.b, blockNrOrHash) + if err != nil { + return nil, err + } + + if s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res hexutil.Bytes err := s.b.HistoricalRPCService().CallContext(ctx, &res, "eth_call", args, blockNrOrHash, overrides) @@ -1255,8 +1292,12 @@ func (s *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, b bNrOrHash = *blockNrOrHash } - header, err := s.b.HeaderByNumberOrHash(ctx, bNrOrHash) - if err == nil && header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + header, err := headerByNumberOrHash(ctx, s.b, bNrOrHash) + if err != nil { + return 0, err + } + + if s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res hexutil.Uint64 err := s.b.HistoricalRPCService().CallContext(ctx, &res, "eth_estimateGas", args, blockNrOrHash) @@ -1524,7 +1565,7 @@ func (s *BlockChainAPI) CreateAccessList(ctx context.Context, args TransactionAr bNrOrHash = *blockNrOrHash } - header, err := s.b.HeaderByNumberOrHash(ctx, bNrOrHash) + header, err := headerByNumberOrHash(ctx, s.b, bNrOrHash) if err == nil && header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res accessListResult @@ -1691,12 +1732,12 @@ func (s *TransactionAPI) GetTransactionCount(ctx context.Context, address common return (*hexutil.Uint64)(&nonce), nil } // Resolve block number and use its state to ask for the nonce - state, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { + header, err := headerByNumberOrHash(ctx, s.b, blockNrOrHash) + if err != nil { return nil, err } - if header != nil && s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { + if s.b.ChainConfig().IsOptimismPreBedrock(header.Number) { if s.b.HistoricalRPCService() != nil { var res hexutil.Uint64 err := s.b.HistoricalRPCService().CallContext(ctx, &res, "eth_getTransactionCount", address, blockNrOrHash) @@ -1709,6 +1750,11 @@ func (s *TransactionAPI) GetTransactionCount(ctx context.Context, address common } } + state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) + if state == nil || err != nil { + return nil, err + } + nonce := state.GetNonce(address) return (*hexutil.Uint64)(&nonce), state.Error() }