Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

make trace transaction api work with batch tx #907

Merged
merged 3 commits into from
Jan 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 29 additions & 18 deletions rpc/ethereum/namespaces/debug/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,27 +89,32 @@ 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)
return nil, fmt.Errorf("transaction not included in block %v", blk.Block.Height)
}

// nolint: prealloc
var predecessors []*evmtypes.MsgEthereumTx
for _, txBz := range blk.Block.Txs[:transaction.Index] {
tx, err := a.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
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)
Expand All @@ -118,7 +123,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)
Expand Down Expand Up @@ -209,7 +223,6 @@ func (a *API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConf

txDecoder := a.clientCtx.TxConfig.TxDecoder()

// nolint: prealloc
var txsMessages []*evmtypes.MsgEthereumTx
for i, tx := range txs {
decodedTx, err := txDecoder(tx)
Expand All @@ -218,16 +231,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
Expand Down
7 changes: 5 additions & 2 deletions rpc/ethereum/namespaces/eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,12 +699,15 @@ func (e *PublicAPI) getTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock,
e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx)
return nil, nil
}
if len(tx.GetMsgs()) != 1 {
// find msg index in events
msgIndex := rpctypes.FindTxAttributesByIndex(res.TxResult.Events, uint64(idx))
if msgIndex < 0 {
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)
// msgIndex is inferred from tx events, should be within bound.
msg, ok = tx.GetMsgs()[msgIndex].(*evmtypes.MsgEthereumTx)
if !ok {
e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx)
return nil, nil
Expand Down
24 changes: 24 additions & 0 deletions rpc/ethereum/types/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,30 @@ func FindTxAttributes(events []abci.Event, txHash string) (int, map[string]strin
return -1, nil
}

// FindTxAttributesByIndex search the msg in tx events by txIndex
// returns the msgIndex, returns -1 if not found.
func FindTxAttributesByIndex(events []abci.Event, txIndex uint64) int {
strIndex := []byte(strconv.FormatUint(txIndex, 10))
msgIndex := -1
for _, event := range events {
if event.Type != evmtypes.EventTypeEthereumTx {
continue
}

msgIndex++

value := FindAttribute(event.Attributes, []byte(evmtypes.AttributeKeyTxIndex))
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
if !bytes.Equal(value, strIndex) {
continue
}

// found, convert attributes to map for later lookup
return msgIndex
}
// not found
return -1
}

// FindAttribute find event attribute with specified key, if not found returns nil.
func FindAttribute(attrs []abci.EventAttribute, key []byte) []byte {
for _, attr := range attrs {
Expand Down