forked from cerc-io/laconicd-deprecated
rpc: make trace transaction api work with batch tx (#907)
* make trace transaction api work with batch tx Closes: #906 fix linter * review suggestion Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
0b92af406a
commit
351e6d6eb3
@ -89,13 +89,17 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (
|
|||||||
return nil, err
|
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
|
// check tx index is not out of bound
|
||||||
if uint32(len(blk.Block.Txs)) < transaction.Index {
|
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)
|
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)
|
return nil, fmt.Errorf("transaction not included in block %v", blk.Block.Height)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: prealloc
|
|
||||||
var predecessors []*evmtypes.MsgEthereumTx
|
var predecessors []*evmtypes.MsgEthereumTx
|
||||||
for _, txBz := range blk.Block.Txs[:transaction.Index] {
|
for _, txBz := range blk.Block.Txs[:transaction.Index] {
|
||||||
tx, err := a.clientCtx.TxConfig.TxDecoder()(txBz)
|
tx, err := a.clientCtx.TxConfig.TxDecoder()(txBz)
|
||||||
@ -103,7 +107,7 @@ 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())
|
a.logger.Debug("failed to decode transaction in block", "height", blk.Block.Height, "error", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
msg := tx.GetMsgs()[0]
|
for _, msg := range tx.GetMsgs() {
|
||||||
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
@ -111,6 +115,7 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (
|
|||||||
|
|
||||||
predecessors = append(predecessors, ethMsg)
|
predecessors = append(predecessors, ethMsg)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tx, err := a.clientCtx.TxConfig.TxDecoder()(transaction.Tx)
|
tx, err := a.clientCtx.TxConfig.TxDecoder()(transaction.Tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -118,7 +123,16 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (
|
|||||||
return nil, err
|
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 {
|
if !ok {
|
||||||
a.logger.Debug("invalid transaction type", "type", fmt.Sprintf("%T", tx))
|
a.logger.Debug("invalid transaction type", "type", fmt.Sprintf("%T", tx))
|
||||||
return nil, fmt.Errorf("invalid transaction type %T", tx)
|
return nil, fmt.Errorf("invalid transaction type %T", tx)
|
||||||
@ -209,7 +223,6 @@ func (a *API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConf
|
|||||||
|
|
||||||
txDecoder := a.clientCtx.TxConfig.TxDecoder()
|
txDecoder := a.clientCtx.TxConfig.TxDecoder()
|
||||||
|
|
||||||
// nolint: prealloc
|
|
||||||
var txsMessages []*evmtypes.MsgEthereumTx
|
var txsMessages []*evmtypes.MsgEthereumTx
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
decodedTx, err := txDecoder(tx)
|
decodedTx, err := txDecoder(tx)
|
||||||
@ -218,17 +231,15 @@ func (a *API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConf
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
messages := decodedTx.GetMsgs()
|
for _, msg := range decodedTx.GetMsgs() {
|
||||||
if len(messages) == 0 {
|
ethMessage, ok := msg.(*evmtypes.MsgEthereumTx)
|
||||||
continue
|
|
||||||
}
|
|
||||||
ethMessage, ok := messages[0].(*evmtypes.MsgEthereumTx)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
// Just considers Ethereum transactions
|
// Just considers Ethereum transactions
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
txsMessages = append(txsMessages, ethMessage)
|
txsMessages = append(txsMessages, ethMessage)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// minus one to get the context at the beginning of the block
|
// minus one to get the context at the beginning of the block
|
||||||
contextHeight := height - 1
|
contextHeight := height - 1
|
||||||
|
@ -699,12 +699,15 @@ func (e *PublicAPI) getTransactionByBlockAndIndex(block *tmrpctypes.ResultBlock,
|
|||||||
e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx)
|
e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx)
|
||||||
return nil, nil
|
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)
|
e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
var ok bool
|
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 {
|
if !ok {
|
||||||
e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx)
|
e.logger.Debug("invalid ethereum tx", "height", block.Block.Header, "index", idx)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -282,6 +282,31 @@ func FindTxAttributes(events []abci.Event, txHash string) (int, map[string]strin
|
|||||||
return -1, nil
|
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))
|
||||||
|
txIndexKey := []byte(evmtypes.AttributeKeyTxIndex)
|
||||||
|
msgIndex := -1
|
||||||
|
for _, event := range events {
|
||||||
|
if event.Type != evmtypes.EventTypeEthereumTx {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
msgIndex++
|
||||||
|
|
||||||
|
value := FindAttribute(event.Attributes, txIndexKey)
|
||||||
|
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.
|
// FindAttribute find event attribute with specified key, if not found returns nil.
|
||||||
func FindAttribute(attrs []abci.EventAttribute, key []byte) []byte {
|
func FindAttribute(attrs []abci.EventAttribute, key []byte) []byte {
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
|
Loading…
Reference in New Issue
Block a user