From 4c3fd40d18f940c6684b2083febeb1dce111e97d Mon Sep 17 00:00:00 2001 From: Amir Deris Date: Tue, 7 Apr 2026 16:45:23 -0700 Subject: [PATCH 1/5] reused context and block in simulate.go, updated simulate_test --- evmrpc/simulate.go | 43 ++++++++++++++++++++++++----------------- evmrpc/simulate_test.go | 25 +++++++++--------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/evmrpc/simulate.go b/evmrpc/simulate.go index 50d4f1ca12..1baf28cc7a 100644 --- a/evmrpc/simulate.go +++ b/evmrpc/simulate.go @@ -261,7 +261,7 @@ func NewBackend( } func (b *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *ethtypes.Header, error) { - height, isLatestBlock, err := b.getBlockHeight(ctx, blockNrOrHash) + tmBlock, height, isLatestBlock, err := b.getResultBlockByNumberOrHash(ctx, blockNrOrHash) if err != nil { return nil, nil, err } @@ -273,7 +273,7 @@ func (b *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHas return nil, nil, err } } - header := b.getHeader(big.NewInt(height)) + header := b.getHeader(ctx, big.NewInt(height), tmBlock) header.BaseFee = b.keeper.GetNextBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt() return state.NewDBImpl(sdkCtx, b.keeper, true), header, nil } @@ -388,7 +388,7 @@ func (b Backend) BlockByNumber(ctx context.Context, bn rpc.BlockNumber) (*ethtyp }) } } - header := b.getHeader(big.NewInt(blockNum)) + header := b.getHeader(ctx, big.NewInt(blockNum), tmBlock) block := ðtypes.Block{ Header_: header, Txs: txs, @@ -433,11 +433,11 @@ func (b *Backend) Engine() consensus.Engine { } func (b *Backend) HeaderByNumber(ctx context.Context, bn rpc.BlockNumber) (*ethtypes.Header, error) { - height, _, err := b.getBlockHeight(ctx, rpc.BlockNumberOrHashWithNumber(bn)) + tmBlock, height, _, err := b.getResultBlockByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(bn)) if err != nil { return nil, err } - return b.getHeader(big.NewInt(height)), nil + return b.getHeader(ctx, big.NewInt(height), tmBlock), nil } func (b *Backend) StateAtTransaction(ctx context.Context, block *ethtypes.Block, txIndex int, reexec uint64) (*ethtypes.Transaction, vm.BlockContext, vm.StateDB, tracers.StateReleaseFunc, error) { @@ -552,7 +552,7 @@ func (b *Backend) GetEVM(_ context.Context, msg *core.Message, stateDB vm.StateD } func (b *Backend) CurrentHeader() *ethtypes.Header { - header := b.getHeader(big.NewInt(b.ctxProvider(LatestCtxHeight).BlockHeight())) + header := b.getHeader(context.Background(), big.NewInt(b.ctxProvider(LatestCtxHeight).BlockHeight()), nil) header.BaseFee = b.keeper.GetNextBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt() return header } @@ -561,7 +561,9 @@ func (b *Backend) SuggestGasTipCap(context.Context) (*big.Int, error) { return utils.Big0, nil } -func (b *Backend) getBlockHeight(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (int64, bool, error) { +// getResultBlockByNumberOrHash resolves blockNrOrHash to a Tendermint ResultBlock in one RPC path +// (by hash or by number, including latest). Callers can pass tmBlock to getHeader to avoid a second block fetch. +func (b *Backend) getResultBlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*coretypes.ResultBlock, int64, bool, error) { var ( block *coretypes.ResultBlock err error @@ -571,16 +573,16 @@ func (b *Backend) getBlockHeight(ctx context.Context, blockNrOrHash rpc.BlockNum if blockNrOrHash.BlockHash != nil { block, err = blockByHashRespectingWatermarks(ctx, b.tmClient, b.watermarks, blockNrOrHash.BlockHash[:], 1) if err != nil { - return 0, false, err + return nil, 0, false, err } - return block.Block.Height, false, nil + return block, block.Block.Height, false, nil } var blockNumberPtr *int64 if blockNrOrHash.BlockNumber != nil { blockNumberPtr, err = getBlockNumber(ctx, b.tmClient, *blockNrOrHash.BlockNumber) if err != nil { - return 0, false, err + return nil, 0, false, err } if blockNumberPtr == nil { isLatestBlock = true @@ -590,25 +592,30 @@ func (b *Backend) getBlockHeight(ctx context.Context, blockNrOrHash rpc.BlockNum } block, err = blockByNumberRespectingWatermarks(ctx, b.tmClient, b.watermarks, blockNumberPtr, 1) if err != nil { - return 0, false, err + return nil, 0, false, err } - return block.Block.Height, isLatestBlock, nil + return block, block.Block.Height, isLatestBlock, nil } -func (b *Backend) getHeader(blockNumber *big.Int) *ethtypes.Header { +func (b *Backend) getHeader(ctx context.Context, blockNumber *big.Int, tmBlock *coretypes.ResultBlock) *ethtypes.Header { zeroExcessBlobGas := uint64(0) baseFee := b.keeper.GetNextBaseFeePerGas(b.ctxProvider(blockNumber.Int64() - 1)).TruncateInt().BigInt() - ctx := b.ctxProvider(blockNumber.Int64()) - if ctx.ChainID() == "pacific-1" && ctx.BlockHeight() < b.keeper.UpgradeKeeper().GetDoneHeight(ctx.WithGasMeter(sdk.NewInfiniteGasMeter(1, 1)), "6.2.0") { + sdkCtx := b.ctxProvider(blockNumber.Int64()) + if sdkCtx.ChainID() == "pacific-1" && sdkCtx.BlockHeight() < b.keeper.UpgradeKeeper().GetDoneHeight(sdkCtx.WithGasMeter(sdk.NewInfiniteGasMeter(1, 1)), "6.2.0") { baseFee = nil } - // Get block results to access consensus parameters number := blockNumber.Int64() - block, blockErr := blockByNumberRespectingWatermarks(context.Background(), b.tmClient, b.watermarks, &number, 1) + var block *coretypes.ResultBlock + var blockErr error + if tmBlock != nil { + block = tmBlock + } else { + block, blockErr = blockByNumberRespectingWatermarks(ctx, b.tmClient, b.watermarks, &number, 1) + } var gasLimit uint64 if blockErr == nil { // Try to get consensus parameters from block results - blockRes, blockResErr := blockResultsWithRetry(context.Background(), b.tmClient, &number) + blockRes, blockResErr := blockResultsWithRetry(ctx, b.tmClient, &number) if blockResErr == nil && blockRes.ConsensusParamUpdates != nil && blockRes.ConsensusParamUpdates.Block != nil { gasLimit = uint64(blockRes.ConsensusParamUpdates.Block.MaxGas) //nolint:gosec } else { diff --git a/evmrpc/simulate_test.go b/evmrpc/simulate_test.go index a00df9b966..ce632c4521 100644 --- a/evmrpc/simulate_test.go +++ b/evmrpc/simulate_test.go @@ -28,18 +28,13 @@ import ( "github.com/stretchr/testify/require" ) -// brFailClient fails BlockResults; bcFailClient fails Block +// brFailClient fails BlockResults type brFailClient struct{ *MockClient } func (br brFailClient) BlockResults(ctx context.Context, h *int64) (*coretypes.ResultBlockResults, error) { return nil, fmt.Errorf("fail br") } -type bcFailClient struct { - *MockClient - first bool -} - func primeReceiptStore(t *testing.T, store receipt.ReceiptStore, latest int64) { t.Helper() if store == nil { @@ -52,11 +47,10 @@ func primeReceiptStore(t *testing.T, store receipt.ReceiptStore, latest int64) { require.NoError(t, store.SetEarliestVersion(1)) } -func (bc *bcFailClient) Block(ctx context.Context, h *int64) (*coretypes.ResultBlock, error) { - if !bc.first { - bc.first = true - return bc.MockClient.Block(ctx, h) - } +// bcAlwaysFailClient fails every Block call (header resolution uses a single block fetch). +type bcAlwaysFailClient struct{ *MockClient } + +func (bc bcAlwaysFailClient) Block(ctx context.Context, h *int64) (*coretypes.ResultBlock, error) { return nil, fmt.Errorf("fail bc") } @@ -451,13 +445,12 @@ func TestGasLimitFallbackToDefault(t *testing.T) { require.NoError(t, err) require.Equal(t, uint64(10_000_000), h1.GasLimit) // DefaultBlockGasLimit - // Case 2: Block fails - bcClient := &bcFailClient{MockClient: &MockClient{}} + // Case 2: Block fails — with one RPC path for the block, resolution errors out entirely. + bcClient := &bcAlwaysFailClient{MockClient: &MockClient{}} watermarks2 := evmrpc.NewWatermarkManager(bcClient, ctxProvider, nil, testApp.EvmKeeper.ReceiptStore()) backend2 := evmrpc.NewBackend(ctxProvider, &testApp.EvmKeeper, legacyabci.BeginBlockKeepers{}, func(int64) client.TxConfig { return TxConfig }, bcClient, cfg, testApp.BaseApp, testApp.TracerAnteHandler, evmrpc.NewBlockCache(3000), &sync.Mutex{}, watermarks2) - h2, err := backend2.HeaderByNumber(context.Background(), 1) - require.NoError(t, err) - require.Equal(t, uint64(10_000_000), h2.GasLimit) // DefaultBlockGasLimit + _, err = backend2.HeaderByNumber(context.Background(), 1) + require.Error(t, err) } func TestSimulationAPIRequestLimiter(t *testing.T) { From 04d0539f9a692569bd57db022edf7d554ccae1ef Mon Sep 17 00:00:00 2001 From: Amir Deris Date: Tue, 7 Apr 2026 17:08:49 -0700 Subject: [PATCH 2/5] replacing other double fetching block instances in evmrpc/simulate --- evmrpc/simulate.go | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/evmrpc/simulate.go b/evmrpc/simulate.go index 1baf28cc7a..1c1fe73e62 100644 --- a/evmrpc/simulate.go +++ b/evmrpc/simulate.go @@ -330,6 +330,21 @@ func (b Backend) BlockByNumber(ctx context.Context, bn rpc.BlockNumber) (*ethtyp if err != nil { return nil, nil, err } + return b.blockFromResultBlock(ctx, tmBlock) +} + +func (b Backend) BlockByHash(ctx context.Context, hash common.Hash) (*ethtypes.Block, []tracersutils.TraceBlockMetadata, error) { + tmBlock, err := blockByHashRespectingWatermarks(ctx, b.tmClient, b.watermarks, hash.Bytes(), 1) + if err != nil { + return nil, nil, err + } + return b.blockFromResultBlock(ctx, tmBlock) +} + +// blockFromResultBlock builds an Ethereum block from an already-fetched Tendermint ResultBlock, +// avoiding a redundant block fetch when the caller already has the block in hand. +func (b Backend) blockFromResultBlock(ctx context.Context, tmBlock *coretypes.ResultBlock) (*ethtypes.Block, []tracersutils.TraceBlockMetadata, error) { + blockNum := tmBlock.Block.Height blockRes, err := b.tmClient.BlockResults(ctx, &tmBlock.Block.Height) if err != nil { return nil, nil, err @@ -397,15 +412,6 @@ func (b Backend) BlockByNumber(ctx context.Context, bn rpc.BlockNumber) (*ethtyp return block, metadata, nil } -func (b Backend) BlockByHash(ctx context.Context, hash common.Hash) (*ethtypes.Block, []tracersutils.TraceBlockMetadata, error) { - tmBlock, err := blockByHashRespectingWatermarks(ctx, b.tmClient, b.watermarks, hash.Bytes(), 1) - if err != nil { - return nil, nil, err - } - blockNumber := rpc.BlockNumber(tmBlock.Block.Height) - return b.BlockByNumber(ctx, blockNumber) -} - func (b *Backend) RPCGasCap() uint64 { return b.config.GasCap } func (b *Backend) RPCEVMTimeout() time.Duration { return b.config.EVMTimeout } @@ -552,7 +558,12 @@ func (b *Backend) GetEVM(_ context.Context, msg *core.Message, stateDB vm.StateD } func (b *Backend) CurrentHeader() *ethtypes.Header { - header := b.getHeader(context.Background(), big.NewInt(b.ctxProvider(LatestCtxHeight).BlockHeight()), nil) + height := b.ctxProvider(LatestCtxHeight).BlockHeight() + // CurrentHeader has no incoming context (ethapi.Backend interface constraint), + // so we use context.Background() and pre-fetch the block here to avoid a + // redundant fetch inside getHeader. + tmBlock, _ := blockByNumberRespectingWatermarks(context.Background(), b.tmClient, b.watermarks, &height, 1) + header := b.getHeader(context.Background(), big.NewInt(height), tmBlock) header.BaseFee = b.keeper.GetNextBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt() return header } @@ -605,15 +616,12 @@ func (b *Backend) getHeader(ctx context.Context, blockNumber *big.Int, tmBlock * baseFee = nil } number := blockNumber.Int64() - var block *coretypes.ResultBlock - var blockErr error - if tmBlock != nil { - block = tmBlock - } else { - block, blockErr = blockByNumberRespectingWatermarks(ctx, b.tmClient, b.watermarks, &number, 1) + block := tmBlock + if block == nil { + block, _ = blockByNumberRespectingWatermarks(ctx, b.tmClient, b.watermarks, &number, 1) } var gasLimit uint64 - if blockErr == nil { + if block != nil { // Try to get consensus parameters from block results blockRes, blockResErr := blockResultsWithRetry(ctx, b.tmClient, &number) if blockResErr == nil && blockRes.ConsensusParamUpdates != nil && blockRes.ConsensusParamUpdates.Block != nil { @@ -636,8 +644,7 @@ func (b *Backend) getHeader(ctx context.Context, blockNumber *big.Int, tmBlock * ExcessBlobGas: &zeroExcessBlobGas, } - //TODO: what should happen if an err occurs here? - if blockErr == nil { + if block != nil { header.ParentHash = common.BytesToHash(block.BlockID.Hash) header.Time = toUint64(block.Block.Time.Unix()) } From 33506c4c5879d4c7b2f1ab2d3e8e5d90afc97324 Mon Sep 17 00:00:00 2001 From: Amir Deris Date: Tue, 7 Apr 2026 20:56:06 -0700 Subject: [PATCH 3/5] Revert "replacing other double fetching block instances in evmrpc/simulate" This reverts commit 04d0539f9a692569bd57db022edf7d554ccae1ef. --- evmrpc/simulate.go | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/evmrpc/simulate.go b/evmrpc/simulate.go index 1c1fe73e62..1baf28cc7a 100644 --- a/evmrpc/simulate.go +++ b/evmrpc/simulate.go @@ -330,21 +330,6 @@ func (b Backend) BlockByNumber(ctx context.Context, bn rpc.BlockNumber) (*ethtyp if err != nil { return nil, nil, err } - return b.blockFromResultBlock(ctx, tmBlock) -} - -func (b Backend) BlockByHash(ctx context.Context, hash common.Hash) (*ethtypes.Block, []tracersutils.TraceBlockMetadata, error) { - tmBlock, err := blockByHashRespectingWatermarks(ctx, b.tmClient, b.watermarks, hash.Bytes(), 1) - if err != nil { - return nil, nil, err - } - return b.blockFromResultBlock(ctx, tmBlock) -} - -// blockFromResultBlock builds an Ethereum block from an already-fetched Tendermint ResultBlock, -// avoiding a redundant block fetch when the caller already has the block in hand. -func (b Backend) blockFromResultBlock(ctx context.Context, tmBlock *coretypes.ResultBlock) (*ethtypes.Block, []tracersutils.TraceBlockMetadata, error) { - blockNum := tmBlock.Block.Height blockRes, err := b.tmClient.BlockResults(ctx, &tmBlock.Block.Height) if err != nil { return nil, nil, err @@ -412,6 +397,15 @@ func (b Backend) blockFromResultBlock(ctx context.Context, tmBlock *coretypes.Re return block, metadata, nil } +func (b Backend) BlockByHash(ctx context.Context, hash common.Hash) (*ethtypes.Block, []tracersutils.TraceBlockMetadata, error) { + tmBlock, err := blockByHashRespectingWatermarks(ctx, b.tmClient, b.watermarks, hash.Bytes(), 1) + if err != nil { + return nil, nil, err + } + blockNumber := rpc.BlockNumber(tmBlock.Block.Height) + return b.BlockByNumber(ctx, blockNumber) +} + func (b *Backend) RPCGasCap() uint64 { return b.config.GasCap } func (b *Backend) RPCEVMTimeout() time.Duration { return b.config.EVMTimeout } @@ -558,12 +552,7 @@ func (b *Backend) GetEVM(_ context.Context, msg *core.Message, stateDB vm.StateD } func (b *Backend) CurrentHeader() *ethtypes.Header { - height := b.ctxProvider(LatestCtxHeight).BlockHeight() - // CurrentHeader has no incoming context (ethapi.Backend interface constraint), - // so we use context.Background() and pre-fetch the block here to avoid a - // redundant fetch inside getHeader. - tmBlock, _ := blockByNumberRespectingWatermarks(context.Background(), b.tmClient, b.watermarks, &height, 1) - header := b.getHeader(context.Background(), big.NewInt(height), tmBlock) + header := b.getHeader(context.Background(), big.NewInt(b.ctxProvider(LatestCtxHeight).BlockHeight()), nil) header.BaseFee = b.keeper.GetNextBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).TruncateInt().BigInt() return header } @@ -616,12 +605,15 @@ func (b *Backend) getHeader(ctx context.Context, blockNumber *big.Int, tmBlock * baseFee = nil } number := blockNumber.Int64() - block := tmBlock - if block == nil { - block, _ = blockByNumberRespectingWatermarks(ctx, b.tmClient, b.watermarks, &number, 1) + var block *coretypes.ResultBlock + var blockErr error + if tmBlock != nil { + block = tmBlock + } else { + block, blockErr = blockByNumberRespectingWatermarks(ctx, b.tmClient, b.watermarks, &number, 1) } var gasLimit uint64 - if block != nil { + if blockErr == nil { // Try to get consensus parameters from block results blockRes, blockResErr := blockResultsWithRetry(ctx, b.tmClient, &number) if blockResErr == nil && blockRes.ConsensusParamUpdates != nil && blockRes.ConsensusParamUpdates.Block != nil { @@ -644,7 +636,8 @@ func (b *Backend) getHeader(ctx context.Context, blockNumber *big.Int, tmBlock * ExcessBlobGas: &zeroExcessBlobGas, } - if block != nil { + //TODO: what should happen if an err occurs here? + if blockErr == nil { header.ParentHash = common.BytesToHash(block.BlockID.Hash) header.Time = toUint64(block.Block.Time.Unix()) } From 5f2c7ea18731076e3ecbc4483142ebd5ea81f84d Mon Sep 17 00:00:00 2001 From: Amir Deris Date: Wed, 8 Apr 2026 09:29:50 -0700 Subject: [PATCH 4/5] added test coverage for new code path --- evmrpc/simulate_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/evmrpc/simulate_test.go b/evmrpc/simulate_test.go index ce632c4521..89bd731bf3 100644 --- a/evmrpc/simulate_test.go +++ b/evmrpc/simulate_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/export" @@ -453,6 +454,46 @@ func TestGasLimitFallbackToDefault(t *testing.T) { require.Error(t, err) } +// Exercises getHeader when tmBlock is nil (CurrentHeader): successful block fetch vs gas-limit +// fallback when Block RPC fails. HeaderByNumber / BlockByNumber already cover the tmBlock != nil path. +func TestSimulateBackendBlockResolutionCoverage(t *testing.T) { + testApp := app.Setup(t, false, false, false) + baseCtx := testApp.GetContextForDeliverTx([]byte{}).WithBlockHeight(1) + ctxProvider := func(h int64) sdk.Context { + if h == evmrpc.LatestCtxHeight { + return baseCtx + } + return baseCtx.WithBlockHeight(h) + } + cfg := &evmrpc.SimulateConfig{GasCap: 10_000_000, EVMTimeout: time.Second} + primeReceiptStore(t, testApp.EvmKeeper.ReceiptStore(), 1) + tmClient := &MockClient{} + watermarks := evmrpc.NewWatermarkManager(tmClient, ctxProvider, nil, testApp.EvmKeeper.ReceiptStore()) + backend := evmrpc.NewBackend(ctxProvider, &testApp.EvmKeeper, + legacyabci.BeginBlockKeepers{}, func(int64) client.TxConfig { return TxConfig }, + tmClient, cfg, testApp.BaseApp, testApp.TracerAnteHandler, evmrpc.NewBlockCache(3000), &sync.Mutex{}, watermarks) + + t.Run("CurrentHeader_fetches_block_when_tmBlock_nil", func(t *testing.T) { + h := backend.CurrentHeader() + require.NotNil(t, h) + require.Equal(t, int64(1), h.Number.Int64()) + require.Equal(t, common.BytesToHash(MockBlockID.Hash), h.ParentHash) + }) + + t.Run("CurrentHeader_fallback_gas_limit_when_block_unavailable", func(t *testing.T) { + bcClient := &bcAlwaysFailClient{MockClient: &MockClient{}} + wm := evmrpc.NewWatermarkManager(bcClient, ctxProvider, nil, testApp.EvmKeeper.ReceiptStore()) + b2 := evmrpc.NewBackend(ctxProvider, &testApp.EvmKeeper, + legacyabci.BeginBlockKeepers{}, func(int64) client.TxConfig { return TxConfig }, + bcClient, cfg, testApp.BaseApp, testApp.TracerAnteHandler, evmrpc.NewBlockCache(3000), &sync.Mutex{}, wm) + h := b2.CurrentHeader() + require.NotNil(t, h) + require.Equal(t, int64(1), h.Number.Int64()) + require.Equal(t, uint64(10_000_000), h.GasLimit) + require.Equal(t, common.Hash{}, h.ParentHash) + }) +} + func TestSimulationAPIRequestLimiter(t *testing.T) { type testEnv struct { From fea1a20efd0b09bf5e7596e3e504f1131ad9a6ac Mon Sep 17 00:00:00 2001 From: Amir Deris Date: Wed, 8 Apr 2026 13:42:08 -0700 Subject: [PATCH 5/5] plt-254 renamed method and used height from the returned block --- evmrpc/simulate.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/evmrpc/simulate.go b/evmrpc/simulate.go index 1baf28cc7a..8da2dd2f1c 100644 --- a/evmrpc/simulate.go +++ b/evmrpc/simulate.go @@ -261,10 +261,11 @@ func NewBackend( } func (b *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (vm.StateDB, *ethtypes.Header, error) { - tmBlock, height, isLatestBlock, err := b.getResultBlockByNumberOrHash(ctx, blockNrOrHash) + tmBlock, isLatestBlock, err := b.getBlockByNumberOrHash(ctx, blockNrOrHash) if err != nil { return nil, nil, err } + height := tmBlock.Block.Height isWasmdCall, ok := ctx.Value(CtxIsWasmdPrecompileCallKey).(bool) sdkCtx := b.ctxProvider(height).WithIsEVM(true).WithEVMEntryViaWasmdPrecompile(ok && isWasmdCall) if !isLatestBlock { @@ -433,10 +434,11 @@ func (b *Backend) Engine() consensus.Engine { } func (b *Backend) HeaderByNumber(ctx context.Context, bn rpc.BlockNumber) (*ethtypes.Header, error) { - tmBlock, height, _, err := b.getResultBlockByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(bn)) + tmBlock, _, err := b.getBlockByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(bn)) if err != nil { return nil, err } + height := tmBlock.Block.Height return b.getHeader(ctx, big.NewInt(height), tmBlock), nil } @@ -561,9 +563,9 @@ func (b *Backend) SuggestGasTipCap(context.Context) (*big.Int, error) { return utils.Big0, nil } -// getResultBlockByNumberOrHash resolves blockNrOrHash to a Tendermint ResultBlock in one RPC path +// getBlockByNumberOrHash resolves blockNrOrHash to a Tendermint ResultBlock in one RPC path // (by hash or by number, including latest). Callers can pass tmBlock to getHeader to avoid a second block fetch. -func (b *Backend) getResultBlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*coretypes.ResultBlock, int64, bool, error) { +func (b *Backend) getBlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*coretypes.ResultBlock, bool, error) { var ( block *coretypes.ResultBlock err error @@ -573,16 +575,16 @@ func (b *Backend) getResultBlockByNumberOrHash(ctx context.Context, blockNrOrHas if blockNrOrHash.BlockHash != nil { block, err = blockByHashRespectingWatermarks(ctx, b.tmClient, b.watermarks, blockNrOrHash.BlockHash[:], 1) if err != nil { - return nil, 0, false, err + return nil, false, err } - return block, block.Block.Height, false, nil + return block, false, nil } var blockNumberPtr *int64 if blockNrOrHash.BlockNumber != nil { blockNumberPtr, err = getBlockNumber(ctx, b.tmClient, *blockNrOrHash.BlockNumber) if err != nil { - return nil, 0, false, err + return nil, false, err } if blockNumberPtr == nil { isLatestBlock = true @@ -592,9 +594,9 @@ func (b *Backend) getResultBlockByNumberOrHash(ctx context.Context, blockNrOrHas } block, err = blockByNumberRespectingWatermarks(ctx, b.tmClient, b.watermarks, blockNumberPtr, 1) if err != nil { - return nil, 0, false, err + return nil, false, err } - return block, block.Block.Height, isLatestBlock, nil + return block, isLatestBlock, nil } func (b *Backend) getHeader(ctx context.Context, blockNumber *big.Int, tmBlock *coretypes.ResultBlock) *ethtypes.Header {