From 481e3b82ce3e7f2ffc2259bbbcbdfcbb49587441 Mon Sep 17 00:00:00 2001 From: Calvin Lau <38898718+calvinaco@users.noreply.github.com> Date: Fri, 12 Nov 2021 16:50:38 +0800 Subject: [PATCH] rpc: add `debug_tranceBlockByHash`, fix `debug_traceBlock* ` crash on non-existing block (#743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Problem: Missing debug_tranceBlockByHash RPC method Solution: (Fix #742) Add the missing method * Problem: debug_traceBlockByNumber crashed when block height not found Solution: (Fix #744) Fix memory reference error * Run go fmt * Revert comment on init.sh * Apply suggestions from code review Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update rpc/ethereum/backend/backend.go * Update rpc/ethereum/backend/backend.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> --- CHANGELOG.md | 6 ++++-- init.sh | 2 +- rpc/ethereum/backend/backend.go | 16 ++++++++++++++++ rpc/ethereum/namespaces/debug/api.go | 20 ++++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ee1593a..bd3d8fe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,8 +49,9 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version * (evm) [tharsis#662](https://github.com/tharsis/ethermint/pull/662) Disable basefee for non london blocks * (cmd) [tharsis#712](https://github.com/tharsis/ethermint/pull/712) add tx cli to build evm transaction -* (rpc) [tharsis#733](https://github.com/tharsis/ethermint/pull/733) add JSON_RPC endpoint personal_unpair -* (rpc) [tharsis#740](https://github.com/tharsis/ethermint/pull/740) add JSON_RPC endpoint personal_initializeWallet +* (rpc) [tharsis#733](https://github.com/tharsis/ethermint/pull/733) add JSON_RPC endpoint `personal_unpair` +* (rpc) [tharsis#740](https://github.com/tharsis/ethermint/pull/740) add JSON_RPC endpoint `personal_initializeWallet` +* (rpc) [tharsis#743](https://github.com/tharsis/ethermint/pull/743) add JSON_RPC endpoint `debug_traceBlockByHash` ### Bug Fixes @@ -61,6 +62,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (evm, test) [tharsis#649](https://github.com/tharsis/ethermint/pull/649) Test DynamicFeeTx. * (evm) [tharsis#702](https://github.com/tharsis/ethermint/pull/702) Fix panic in web3 RPC handlers * (rpc) [tharsis#720](https://github.com/tharsis/ethermint/pull/720) Fix `debug_traceTransaction` failure +* (rpc) [tharsis#743](https://github.com/tharsis/ethermint/pull/743) Fix debug JSON RPC handler crash on non-existing block ### Improvements diff --git a/init.sh b/init.sh index 1e91402a..e9a13d1d 100755 --- a/init.sh +++ b/init.sh @@ -25,7 +25,7 @@ ethermintd config chain-id $CHAINID ethermintd keys add $KEY --keyring-backend $KEYRING --algo $KEYALGO # Set moniker and chain-id for Ethermint (Moniker can be anything, chain-id must be an integer) -ethermintd init $MONIKER --chain-id $CHAINID +ethermintd init $MONIKER --chain-id $CHAINID # Change parameter token denominations to aphoton cat $HOME/.ethermintd/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="aphoton"' > $HOME/.ethermintd/config/tmp_genesis.json && mv $HOME/.ethermintd/config/tmp_genesis.json $HOME/.ethermintd/config/genesis.json diff --git a/rpc/ethereum/backend/backend.go b/rpc/ethereum/backend/backend.go index eb57dd61..efa7944e 100644 --- a/rpc/ethereum/backend/backend.go +++ b/rpc/ethereum/backend/backend.go @@ -53,6 +53,7 @@ type Backend interface { // Blockchain API BlockNumber() (hexutil.Uint64, error) GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tmrpctypes.ResultBlock, error) + GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) GetBlockByNumber(blockNum types.BlockNumber, fullTx bool) (map[string]interface{}, error) GetBlockByHash(hash common.Hash, fullTx bool) (map[string]interface{}, error) BlockByNumber(blockNum types.BlockNumber) (*ethtypes.Block, error) @@ -306,6 +307,21 @@ func (e *EVMBackend) GetTendermintBlockByNumber(blockNum types.BlockNumber) (*tm return resBlock, nil } +// GetTendermintBlockByHash returns a Tendermint format block by block number +func (e *EVMBackend) GetTendermintBlockByHash(blockHash common.Hash) (*tmrpctypes.ResultBlock, error) { + resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, blockHash.Bytes()) + if err != nil { + e.logger.Debug("tendermint client failed to get block", "blockHash", blockHash.Hex(), "error", err.Error()) + } + + if resBlock == nil || resBlock.Block == nil { + e.logger.Debug("GetBlockByNumber block not found", "blockHash", blockHash.Hex()) + return nil, nil + } + + return resBlock, nil +} + // BlockBloom query block bloom filter from block results func (e *EVMBackend) BlockBloom(height *int64) (ethtypes.Bloom, error) { result, err := e.clientCtx.Client.BlockResults(e.ctx, height) diff --git a/rpc/ethereum/namespaces/debug/api.go b/rpc/ethereum/namespaces/debug/api.go index 49933ddb..f590c109 100644 --- a/rpc/ethereum/namespaces/debug/api.go +++ b/rpc/ethereum/namespaces/debug/api.go @@ -167,12 +167,32 @@ func (a *API) TraceBlockByNumber(height rpctypes.BlockNumber, config *evmtypes.T // Get Tendermint Block resBlock, err := a.backend.GetTendermintBlockByNumber(height) if err != nil { + a.logger.Debug("get block failed", "height", height, "error", err.Error()) return nil, err } return a.traceBlock(height, config, resBlock) } +// TraceBlockByHash returns the structured logs created during the execution of +// EVM and returns them as a JSON object. +func (a *API) TraceBlockByHash(hash common.Hash, config *evmtypes.TraceConfig) ([]*evmtypes.TxTraceResult, error) { + a.logger.Debug("debug_traceBlockByHash", "hash", hash) + // Get Tendermint Block + resBlock, err := a.backend.GetTendermintBlockByHash(hash) + if err != nil { + a.logger.Debug("get block failed", "hash", hash.Hex(), "error", err.Error()) + return nil, err + } + + if resBlock == nil || resBlock.Block == nil { + a.logger.Debug("block not found", "hash", hash.Hex()) + return nil, errors.New("block not found") + } + + return a.traceBlock(rpctypes.BlockNumber(resBlock.Block.Height), config, resBlock) +} + // traceBlock configures a new tracer according to the provided configuration, and // executes all the transactions contained within. The return value will be one item // per transaction, dependent on the requested tracer.