Skip to content

Commit

Permalink
Merge branch 'develop' into cctx-validate-outbound
Browse files Browse the repository at this point in the history
  • Loading branch information
skosito authored Jun 19, 2024
2 parents a923566 + f5a7aae commit 3a7cf12
Show file tree
Hide file tree
Showing 10 changed files with 351 additions and 39 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
* [2266](https://github.com/zeta-chain/node/pull/2266) - try fixing E2E test `crosschain_swap` failure `btc transaction not signed`
* [2294](https://github.com/zeta-chain/node/pull/2294) - add and fix existing ethermint rpc unit test
* [2329](https://github.com/zeta-chain/node/pull/2329) - fix TODOs in rpc unit tests
* [2342](https://github.com/zeta-chain/node/pull/2342) - extend rpc unit tests with testing extension to include synthetic ethereum txs
* [2299](https://github.com/zeta-chain/node/pull/2299) - add `zetae2e` command to deploy test contracts

### Fixes
Expand Down
53 changes: 53 additions & 0 deletions rpc/backend/backend_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
tmrpctypes "github.com/cometbft/cometbft/rpc/core/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
Expand Down Expand Up @@ -35,6 +36,30 @@ type BackendTestSuite struct {
signer keyring.Signer
}

// testTx is a dummy implementation of cosmos Tx used for testing.
type testTx struct {
}

func (tx testTx) GetMsgs() []sdk.Msg { return nil }
func (tx testTx) GetSigners() []sdk.AccAddress { return nil }

func (tx testTx) ValidateBasic() error { return nil }
func (t testTx) ProtoMessage() { panic("not implemented") }
func (t testTx) Reset() { panic("not implemented") }

func (t testTx) String() string { panic("not implemented") }

func (t testTx) Bytes() []byte { panic("not implemented") }

func (t testTx) VerifySignature(msg []byte, sig []byte) bool { panic("not implemented") }

func (t testTx) Type() string { panic("not implemented") }

var (
_ sdk.Tx = (*testTx)(nil)
_ sdk.Msg = (*testTx)(nil)
)

func TestBackendTestSuite(t *testing.T) {
suite.Run(t, new(BackendTestSuite))
}
Expand Down Expand Up @@ -118,6 +143,34 @@ func (suite *BackendTestSuite) buildEthereumTx() (*evmtypes.MsgEthereumTx, []byt
return msgEthereumTx, bz
}

func (suite *BackendTestSuite) buildSyntheticTxResult(txHash string) ([]byte, abci.ResponseDeliverTx) {
testTx := &testTx{}
txBuilder := suite.backend.clientCtx.TxConfig.NewTxBuilder()
txBuilder.SetSignatures()
txBuilder.SetMsgs(testTx)
bz, _ := suite.backend.clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
return bz, abci.ResponseDeliverTx{
Code: 0,
Events: []abci.Event{
{Type: evmtypes.EventTypeEthereumTx, Attributes: []abci.EventAttribute{
{Key: "ethereumTxHash", Value: txHash},
{Key: "txIndex", Value: "8888"},
{Key: "amount", Value: "1000"},
{Key: "txGasUsed", Value: "21000"},
{Key: "txHash", Value: ""},
{Key: "recipient", Value: "0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7"},
}},
{
Type: "message", Attributes: []abci.EventAttribute{
{Key: "sender", Value: "0x735b14BB79463307AAcBED86DAf3322B1e6226aB"},
{Key: "txType", Value: "88"},
{Key: "txNonce", Value: "1"},
},
},
},
}
}

// buildFormattedBlock returns a formatted block for testing
func (suite *BackendTestSuite) buildFormattedBlock(
blockRes *tmrpctypes.ResultBlockResults,
Expand Down
119 changes: 113 additions & 6 deletions rpc/backend/blocks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

sdkmath "cosmossdk.io/math"
"github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/bytes"
tmrpctypes "github.com/cometbft/cometbft/rpc/core/types"
tmtypes "github.com/cometbft/cometbft/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -19,6 +20,7 @@ import (

"github.com/zeta-chain/zetacore/rpc/backend/mocks"
ethrpc "github.com/zeta-chain/zetacore/rpc/types"
"github.com/zeta-chain/zetacore/testutil/sample"
)

func (suite *BackendTestSuite) TestBlockNumber() {
Expand Down Expand Up @@ -140,7 +142,7 @@ func (suite *BackendTestSuite) TestGetBlockByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int, validator sdk.AccAddress, txBz []byte) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
resBlock, _ = RegisterBlock(client, height, txBz)
resBlock, _ = RegisterBlock(client, height, []tmtypes.Tx{txBz})
RegisterBlockResultsError(client, blockNum.Int64())
},
true,
Expand All @@ -157,7 +159,7 @@ func (suite *BackendTestSuite) TestGetBlockByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int, validator sdk.AccAddress, txBz []byte) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
resBlock, _ = RegisterBlock(client, height, txBz)
resBlock, _ = RegisterBlock(client, height, []tmtypes.Tx{txBz})
blockRes, _ = RegisterBlockResults(client, blockNum.Int64())
RegisterConsensusParams(client, height)

Expand All @@ -179,7 +181,7 @@ func (suite *BackendTestSuite) TestGetBlockByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int, validator sdk.AccAddress, txBz []byte) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
resBlock, _ = RegisterBlock(client, height, txBz)
resBlock, _ = RegisterBlock(client, height, []tmtypes.Tx{txBz})
blockRes, _ = RegisterBlockResults(client, blockNum.Int64())
RegisterConsensusParams(client, height)

Expand Down Expand Up @@ -497,7 +499,7 @@ func (suite *BackendTestSuite) TestGetBlockTransactionCountByNumber() {
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, bz)
RegisterBlock(client, height, []tmtypes.Tx{bz})
RegisterBlockResults(client, height)
},
hexutil.Uint(1),
Expand Down Expand Up @@ -1268,7 +1270,7 @@ func (suite *BackendTestSuite) TestHeaderByNumber() {
func(blockNum ethrpc.BlockNumber, baseFee sdkmath.Int) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
expResultBlock, _ = RegisterBlock(client, height, bz)
expResultBlock, _ = RegisterBlock(client, height, []tmtypes.Tx{bz})
RegisterBlockResults(client, height)

queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
Expand Down Expand Up @@ -1471,7 +1473,7 @@ func (suite *BackendTestSuite) TestEthBlockByNumber() {
func(blockNum ethrpc.BlockNumber) {
height := blockNum.Int64()
client := suite.backend.clientCtx.Client.(*mocks.Client)
RegisterBlock(client, height, bz)
RegisterBlock(client, height, []tmtypes.Tx{bz})

RegisterBlockResults(client, blockNum.Int64())
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
Expand Down Expand Up @@ -1613,3 +1615,108 @@ func (suite *BackendTestSuite) TestEthBlockFromTendermintBlock() {
})
}
}

func (suite *BackendTestSuite) TestEthAndSyntheticMsgsFromTendermintBlock() {
// synthetic tx
hash := sample.Hash().Hex()
tx, txRes := suite.buildSyntheticTxResult(hash)

// real tx
msgEthereumTx, _ := suite.buildEthereumTx()
realTx := suite.signAndEncodeEthTx(msgEthereumTx)

suite.backend.indexer = nil
// block contains block real and synthetic tx
emptyBlock := tmtypes.MakeBlock(1, []tmtypes.Tx{realTx, tx}, nil, nil)
emptyBlock.ChainID = ChainID
blockHash := common.BigToHash(big.NewInt(1)).Bytes()
resBlock := &tmrpctypes.ResultBlock{Block: emptyBlock, BlockID: tmtypes.BlockID{Hash: bytes.HexBytes(blockHash)}}
blockRes := &tmrpctypes.ResultBlockResults{
Height: 1,
TxsResults: []*types.ResponseDeliverTx{{}, &txRes},
}

// both real and synthetic should be returned
msgs, additionals := suite.backend.EthMsgsFromTendermintBlock(resBlock, blockRes)
suite.Require().Equal(2, len(msgs))
suite.Require().Equal(2, len(additionals))

suite.Require().Nil(additionals[0])
suite.Require().NotNil(additionals[1])

suite.Require().Equal(msgEthereumTx.Hash, msgs[0].Hash)
suite.Require().Equal(hash, msgs[1].Hash)
}

func (suite *BackendTestSuite) TestEthAndSyntheticEthBlockByNumber() {
// synthetic tx
hash := sample.Hash().Hex()
tx, txRes := suite.buildSyntheticTxResult(hash)

// real tx
msgEthereumTx, _ := suite.buildEthereumTx()
realTx := suite.signAndEncodeEthTx(msgEthereumTx)

suite.backend.indexer = nil
client := suite.backend.clientCtx.Client.(*mocks.Client)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
// block contains block real and synthetic tx
RegisterBlock(client, 1, []tmtypes.Tx{realTx, tx})
RegisterBlockResultsWithTxResults(client, 1, []*types.ResponseDeliverTx{{}, &txRes})
RegisterBaseFee(queryClient, sdk.NewInt(1))

// only real should be returned
block, err := suite.backend.EthBlockByNumber(1)
suite.Require().NoError(err)
suite.Require().Equal(1, len(block.Transactions()))
suite.Require().Equal(msgEthereumTx.Hash, block.Transactions()[0].Hash().String())
}

func (suite *BackendTestSuite) TestEthAndSyntheticGetBlockByNumber() {
// synthetic tx
hash := sample.Hash().Hex()
tx, txRes := suite.buildSyntheticTxResult(hash)

// real tx
msgEthereumTx, _ := suite.buildEthereumTx()
realTx := suite.signAndEncodeEthTx(msgEthereumTx)

suite.backend.indexer = nil
client := suite.backend.clientCtx.Client.(*mocks.Client)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
// block contains block real and synthetic tx
RegisterBlock(client, 1, []tmtypes.Tx{realTx, tx})
RegisterBlockResultsWithTxResults(client, 1, []*types.ResponseDeliverTx{{}, &txRes})
RegisterBaseFee(queryClient, sdk.NewInt(1))
RegisterValidatorAccount(queryClient, sdk.AccAddress(common.Address{}.Bytes()))
RegisterConsensusParams(client, 1)

// both real and synthetic should be returned
block, err := suite.backend.GetBlockByNumber(1, false)
suite.Require().NoError(err)

transactions := block["transactions"].([]interface{})
suite.Require().Equal(2, len(transactions))
suite.Require().Equal(common.HexToHash(msgEthereumTx.Hash), transactions[0])
suite.Require().Equal(common.HexToHash(hash), transactions[1])

// both real and synthetic should be returned
block, err = suite.backend.GetBlockByNumber(1, true)
suite.Require().NoError(err)

transactions = block["transactions"].([]interface{})
suite.Require().Equal(2, len(transactions))
resRealTx := transactions[0].(*ethrpc.RPCTransaction)
suite.Require().Equal(common.HexToHash(msgEthereumTx.Hash), resRealTx.Hash)
resSyntheticTx := transactions[1].(*ethrpc.RPCTransaction)
suite.Require().Equal(common.HexToHash(hash), resSyntheticTx.Hash)

suite.Require().Equal(hash, resSyntheticTx.Hash.Hex())
suite.Require().Equal("0x735b14BB79463307AAcBED86DAf3322B1e6226aB", resSyntheticTx.From.Hex())
suite.Require().Equal("0x775b87ef5D82ca211811C1a02CE0fE0CA3a455d7", resSyntheticTx.To.Hex())
suite.Require().Equal("0x58", resSyntheticTx.Type.String())
suite.Require().Equal("0x1", resSyntheticTx.Nonce.String())
suite.Require().Nil(resSyntheticTx.V)
suite.Require().Nil(resSyntheticTx.R)
suite.Require().Nil(resSyntheticTx.S)
}
5 changes: 3 additions & 2 deletions rpc/backend/call_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"math/big"

tmtypes "github.com/cometbft/cometbft/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -400,7 +401,7 @@ func (suite *BackendTestSuite) TestDoCall() {
func() {
client := suite.backend.clientCtx.Client.(*mocks.Client)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterBlock(client, 1, bz)
RegisterBlock(client, 1, []tmtypes.Tx{bz})
RegisterEthCallError(
queryClient,
&evmtypes.EthCallRequest{Args: argsBz, ChainId: suite.backend.chainID.Int64()},
Expand All @@ -416,7 +417,7 @@ func (suite *BackendTestSuite) TestDoCall() {
func() {
client := suite.backend.clientCtx.Client.(*mocks.Client)
queryClient := suite.backend.queryClient.QueryClient.(*mocks.EVMQueryClient)
RegisterBlock(client, 1, bz)
RegisterBlock(client, 1, []tmtypes.Tx{bz})
RegisterEthCall(
queryClient,
&evmtypes.EthCallRequest{Args: argsBz, ChainId: suite.backend.chainID.Int64()},
Expand Down
34 changes: 16 additions & 18 deletions rpc/backend/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package backend

import (
"context"
"math/big"
"testing"

abci "github.com/cometbft/cometbft/abci/types"
Expand Down Expand Up @@ -38,6 +39,12 @@ func RegisterTxSearch(client *mocks.Client, query string, txBz []byte) {
Return(&tmrpctypes.ResultTxSearch{Txs: resulTxs, TotalCount: 1}, nil)
}

func RegisterTxSearchWithTxResult(client *mocks.Client, query string, txBz []byte, res abci.ResponseDeliverTx) {
resulTxs := []*tmrpctypes.ResultTx{{Tx: txBz, Height: 1, TxResult: res}}
client.On("TxSearch", rpc.ContextWithHeight(1), query, false, (*int)(nil), (*int)(nil), "").
Return(&tmrpctypes.ResultTxSearch{Txs: resulTxs, TotalCount: 1}, nil)
}

func RegisterTxSearchEmpty(client *mocks.Client, query string) {
client.On("TxSearch", rpc.ContextWithHeight(1), query, false, (*int)(nil), (*int)(nil), "").
Return(&tmrpctypes.ResultTxSearch{}, nil)
Expand Down Expand Up @@ -94,36 +101,26 @@ func RegisterStatusError(client *mocks.Client) {
}

// Block
func RegisterBlockMultipleTxs(
client *mocks.Client,
height int64,
txs []types.Tx,
) (*tmrpctypes.ResultBlock, error) {
block := types.MakeBlock(height, txs, nil, nil)
block.ChainID = ChainID
resBlock := &tmrpctypes.ResultBlock{Block: block}
client.On("Block", rpc.ContextWithHeight(height), mock.AnythingOfType("*int64")).Return(resBlock, nil)
return resBlock, nil
}

func RegisterBlock(
client *mocks.Client,
height int64,
tx []byte,
txs []types.Tx,
) (*tmrpctypes.ResultBlock, error) {
// without tx
if tx == nil {
if len(txs) == 0 {
emptyBlock := types.MakeBlock(height, []types.Tx{}, nil, nil)
emptyBlock.ChainID = ChainID
resBlock := &tmrpctypes.ResultBlock{Block: emptyBlock}
blockHash := common.BigToHash(big.NewInt(height)).Bytes()
resBlock := &tmrpctypes.ResultBlock{Block: emptyBlock, BlockID: types.BlockID{Hash: bytes.HexBytes(blockHash)}}
client.On("Block", rpc.ContextWithHeight(height), mock.AnythingOfType("*int64")).Return(resBlock, nil)
return resBlock, nil
}

// with tx
block := types.MakeBlock(height, []types.Tx{tx}, nil, nil)
block := types.MakeBlock(height, txs, nil, nil)
block.ChainID = ChainID
resBlock := &tmrpctypes.ResultBlock{Block: block}
blockHash := common.BigToHash(big.NewInt(height)).Bytes()
resBlock := &tmrpctypes.ResultBlock{Block: block, BlockID: types.BlockID{Hash: bytes.HexBytes(blockHash)}}
client.On("Block", rpc.ContextWithHeight(height), mock.AnythingOfType("*int64")).Return(resBlock, nil)
return resBlock, nil
}
Expand Down Expand Up @@ -154,7 +151,8 @@ func TestRegisterBlock(t *testing.T) {

emptyBlock := types.MakeBlock(height, []types.Tx{}, nil, nil)
emptyBlock.ChainID = ChainID
resBlock := &tmrpctypes.ResultBlock{Block: emptyBlock}
blockHash := common.BigToHash(big.NewInt(height)).Bytes()
resBlock := &tmrpctypes.ResultBlock{Block: emptyBlock, BlockID: types.BlockID{Hash: blockHash}}
require.Equal(t, resBlock, res)
require.NoError(t, err)
}
Expand Down
15 changes: 12 additions & 3 deletions rpc/backend/evm_query_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,23 @@ func RegisterTraceTransactionWithPredecessors(
predecessors []*evmtypes.MsgEthereumTx,
) {
data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d}
queryClient.On("TraceTx", rpc.ContextWithHeight(1),
&evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, Predecessors: predecessors, ChainId: 7001}).
queryClient.On(
"TraceTx",
rpc.ContextWithHeight(1),
&evmtypes.QueryTraceTxRequest{
Msg: msgEthTx,
BlockHash: "0000000000000000000000000000000000000000000000000000000000000001",
BlockNumber: 1,
Predecessors: predecessors,
ChainId: 7001,
},
).
Return(&evmtypes.QueryTraceTxResponse{Data: data}, nil)
}

func RegisterTraceTransaction(queryClient *mocks.EVMQueryClient, msgEthTx *evmtypes.MsgEthereumTx) {
data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d}
queryClient.On("TraceTx", rpc.ContextWithHeight(1), &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, Predecessors: []*evmtypes.MsgEthereumTx{}, ChainId: 7001}).
queryClient.On("TraceTx", rpc.ContextWithHeight(1), &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockHash: "0000000000000000000000000000000000000000000000000000000000000001", BlockNumber: 1, Predecessors: []*evmtypes.MsgEthereumTx{}, ChainId: 7001}).
Return(&evmtypes.QueryTraceTxResponse{Data: data}, nil)
}

Expand Down
Loading

0 comments on commit 3a7cf12

Please sign in to comment.