Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: modify rpc methods to include synthetic txs #2282

Merged
merged 29 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4c4b0ca
Add eth tx bytes to events and decode in tracing
skosito May 21, 2024
22ebd86
bump ethermint
skosito May 21, 2024
7e0e446
cleanup and add predecessors handling
skosito May 22, 2024
134036e
cleanup
skosito May 22, 2024
2e275f8
POC for alternative solution to pull tx info from events
skosito May 22, 2024
f6cb6eb
cleanup
skosito May 23, 2024
8f611cb
cleanup
skosito May 23, 2024
51761da
Modify rpc methods to include synthetic txs
skosito May 28, 2024
c0b8891
Add todos
skosito May 28, 2024
5670023
cleanup
skosito May 28, 2024
299fd84
cleanup
skosito May 28, 2024
531052e
changelog
skosito May 28, 2024
7dd8aa6
Merge branch 'develop' into debug-trace-tx-changes
skosito May 28, 2024
9a43e43
comments
skosito May 28, 2024
da06e60
refactor duplicate code
skosito May 28, 2024
85f8bf8
make generate
skosito May 28, 2024
51d22a2
lint fixes
skosito May 28, 2024
51f265a
cleanup
skosito May 28, 2024
e9408a4
link issue to todo
skosito May 28, 2024
367d9b0
Merge branch 'develop' into debug-trace-tx-changes
skosito May 29, 2024
9ff0b69
PR comments
skosito May 29, 2024
a8468e6
Remove todos
skosito May 29, 2024
9be7452
bump ethermint and use new attr constants
skosito May 29, 2024
a765205
Merge branch 'develop' into debug-trace-tx-changes
skosito May 30, 2024
d761ed9
lint
skosito May 30, 2024
89bd917
PR comments
skosito May 30, 2024
02222c3
Merge branch 'develop' into debug-trace-tx-changes
skosito May 31, 2024
2e8600f
bump ethermint
skosito May 31, 2024
f947a6e
more descriptive err message
skosito May 31, 2024
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
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* [2152](https://github.com/zeta-chain/node/pull/2152) - custom priority nonce mempool
* [2113](https://github.com/zeta-chain/node/pull/2113) - add zetaclientd-supervisor process
* [2154](https://github.com/zeta-chain/node/pull/2154) - add `ibccrosschain` module
* [2282](https://github.com/zeta-chain/node/pull/2282) - modify rpc methods to support synthetic txs
* [2258](https://github.com/zeta-chain/node/pull/2258) - add Optimism and Base in static chain information
* [2287](https://github.com/zeta-chain/node/pull/2287) - implement `MsgUpdateChainInfo` message
* [2279](https://github.com/zeta-chain/node/pull/2279) - add a CCTXGateway field to chain static data
Expand Down
13 changes: 6 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ require (
cosmossdk.io/tools/rosetta v0.2.1
github.com/binance-chain/tss-lib v0.0.0-20201118045712-70b2cb4bf916
github.com/btcsuite/btcd/btcutil v1.1.3
github.com/cockroachdb/errors v1.10.0
github.com/cometbft/cometbft v0.37.4
github.com/cometbft/cometbft-db v0.8.0
github.com/golang/mock v1.6.0
github.com/huandu/skiplist v1.2.0
github.com/nanmu42/etherscan-api v1.10.0
github.com/onrik/ethrpc v1.2.0
github.com/tendermint/tendermint v0.34.12
go.nhat.io/grpcmock v0.25.0
)

Expand All @@ -77,7 +79,6 @@ require (
github.com/agl/ed25519 v0.0.0-20200225211852-fd4d107ace12 // indirect
github.com/bool64/shared v0.1.5 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cockroachdb/errors v1.10.0 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
Expand All @@ -95,10 +96,8 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/golang/glog v1.1.2 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/huandu/skiplist v1.2.0 // indirect
github.com/iancoleman/orderedmap v0.3.0 // indirect
github.com/ipfs/boxo v0.10.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
Expand Down Expand Up @@ -216,7 +215,7 @@ require (
github.com/gtank/ristretto255 v0.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.4 // indirect
github.com/hashicorp/go-getter v1.7.4
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
Expand Down Expand Up @@ -321,7 +320,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.17.0
golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb // indirect
golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.19.0
golang.org/x/oauth2 v0.15.0 // indirect
Expand Down Expand Up @@ -354,4 +353,4 @@ replace (

replace github.com/cometbft/cometbft-db => github.com/notional-labs/cometbft-db v0.0.0-20230321185329-6dc7c0ca6345

replace github.com/evmos/ethermint => github.com/zeta-chain/ethermint v0.0.0-20240429123701-35f3f79bf83f
replace github.com/evmos/ethermint => github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94
5 changes: 2 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1639,7 +1639,6 @@ github.com/tendermint/tendermint v0.34.0-rc6/go.mod h1:ugzyZO5foutZImv0Iyx/gOFCX
github.com/tendermint/tendermint v0.34.0/go.mod h1:Aj3PIipBFSNO21r+Lq3TtzQ+uKESxkbA3yo/INM4QwQ=
github.com/tendermint/tendermint v0.34.10/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0=
github.com/tendermint/tendermint v0.34.11/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0=
github.com/tendermint/tendermint v0.34.12 h1:m+kUYNhONedhJfHmHG8lqsdZvbR5t6vmhaok1yXjpKg=
github.com/tendermint/tendermint v0.34.12/go.mod h1:aeHL7alPh4uTBIJQ8mgFEE8VwJLXI1VD3rVOmH2Mcy0=
github.com/tendermint/tm-db v0.6.2/go.mod h1:GYtQ67SUvATOcoY8/+x6ylk8Qo02BQyLrAs+yAcLvGI=
github.com/tendermint/tm-db v0.6.3/go.mod h1:lfA1dL9/Y/Y8wwyPp2NMLyn5P5Ptr/gvDFNWtrCWSf8=
Expand Down Expand Up @@ -1733,8 +1732,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeta-chain/ethermint v0.0.0-20240429123701-35f3f79bf83f h1:joafCsPgohPEn93VCbNXi9IAl6kNvKy8u+kv5amEvUk=
github.com/zeta-chain/ethermint v0.0.0-20240429123701-35f3f79bf83f/go.mod h1:s1zA6OpXv3Tb5I0M6M6j5fo/AssaZL/pgkc7G0W2kN8=
github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94 h1:M54ljayJvy+WlEVdUmX8pgo1nA+XguB3mLhm3wi2z9o=
github.com/zeta-chain/ethermint v0.0.0-20240531172701-61d040058c94/go.mod h1:s1zA6OpXv3Tb5I0M6M6j5fo/AssaZL/pgkc7G0W2kN8=
github.com/zeta-chain/go-tss v0.1.1-0.20240430111318-1785e48eb127 h1:AGQepvsMIVHAHPlplzNcSCyMoGBY1DfO4WHG/QHUSIU=
github.com/zeta-chain/go-tss v0.1.1-0.20240430111318-1785e48eb127/go.mod h1:bVpAoSlRYYCY/R34horVU3cheeHqhSVxygelc++emIU=
github.com/zeta-chain/keystone/keys v0.0.0-20231105174229-903bc9405da2 h1:gd2uE0X+ZbdFJ8DubxNqLbOVlCB12EgWdzSNRAR82tM=
Expand Down
90 changes: 70 additions & 20 deletions rpc/backend/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import (
"math/big"
"strconv"

abci "github.com/cometbft/cometbft/abci/types"
tmrpcclient "github.com/cometbft/cometbft/rpc/client"
tmrpctypes "github.com/cometbft/cometbft/rpc/core/types"
tmtypes "github.com/cometbft/cometbft/types"
sdk "github.com/cosmos/cosmos-sdk/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -272,14 +274,14 @@ func (b *Backend) BlockNumberFromTendermintByHash(blockHash common.Hash) (*big.I
return big.NewInt(resBlock.Block.Height), nil
}

// EthMsgsFromTendermintBlock returns all real MsgEthereumTxs from a
// EthMsgsFromTendermintBlock returns all real and synthetic MsgEthereumTxs from a
// Tendermint block. It also ensures consistency over the correct txs indexes
// across RPC endpoints
func (b *Backend) EthMsgsFromTendermintBlock(
resBlock *tmrpctypes.ResultBlock,
blockRes *tmrpctypes.ResultBlockResults,
) ([]*evmtypes.MsgEthereumTx, []*rpctypes.TxResultAdditionalFields) {
var result []*evmtypes.MsgEthereumTx
var ethMsgs []*evmtypes.MsgEthereumTx
var txsAdditional []*rpctypes.TxResultAdditionalFields
block := resBlock.Block

Expand All @@ -294,30 +296,78 @@ func (b *Backend) EthMsgsFromTendermintBlock(
}

tx, err := b.clientCtx.TxConfig.TxDecoder()(tx)
if err != nil {
// assumption is that if regular ethermint msg is found in tx
// there should not be synthetic one as well
shouldCheckForSyntheticTx := true
// if tx can be decoded, try to find MsgEthereumTx inside
if err == nil {
for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if ok {
shouldCheckForSyntheticTx = false
ethMsg.Hash = ethMsg.AsTransaction().Hash().Hex()
ethMsgs = append(ethMsgs, ethMsg)
txsAdditional = append(txsAdditional, nil)
}
}
} else {
b.logger.Debug("failed to decode transaction in block", "height", block.Height, "error", err.Error())
continue
}
for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
res, additional, err := rpctypes.ParseTxBlockResult(txResults[i], tx, i, block.Height)
if err != nil || additional == nil || res == nil {
continue
}
ethMsg = &evmtypes.MsgEthereumTx{
From: additional.Sender.Hex(),
Hash: additional.Hash.Hex(),
}

// if tx can not be decoded or MsgEthereumTx was not found, try to parse it from block results
if shouldCheckForSyntheticTx {
ethMsg, additional := b.parseSyntheticTxFromBlockResults(txResults, i, tx, block)
if ethMsg != nil {
ethMsgs = append(ethMsgs, ethMsg)
txsAdditional = append(txsAdditional, additional)
} else {
ethMsg.Hash = ethMsg.AsTransaction().Hash().Hex()
txsAdditional = append(txsAdditional, nil)
}
result = append(result, ethMsg)
}
}
return result, txsAdditional
return ethMsgs, txsAdditional
}

func (b *Backend) parseSyntheticTxFromBlockResults(
txResults []*abci.ResponseDeliverTx,
i int,
tx sdk.Tx,
block *tmtypes.Block,
) (*evmtypes.MsgEthereumTx, *rpctypes.TxResultAdditionalFields) {
res, additional, err := rpctypes.ParseTxBlockResult(txResults[i], tx, i, block.Height)
// just skip tx if it can not be parsed, so remaining txs from the block are parsed
if err != nil {
b.logger.Error(err.Error())
return nil, nil
}
if additional == nil || res == nil {
return nil, nil
lumtis marked this conversation as resolved.
Show resolved Hide resolved
}
return b.parseSyntethicTxFromAdditionalFields(additional), additional
}

func (b *Backend) parseSyntethicTxFromAdditionalFields(
additional *rpctypes.TxResultAdditionalFields,
) *evmtypes.MsgEthereumTx {
recipient := additional.Recipient
t := ethtypes.NewTx(&ethtypes.LegacyTx{
Nonce: additional.Nonce,
Data: additional.Data,
Gas: additional.GasUsed,
To: &recipient,
GasPrice: nil,
Value: additional.Value,
V: big.NewInt(0),
R: big.NewInt(0),
S: big.NewInt(0),
})
ethMsg := &evmtypes.MsgEthereumTx{}
err := ethMsg.FromEthereumTx(t)
if err != nil {
b.logger.Error("can not create eth msg", err.Error())
return nil
}
ethMsg.Hash = additional.Hash.Hex()
ethMsg.From = additional.Sender.Hex()
return ethMsg
}

// HeaderByNumber returns the block header identified by height.
Expand Down
89 changes: 15 additions & 74 deletions rpc/backend/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
tmrpctypes "github.com/cometbft/cometbft/rpc/core/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
evmtypes "github.com/evmos/ethermint/x/evm/types"
"github.com/pkg/errors"

Expand Down Expand Up @@ -50,62 +49,28 @@ func (b *Backend) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfi
return nil, err
}

// check tx index is not out of bound
// #nosec G701 txs number in block is always less than MaxUint32
if uint32(len(blk.Block.Txs)) < transaction.TxIndex {
b.logger.Debug(
"tx index out of bounds",
"index",
transaction.TxIndex,
"hash",
hash.String(),
"height",
blk.Block.Height,
)
return nil, fmt.Errorf("transaction not included in block %v", blk.Block.Height)
}

var predecessors []*evmtypes.MsgEthereumTx
for _, txBz := range blk.Block.Txs[:transaction.TxIndex] {
tx, err := b.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
b.logger.Debug("failed to decode transaction in block", "height", blk.Block.Height, "error", err.Error())
continue
}
for _, msg := range tx.GetMsgs() {
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
continue
}

predecessors = append(predecessors, ethMsg)
}
}

tx, err := b.clientCtx.TxConfig.TxDecoder()(blk.Block.Txs[transaction.TxIndex])
blockResult, err := b.TendermintBlockResultByNumber(&blk.Block.Height)
if err != nil {
b.logger.Debug("tx not found", "hash", hash)
return nil, err
return nil, fmt.Errorf("block result not found for height %d", blk.Block.Height)
}

// add predecessor messages in current cosmos tx
// #nosec G701 always in range
for i := 0; i < int(transaction.MsgIndex); i++ {
ethMsg, ok := tx.GetMsgs()[i].(*evmtypes.MsgEthereumTx)
if !ok {
continue
predecessors := []*evmtypes.MsgEthereumTx{}
msgs, _ := b.EthMsgsFromTendermintBlock(blk, blockResult)
var ethMsg *evmtypes.MsgEthereumTx
for _, m := range msgs {
if m.Hash == hash.Hex() {
ethMsg = m
break
}
predecessors = append(predecessors, ethMsg)
predecessors = append(predecessors, m)
}

ethMessage, ok := tx.GetMsgs()[transaction.MsgIndex].(*evmtypes.MsgEthereumTx)
if !ok {
b.logger.Debug("invalid transaction type", "type", fmt.Sprintf("%T", tx))
return nil, fmt.Errorf("invalid transaction type %T", tx)
if ethMsg == nil {
return nil, fmt.Errorf("tx not found in block %d", blk.Block.Height)
}

traceTxRequest := evmtypes.QueryTraceTxRequest{
Msg: ethMessage,
Msg: ethMsg,
Predecessors: predecessors,
BlockNumber: blk.Block.Height,
BlockTime: blk.Block.Time,
Expand Down Expand Up @@ -160,31 +125,7 @@ func (b *Backend) TraceBlock(height rpctypes.BlockNumber,
b.logger.Debug("block result not found", "height", block.Block.Height, "error", err.Error())
return nil, nil
}

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

var txsMessages []*evmtypes.MsgEthereumTx
for i, tx := range txs {
if !rpctypes.TxSuccessOrExceedsBlockGasLimit(blockRes.TxsResults[i]) {
b.logger.Debug("invalid tx result code", "cosmos-hash", hexutil.Encode(tx.Hash()))
continue
}

decodedTx, err := txDecoder(tx)
if err != nil {
b.logger.Error("failed to decode transaction", "hash", txs[i].Hash(), "error", err.Error())
continue
}

for _, msg := range decodedTx.GetMsgs() {
ethMessage, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
// Just considers Ethereum transactions
skosito marked this conversation as resolved.
Show resolved Hide resolved
continue
}
txsMessages = append(txsMessages, ethMessage)
}
}
msgs, _ := b.EthMsgsFromTendermintBlock(block, blockRes)

// minus one to get the context at the beginning of the block
contextHeight := height - 1
Expand All @@ -195,7 +136,7 @@ func (b *Backend) TraceBlock(height rpctypes.BlockNumber,
ctxWithHeight := rpctypes.ContextWithHeight(int64(contextHeight))

traceBlockRequest := &evmtypes.QueryTraceBlockRequest{
Txs: txsMessages,
Txs: msgs,
TraceConfig: config,
BlockNumber: block.Block.Height,
BlockTime: block.Block.Time,
Expand Down
Loading
Loading