From 61893fe85335e2df38b735d82ac9982ee7e91fa9 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Fri, 14 Jan 2022 21:10:41 +0800 Subject: [PATCH] make trace transaction api work with batch tx Closes: #906 --- rpc/ethereum/namespaces/debug/api.go | 45 ++++++++++++++++++---------- rpc/ethereum/namespaces/eth/api.go | 44 ++++++++------------------- 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/rpc/ethereum/namespaces/debug/api.go b/rpc/ethereum/namespaces/debug/api.go index ad516afefc..89648ea9e6 100644 --- a/rpc/ethereum/namespaces/debug/api.go +++ b/rpc/ethereum/namespaces/debug/api.go @@ -89,6 +89,11 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) ( return nil, err } + msgIndex, _ := rpctypes.FindTxAttributes(transaction.TxResult.Events, hash.Hex()) + if msgIndex < 0 { + return nil, fmt.Errorf("ethereum tx not found in msgs: %s", hash.Hex()) + } + // check tx index is not out of bound if uint32(len(blk.Block.Txs)) < transaction.Index { a.logger.Debug("tx index out of bounds", "index", transaction.Index, "hash", hash.String(), "height", blk.Block.Height) @@ -103,13 +108,14 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) ( a.logger.Debug("failed to decode transaction in block", "height", blk.Block.Height, "error", err.Error()) continue } - msg := tx.GetMsgs()[0] - ethMsg, ok := msg.(*evmtypes.MsgEthereumTx) - if !ok { - continue - } + for _, msg := range tx.GetMsgs() { + ethMsg, ok := msg.(*evmtypes.MsgEthereumTx) + if !ok { + continue + } - predecessors = append(predecessors, ethMsg) + predecessors = append(predecessors, ethMsg) + } } tx, err := a.clientCtx.TxConfig.TxDecoder()(transaction.Tx) @@ -118,7 +124,16 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) ( return nil, err } - ethMessage, ok := tx.GetMsgs()[0].(*evmtypes.MsgEthereumTx) + // add predecessor messages in current cosmos tx + for i := 0; i < msgIndex; i++ { + ethMsg, ok := tx.GetMsgs()[i].(*evmtypes.MsgEthereumTx) + if !ok { + continue + } + predecessors = append(predecessors, ethMsg) + } + + ethMessage, ok := tx.GetMsgs()[msgIndex].(*evmtypes.MsgEthereumTx) if !ok { a.logger.Debug("invalid transaction type", "type", fmt.Sprintf("%T", tx)) return nil, fmt.Errorf("invalid transaction type %T", tx) @@ -218,16 +233,14 @@ func (a *API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConf continue } - messages := decodedTx.GetMsgs() - if len(messages) == 0 { - continue - } - ethMessage, ok := messages[0].(*evmtypes.MsgEthereumTx) - if !ok { - // Just considers Ethereum transactions - continue + for _, msg := range decodedTx.GetMsgs() { + ethMessage, ok := msg.(*evmtypes.MsgEthereumTx) + if !ok { + // Just considers Ethereum transactions + continue + } + txsMessages = append(txsMessages, ethMessage) } - txsMessages = append(txsMessages, ethMessage) } // minus one to get the context at the beginning of the block diff --git a/rpc/ethereum/namespaces/eth/api.go b/rpc/ethereum/namespaces/eth/api.go index 084929f6fd..e02070a9e5 100644 --- a/rpc/ethereum/namespaces/eth/api.go +++ b/rpc/ethereum/namespaces/eth/api.go @@ -691,40 +691,22 @@ func (e *PublicAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransac // getTransactionByBlockAndIndex is the common code shared by `GetTransactionByBlockNumberAndIndex` and `GetTransactionByBlockHashAndIndex`. func (e *PublicAPI) getTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { var msg *evmtypes.MsgEthereumTx - // try /tx_search first - res, err := e.backend.GetTxByTxIndex(block.Block.Height, uint(idx)) - if err == nil { - tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx) - if err != nil { - e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx) - return nil, nil - } - if len(tx.GetMsgs()) != 1 { - e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx) - return nil, nil - } - var ok bool - msg, ok = tx.GetMsgs()[0].(*evmtypes.MsgEthereumTx) - if !ok { - e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx) - return nil, nil - } - } else { - blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, &block.Block.Height) - if err != nil { - return nil, nil - } - - i := int(idx) - ethMsgs := e.backend.GetEthereumMsgsFromTendermintBlock(block, blockRes) - if i >= len(ethMsgs) { - e.logger.Debug("block txs index out of bound", "index", i) - return nil, nil - } + // "/tx_search" don't work with batch tx (multiple messges in one cosmos tx), + // so just iterate through the block and results. + blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, &block.Block.Height) + if err != nil { + return nil, nil + } - msg = ethMsgs[i] + i := int(idx) + ethMsgs := e.backend.GetEthereumMsgsFromTendermintBlock(block, blockRes) + if i >= len(ethMsgs) { + e.logger.Debug("block txs index out of bound", "index", i) + return nil, nil } + msg = ethMsgs[i] + return rpctypes.NewTransactionFromMsg( msg, common.BytesToHash(block.Block.Hash()),