From 8d51a70d6d1c71fd32af74d151965394eecd13d2 Mon Sep 17 00:00:00 2001 From: Calvin Lau <38898718+calvinaco@users.noreply.github.com> Date: Mon, 12 Jul 2021 20:45:13 +0800 Subject: [PATCH] rpc: fix `GetBlockByHash` crash on block not found (#256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix GetBlockByHash crashed on block not found * Add and update log message based on review * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> --- ethereum/rpc/backend/backend.go | 14 ++++++++++++-- tests/rpc/rpc_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ethereum/rpc/backend/backend.go b/ethereum/rpc/backend/backend.go index b8452770..1065057e 100644 --- a/ethereum/rpc/backend/backend.go +++ b/ethereum/rpc/backend/backend.go @@ -112,11 +112,16 @@ func (e *EVMBackend) GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) ( if err != nil { // e.logger.Debugf("GetBlockByNumber safely bumping down from %d to latest", height) if resBlock, err = e.clientCtx.Client.Block(e.ctx, nil); err != nil { - e.logger.Debugln("GetBlockByNumber failed to get latest block") + e.logger.WithError(err).Debugln("GetBlockByNumber failed to get latest block") return nil, nil } } + if resBlock.Block == nil { + e.logger.Debugln("GetBlockByNumber block not found", "height", height) + return nil, nil + } + res, err := e.EthBlockFromTendermint(e.clientCtx, e.queryClient, resBlock.Block, fullTx) if err != nil { e.logger.WithError(err).Debugf("EthBlockFromTendermint failed with block %s", resBlock.Block.String()) @@ -129,10 +134,15 @@ func (e *EVMBackend) GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) ( func (e *EVMBackend) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) { resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes()) if err != nil { - e.logger.Warningf("BlockByHash failed for %s", hash.Hex()) + e.logger.WithError(err).Debugln("BlockByHash block not found", "hash", hash.Hex()) return nil, err } + if resBlock.Block == nil { + e.logger.Debugln("BlockByHash block not found", "hash", hash.Hex()) + return nil, nil + } + return e.EthBlockFromTendermint(e.clientCtx, e.queryClient, resBlock.Block, fullTx) } diff --git a/tests/rpc/rpc_test.go b/tests/rpc/rpc_test.go index 12045672..c4466792 100644 --- a/tests/rpc/rpc_test.go +++ b/tests/rpc/rpc_test.go @@ -799,6 +799,33 @@ func TestEth_ExportAccount_WithStorage(t *testing.T) { require.NotEqual(t, evmtypes.Storage(nil), account.Storage) } +func TestEth_GetBlockByHash(t *testing.T) { + param := []interface{}{"0x1", false} + rpcRes := call(t, "eth_getBlockByNumber", param) + + block := make(map[string]interface{}) + err := json.Unmarshal(rpcRes.Result, &block) + blockHash := block["hash"].(string) + + param = []interface{}{blockHash, false} + rpcRes = call(t, "eth_getBlockByHash", param) + block = make(map[string]interface{}) + err = json.Unmarshal(rpcRes.Result, &block) + require.NoError(t, err) + require.Equal(t, "0x1", block["number"].(string)) +} + +func TestEth_GetBlockByHash_BlockHashNotFound(t *testing.T) { + anyBlockHash := "0xb3b20624f8f0f86eb50dd04688409e5cea4bd02d700bf6e79e9384d47d6a5a35" + param := []interface{}{anyBlockHash, false} + rpcRes := call(t, "eth_getBlockByHash", param) + + var result interface{} + err := json.Unmarshal(rpcRes.Result, &result) + require.NoError(t, err) + require.Nil(t, result) +} + func TestEth_GetBlockByNumber(t *testing.T) { param := []interface{}{"0x1", false} rpcRes := call(t, "eth_getBlockByNumber", param)