From 90538ee1e728d9e55e79a2a9e424ec3d4be18e4e Mon Sep 17 00:00:00 2001 From: lumtis Date: Mon, 8 Apr 2024 11:04:55 +0200 Subject: [PATCH] addInTx tests --- testutil/keeper/crosschain.go | 7 + .../keeper/msg_server_add_to_intx_tracker.go | 271 +------------- .../msg_server_add_to_intx_tracker_test.go | 307 +++++++++++----- x/lightclient/keeper/block_header_test.go | 340 ++++++++++++++++++ 4 files changed, 560 insertions(+), 365 deletions(-) diff --git a/testutil/keeper/crosschain.go b/testutil/keeper/crosschain.go index dc3aabcea1..34e81177a1 100644 --- a/testutil/keeper/crosschain.go +++ b/testutil/keeper/crosschain.go @@ -165,6 +165,13 @@ func CrosschainKeeper(t testing.TB) (*keeper.Keeper, sdk.Context, SDKKeepers, Ze return CrosschainKeeperWithMocks(t, CrosschainNoMocks) } +// GetCrosschainLightclientMock returns a new crosschain lightclient keeper mock +func GetCrosschainLightclientMock(t testing.TB, keeper *keeper.Keeper) *crosschainmocks.CrosschainLightclientKeeper { + lk, ok := keeper.GetLightclientKeeper().(*crosschainmocks.CrosschainLightclientKeeper) + require.True(t, ok) + return lk +} + // GetCrosschainAuthorityMock returns a new crosschain authority keeper mock func GetCrosschainAuthorityMock(t testing.TB, keeper *keeper.Keeper) *crosschainmocks.CrosschainAuthorityKeeper { cok, ok := keeper.GetAuthorityKeeper().(*crosschainmocks.CrosschainAuthorityKeeper) diff --git a/x/crosschain/keeper/msg_server_add_to_intx_tracker.go b/x/crosschain/keeper/msg_server_add_to_intx_tracker.go index 0117665ef6..ef6e9a5494 100644 --- a/x/crosschain/keeper/msg_server_add_to_intx_tracker.go +++ b/x/crosschain/keeper/msg_server_add_to_intx_tracker.go @@ -14,7 +14,7 @@ import ( // AddToInTxTracker adds a new record to the inbound transaction tracker. func (k msgServer) AddToInTxTracker(goCtx context.Context, msg *types.MsgAddToInTxTracker) (*types.MsgAddToInTxTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ChainId) + chain := k.GetObserverKeeper().GetSupportedChainFromChainID(ctx, msg.ChainId) if chain == nil { return nil, observertypes.ErrSupportedChains } @@ -74,272 +74,3 @@ func verifyProofAndInTxBody(ctx sdk.Context, k msgServer, msg *types.MsgAddToInT return nil } - -// TODO: Implement tests for verifyOutTxBodyBTC -// https://github.com/zeta-chain/node/issues/1994 - -//func TestKeeper_VerifyEVMInTxBody(t *testing.T) { -//to := sample.EthAddress() -//tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ -// ChainID: big.NewInt(5), -// Nonce: 1, -// GasTipCap: nil, -// GasFeeCap: nil, -// Gas: 21000, -// To: &to, -// Value: big.NewInt(5), -// Data: nil, -//}) -// -//t.Run("should error if msg tx hash not correct", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: "0x0", -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) - -//t.Run("should error if msg chain id not correct", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: 1, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should error if not supported coin type", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Cmd, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should error for cointype_zeta if chain params not found", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{}, false) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Zeta, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should error for cointype_zeta if tx.to wrong", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ -// ConnectorContractAddress: sample.EthAddress().Hex(), -// }, true) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Zeta, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should not error for cointype_zeta", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ -// ConnectorContractAddress: to.Hex(), -// }, true) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Zeta, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.NoError(t, err) -//}) -// -//t.Run("should error for cointype_erc20 if chain params not found", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{}, false) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_ERC20, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should error for cointype_erc20 if tx.to wrong", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ -// Erc20CustodyContractAddress: sample.EthAddress().Hex(), -// }, true) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_ERC20, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should not error for cointype_erc20", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ -// Erc20CustodyContractAddress: to.Hex(), -// }, true) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_ERC20, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.NoError(t, err) -//}) -// -//t.Run("should error for cointype_gas if tss address not found", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{}, errors.New("err")) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Gas, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should error for cointype_gas if tss eth address is empty", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ -// Eth: "0x", -// }, nil) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Gas, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should error for cointype_gas if tss eth address is wrong", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ -// Eth: sample.EthAddress().Hex(), -// }, nil) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Gas, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.Error(t, err) -//}) -// -//t.Run("should not error for cointype_gas", func(t *testing.T) { -// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ -// UseObserverMock: true, -// }) -// observerMock := keepertest.GetCrosschainObserverMock(t, k) -// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ -// Eth: to.Hex(), -// }, nil) -// -// txBytes, err := tx.MarshalBinary() -// require.NoError(t, err) -// msg := &types.MsgAddToInTxTracker{ -// TxHash: tx.Hash().Hex(), -// ChainId: tx.ChainId().Int64(), -// CoinType: coin.CoinType_Gas, -// } -// -// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) -// require.NoError(t, err) -//}) -//} diff --git a/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go b/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go index 8150485725..51286bcee5 100644 --- a/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go +++ b/x/crosschain/keeper/msg_server_add_to_intx_tracker_test.go @@ -1,6 +1,9 @@ package keeper_test import ( + "errors" + "github.com/stretchr/testify/mock" + "github.com/zeta-chain/zetacore/pkg/chains" "testing" sdk "github.com/cosmos/cosmos-sdk/types" @@ -46,47 +49,47 @@ func setupVerificationParams(zk keepertest.ZetaKeepers, ctx sdk.Context, tx_inde func TestMsgServer_AddToInTxTracker(t *testing.T) { t.Run("fail normal user submit without proof", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) - tx_hash := "string" + msgServer := keeper.NewMsgServerImpl(*k) + + txHash := "string" chainID := getValidEthChainID(t) setSupportedChain(ctx, zk, chainID) - msgServer := keeper.NewMsgServerImpl(*k) - _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ Creator: sample.AccAddress(), ChainId: chainID, - TxHash: tx_hash, + TxHash: txHash, CoinType: coin.CoinType_Zeta, Proof: nil, BlockHash: "", TxIndex: 0, }) require.ErrorIs(t, err, authoritytypes.ErrUnauthorized) - _, found := k.GetInTxTracker(ctx, chainID, tx_hash) + _, found := k.GetInTxTracker(ctx, chainID, txHash) require.False(t, found) }) t.Run("fail for unsupported chain id", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeper(t) - tx_hash := "string" + msgServer := keeper.NewMsgServerImpl(*k) + + txHash := "string" chainID := getValidEthChainID(t) setSupportedChain(ctx, zk, chainID) - msgServer := keeper.NewMsgServerImpl(*k) - _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ Creator: sample.AccAddress(), ChainId: chainID + 1, - TxHash: tx_hash, + TxHash: txHash, CoinType: coin.CoinType_Zeta, Proof: nil, BlockHash: "", TxIndex: 0, }) require.ErrorIs(t, err, observertypes.ErrSupportedChains) - _, found := k.GetInTxTracker(ctx, chainID, tx_hash) + _, found := k.GetInTxTracker(ctx, chainID, txHash) require.False(t, found) }) @@ -94,133 +97,247 @@ func TestMsgServer_AddToInTxTracker(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, }) + msgServer := keeper.NewMsgServerImpl(*k) admin := sample.AccAddress() authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) - tx_hash := "string" + txHash := "string" chainID := getValidEthChainID(t) setSupportedChain(ctx, zk, chainID) + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: txHash, + CoinType: coin.CoinType_Zeta, + Proof: nil, + BlockHash: "", + TxIndex: 0, + }) + require.NoError(t, err) + _, found := k.GetInTxTracker(ctx, chainID, txHash) + require.True(t, found) + }) + + t.Run("observer add tx tracker", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) msgServer := keeper.NewMsgServerImpl(*k) + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + + keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(true) + + txHash := "string" + chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ Creator: admin, ChainId: chainID, - TxHash: tx_hash, + TxHash: txHash, CoinType: coin.CoinType_Zeta, Proof: nil, BlockHash: "", TxIndex: 0, }) require.NoError(t, err) - _, found := k.GetInTxTracker(ctx, chainID, tx_hash) + _, found := k.GetInTxTracker(ctx, chainID, txHash) require.True(t, found) }) - t.Run("admin submit fake tracker", func(t *testing.T) { + t.Run("fail if proof is provided but not verified", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ - UseAuthorityMock: true, + UseAuthorityMock: true, + UseLightclientMock: true, + UseObserverMock: true, }) + msgServer := keeper.NewMsgServerImpl(*k) admin := sample.AccAddress() authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) - keepertest.MockIsAuthorized(&authorityMock.Mock, admin, authoritytypes.PolicyType_groupEmergency, true) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + lightclientMock := keepertest.GetCrosschainLightclientMock(t, k) + + keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) + lightclientMock.On("VerifyProof", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("error")) txHash := "string" chainID := getValidEthChainID(t) setSupportedChain(ctx, zk, chainID) + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: txHash, + CoinType: coin.CoinType_Zeta, + Proof: &proofs.Proof{}, + BlockHash: "", + TxIndex: 0, + }) + require.ErrorIs(t, err, types.ErrProofVerificationFail) + }) + + t.Run("fail if proof is provided but can't find chain params to verify body", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseLightclientMock: true, + UseObserverMock: true, + }) msgServer := keeper.NewMsgServerImpl(*k) + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + lightclientMock := keepertest.GetCrosschainLightclientMock(t, k) + + keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) + lightclientMock.On("VerifyProof", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(sample.Bytes(), nil) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(nil, false) + + txHash := "string" + chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ Creator: admin, ChainId: chainID, - TxHash: "Malicious TX HASH", + TxHash: txHash, CoinType: coin.CoinType_Zeta, - Proof: nil, + Proof: &proofs.Proof{}, + BlockHash: "", + TxIndex: 0, + }) + require.ErrorIs(t, err, types.ErrUnsupportedChain) + }) + + t.Run("fail if proof is provided but can't find tss to verify body", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseLightclientMock: true, + UseObserverMock: true, + }) + msgServer := keeper.NewMsgServerImpl(*k) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + lightclientMock := keepertest.GetCrosschainLightclientMock(t, k) + + keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) + lightclientMock.On("VerifyProof", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(sample.Bytes(), nil) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain().ChainId), true) + observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(nil, errors.New("error")) + + txHash := "string" + chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) + + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: txHash, + CoinType: coin.CoinType_Zeta, + Proof: &proofs.Proof{}, + BlockHash: "", + TxIndex: 0, + }) + require.ErrorIs(t, err, observertypes.ErrTssNotFound) + }) + + t.Run("fail if proof is provided but error while verifying tx body", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseLightclientMock: true, + UseObserverMock: true, + }) + msgServer := keeper.NewMsgServerImpl(*k) + + admin := sample.AccAddress() + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + lightclientMock := keepertest.GetCrosschainLightclientMock(t, k) + + keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain().ChainId), true) + observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ + Eth: sample.EthAddress().Hex(), + }, nil) + + // verifying the body will fail because the bytes are tried to be unmarshaled but they are not valid + lightclientMock.On("VerifyProof", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]byte("invalid"), nil) + + txHash := "string" + chainID := getValidEthChainID(t) + setSupportedChain(ctx, zk, chainID) + + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: txHash, + CoinType: coin.CoinType_Zeta, + Proof: &proofs.Proof{}, + BlockHash: "", + TxIndex: 0, + }) + require.ErrorIs(t, err, types.ErrTxBodyVerificationFail) + }) + + t.Run("can add a in tx tracker with a proof", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseLightclientMock: true, + UseObserverMock: true, + }) + msgServer := keeper.NewMsgServerImpl(*k) + + admin := sample.AccAddress() + + chainID := chains.EthChain().ChainId + tssAddress := sample.EthAddress() + ethTx, ethTxBytes := sample.EthTx(t, chainID, tssAddress, 42) + txHash := ethTx.Hash().Hex() + + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + observerMock := keepertest.GetCrosschainObserverMock(t, k) + lightclientMock := keepertest.GetCrosschainLightclientMock(t, k) + + keepertest.MockIsAuthorized(&authorityMock.Mock, mock.Anything, authoritytypes.PolicyType_groupEmergency, false) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, mock.Anything).Return(&chains.Chain{}) + observerMock.On("IsNonTombstonedObserver", mock.Anything, mock.Anything).Return(false) + observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(sample.ChainParams(chains.EthChain().ChainId), true) + observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ + Eth: tssAddress.Hex(), + }, nil) + lightclientMock.On("VerifyProof", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(ethTxBytes, nil) + + _, err := msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ + Creator: admin, + ChainId: chainID, + TxHash: txHash, + CoinType: coin.CoinType_Gas, // use coin types gas: the receiver must be the tss address + Proof: &proofs.Proof{}, BlockHash: "", TxIndex: 0, }) require.NoError(t, err) - _, found := k.GetInTxTracker(ctx, chainID, "Malicious TX HASH") + _, found := k.GetInTxTracker(ctx, chainID, txHash) require.True(t, found) - _, found = k.GetInTxTracker(ctx, chainID, txHash) - require.False(t, found) }) - - // Commented out as these tests don't work without using RPC - // TODO: Reenable these tests - // https://github.com/zeta-chain/node/issues/1875 - //t.Run("add proof based tracker with correct proof", func(t *testing.T) { - // k, ctx, _, zk := keepertest.CrosschainKeeper(t) - // - // chainID := int64(5) - // - // txIndex, block, header, headerRLP, proof, tx, err := sample.Proof() - // require.NoError(t, err) - // setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block) - // msgServer := keeper.NewMsgServerImpl(*k) - // - // _, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ - // Creator: sample.AccAddress(), - // ChainId: chainID, - // TxHash: tx.Hash().Hex(), - // CoinType: pkg.CoinType_Zeta, - // Proof: proof, - // BlockHash: block.Hash().Hex(), - // TxIndex: txIndex, - // }) - // require.NoError(t, err) - // _, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex()) - // require.True(t, found) - //}) - //t.Run("fail to add proof based tracker with wrong tx hash", func(t *testing.T) { - // k, ctx, _, zk := keepertest.CrosschainKeeper(t) - // - // chainID := getValidEthChainID(t) - // - // txIndex, block, header, headerRLP, proof, tx, err := sample.Proof() - // require.NoError(t, err) - // setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block) - // msgServer := keeper.NewMsgServerImpl(*k) - // - // _, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ - // Creator: sample.AccAddress(), - // ChainId: chainID, - // TxHash: "fake_hash", - // CoinType: pkg.CoinType_Zeta, - // Proof: proof, - // BlockHash: block.Hash().Hex(), - // TxIndex: txIndex, - // }) - // require.ErrorIs(t, err, types.ErrTxBodyVerificationFail) - // _, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex()) - // require.False(t, found) - //}) - //t.Run("fail to add proof based tracker with wrong chain id", func(t *testing.T) { - // k, ctx, _, zk := keepertest.CrosschainKeeper(t) - // - // chainID := getValidEthChainID(t) - // - // txIndex, block, header, headerRLP, proof, tx, err := sample.Proof() - // require.NoError(t, err) - // setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block) - // - // msgServer := keeper.NewMsgServerImpl(*k) - // - // _, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ - // Creator: sample.AccAddress(), - // ChainId: 97, - // TxHash: tx.Hash().Hex(), - // CoinType: pkg.CoinType_Zeta, - // Proof: proof, - // BlockHash: block.Hash().Hex(), - // TxIndex: txIndex, - // }) - // require.ErrorIs(t, err, observertypes.ErrSupportedChains) - // _, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex()) - // require.False(t, found) - //}) } diff --git a/x/lightclient/keeper/block_header_test.go b/x/lightclient/keeper/block_header_test.go index 5c92f8133f..5760fa6c96 100644 --- a/x/lightclient/keeper/block_header_test.go +++ b/x/lightclient/keeper/block_header_test.go @@ -246,3 +246,343 @@ func TestMsgServer_VoteBlockHeader(t *testing.T) { } */ + +// Commented out as these tests don't work without using RPC +// TODO: Reenable these tests +// https://github.com/zeta-chain/node/issues/1875 +//t.Run("add proof based tracker with correct proof", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeper(t) +// +// chainID := int64(5) +// +// txIndex, block, header, headerRLP, proof, tx, err := sample.Proof() +// require.NoError(t, err) +// setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block) +// msgServer := keeper.NewMsgServerImpl(*k) +// +// _, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ +// Creator: sample.AccAddress(), +// ChainId: chainID, +// TxHash: tx.Hash().Hex(), +// CoinType: pkg.CoinType_Zeta, +// Proof: proof, +// BlockHash: block.Hash().Hex(), +// TxIndex: txIndex, +// }) +// require.NoError(t, err) +// _, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex()) +// require.True(t, found) +//}) +//t.Run("fail to add proof based tracker with wrong tx hash", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeper(t) +// +// chainID := getValidEthChainID(t) +// +// txIndex, block, header, headerRLP, proof, tx, err := sample.Proof() +// require.NoError(t, err) +// setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block) +// msgServer := keeper.NewMsgServerImpl(*k) +// +// _, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ +// Creator: sample.AccAddress(), +// ChainId: chainID, +// TxHash: "fake_hash", +// CoinType: pkg.CoinType_Zeta, +// Proof: proof, +// BlockHash: block.Hash().Hex(), +// TxIndex: txIndex, +// }) +// require.ErrorIs(t, err, types.ErrTxBodyVerificationFail) +// _, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex()) +// require.False(t, found) +//}) +//t.Run("fail to add proof based tracker with wrong chain id", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeper(t) +// +// chainID := getValidEthChainID(t) +// +// txIndex, block, header, headerRLP, proof, tx, err := sample.Proof() +// require.NoError(t, err) +// setupVerificationParams(zk, ctx, txIndex, chainID, header, headerRLP, block) +// +// msgServer := keeper.NewMsgServerImpl(*k) +// +// _, err = msgServer.AddToInTxTracker(ctx, &types.MsgAddToInTxTracker{ +// Creator: sample.AccAddress(), +// ChainId: 97, +// TxHash: tx.Hash().Hex(), +// CoinType: pkg.CoinType_Zeta, +// Proof: proof, +// BlockHash: block.Hash().Hex(), +// TxIndex: txIndex, +// }) +// require.ErrorIs(t, err, observertypes.ErrSupportedChains) +// _, found := k.GetInTxTracker(ctx, chainID, tx.Hash().Hex()) +// require.False(t, found) +//}) + +//func TestKeeper_VerifyEVMInTxBody(t *testing.T) { +//to := sample.EthAddress() +//tx := ethtypes.NewTx(ðtypes.DynamicFeeTx{ +// ChainID: big.NewInt(5), +// Nonce: 1, +// GasTipCap: nil, +// GasFeeCap: nil, +// Gas: 21000, +// To: &to, +// Value: big.NewInt(5), +// Data: nil, +//}) +// +//t.Run("should error if msg tx hash not correct", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: "0x0", +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) + +//t.Run("should error if msg chain id not correct", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: 1, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should error if not supported coin type", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Cmd, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should error for cointype_zeta if chain params not found", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{}, false) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Zeta, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should error for cointype_zeta if tx.to wrong", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ +// ConnectorContractAddress: sample.EthAddress().Hex(), +// }, true) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Zeta, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should not error for cointype_zeta", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ +// ConnectorContractAddress: to.Hex(), +// }, true) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Zeta, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.NoError(t, err) +//}) +// +//t.Run("should error for cointype_erc20 if chain params not found", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{}, false) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_ERC20, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should error for cointype_erc20 if tx.to wrong", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ +// Erc20CustodyContractAddress: sample.EthAddress().Hex(), +// }, true) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_ERC20, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should not error for cointype_erc20", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetChainParamsByChainID", mock.Anything, mock.Anything).Return(&observertypes.ChainParams{ +// Erc20CustodyContractAddress: to.Hex(), +// }, true) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_ERC20, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.NoError(t, err) +//}) +// +//t.Run("should error for cointype_gas if tss address not found", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{}, errors.New("err")) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Gas, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should error for cointype_gas if tss eth address is empty", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ +// Eth: "0x", +// }, nil) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Gas, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should error for cointype_gas if tss eth address is wrong", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ +// Eth: sample.EthAddress().Hex(), +// }, nil) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Gas, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.Error(t, err) +//}) +// +//t.Run("should not error for cointype_gas", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// observerMock.On("GetTssAddress", mock.Anything, mock.Anything).Return(&observertypes.QueryGetTssAddressResponse{ +// Eth: to.Hex(), +// }, nil) +// +// txBytes, err := tx.MarshalBinary() +// require.NoError(t, err) +// msg := &types.MsgAddToInTxTracker{ +// TxHash: tx.Hash().Hex(), +// ChainId: tx.ChainId().Int64(), +// CoinType: coin.CoinType_Gas, +// } +// +// err = k.VerifyEVMInTxBody(ctx, msg, txBytes) +// require.NoError(t, err) +//}) +//}