From 22a18e3062c3f8e86c94786b552485c67168ebf2 Mon Sep 17 00:00:00 2001 From: Sean King Date: Wed, 15 Sep 2021 18:50:24 +0200 Subject: [PATCH 1/2] test: adding tests for OnRecvPacket --- .../keeper/relay_test.go | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/modules/apps/27-interchain-accounts/keeper/relay_test.go b/modules/apps/27-interchain-accounts/keeper/relay_test.go index ea836fb8c05..7ed6f7b3e74 100644 --- a/modules/apps/27-interchain-accounts/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/keeper/relay_test.go @@ -1,9 +1,15 @@ package keeper_test import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/ibc-go/modules/apps/27-interchain-accounts/types" + clienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/testing" ) @@ -79,8 +85,10 @@ func (suite *KeeperTestSuite) TestTrySendTx() { err := suite.SetupICAPath(path, owner) suite.Require().NoError(err) + portID = path.EndpointA.ChannelConfig.PortID tc.malleate() + _, err = suite.chainA.GetSimApp().ICAKeeper.TrySendTx(suite.chainA.GetContext(), portID, msg) if tc.expPass { @@ -91,3 +99,102 @@ func (suite *KeeperTestSuite) TestTrySendTx() { }) } } + +func (suite *KeeperTestSuite) TestOnRecvPacket() { + var ( + path *ibctesting.Path + msg sdk.Msg + txBytes []byte + packetData []byte + ) + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + { + "Interchain account successfully executes banktypes.MsgSend", func() { + // build MsgSend + amount, _ := sdk.ParseCoinsNormalized("100stake") + interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) + msg = &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} + data := types.IBCAccountPacketData{Type: types.EXECUTE_TX, + Data: txBytes} + packetData = data.GetBytes() + }, true, + }, + { + "Cannot deserialize txBytes", func() { + txBytes = []byte("invalid tx bytes") + data := types.IBCAccountPacketData{Type: types.EXECUTE_TX, + Data: txBytes} + packetData = data.GetBytes() + }, false, + }, + { + "Cannot deserialize txBytes: invalid IBCTxRaw", func() { + txBody := []byte("invalid tx body") + txRaw := &types.IBCTxRaw{ + BodyBytes: txBody, + } + + txBytes = suite.chainB.Codec.MustMarshal(txRaw) + data := types.IBCAccountPacketData{Type: types.EXECUTE_TX, + Data: txBytes} + packetData = data.GetBytes() + }, false, + }, + { + "Wrong data type", func() { + txBytes = []byte{} + data := types.IBCAccountPacketData{Type: 100, + Data: txBytes} + packetData = data.GetBytes() + }, false, + }, + { + "Cannot unmarshal interchain account packet data", func() { + packetData = []byte{} + }, false, + }, + } + + for _, tc := range testCases { + tc := tc + + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + // setup interchain account + owner := suite.chainA.SenderAccount.GetAddress().String() + path = NewICAPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + err := suite.SetupICAPath(path, owner) + suite.Require().NoError(err) + + // send 100stake to interchain account wallet + amount, _ := sdk.ParseCoinsNormalized("100stake") + interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) + bankMsg := &banktypes.MsgSend{FromAddress: suite.chainB.SenderAccount.GetAddress().String(), ToAddress: interchainAccountAddr, Amount: amount} + _, err = suite.chainB.SendMsgs(bankMsg) + + txBytes, err = suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, msg) + // Next we need to define the packet/data to pass into OnRecvPacket + seq := uint64(1) + + tc.malleate() + + packet := channeltypes.NewPacket(packetData, seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) + + // Pass it in here + err = suite.chainB.GetSimApp().ICAKeeper.OnRecvPacket(suite.chainB.GetContext(), packet) + + if tc.expPass { + suite.Require().NoError(err) + } else { + suite.Require().Error(err) + } + }) + } +} From a44c4026bbc9d897736dd895ee2ee9f91ab5aa29 Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 16 Sep 2021 15:52:45 +0200 Subject: [PATCH 2/2] test: adding further test cases for onRecvPacket --- .../27-interchain-accounts/keeper/relay.go | 13 +---- .../keeper/relay_test.go | 49 ++++++++++++++----- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/modules/apps/27-interchain-accounts/keeper/relay.go b/modules/apps/27-interchain-accounts/keeper/relay.go index 15ddfdf7bd3..6884a026dba 100644 --- a/modules/apps/27-interchain-accounts/keeper/relay.go +++ b/modules/apps/27-interchain-accounts/keeper/relay.go @@ -44,18 +44,7 @@ func (k Keeper) createOutgoingPacket( return []byte{}, types.ErrInvalidOutgoingData } - var msgs []sdk.Msg - - switch data := data.(type) { - case []sdk.Msg: - msgs = data - case sdk.Msg: - msgs = []sdk.Msg{data} - default: - return []byte{}, types.ErrInvalidOutgoingData - } - - txBytes, err := k.SerializeCosmosTx(k.cdc, msgs) + txBytes, err := k.SerializeCosmosTx(k.cdc, data) if err != nil { return []byte{}, sdkerrors.Wrap(err, "invalid packet data or codec") } diff --git a/modules/apps/27-interchain-accounts/keeper/relay_test.go b/modules/apps/27-interchain-accounts/keeper/relay_test.go index 7ed6f7b3e74..6fd53d7b888 100644 --- a/modules/apps/27-interchain-accounts/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/keeper/relay_test.go @@ -80,13 +80,13 @@ func (suite *KeeperTestSuite) TestTrySendTx() { suite.Run(tc.name, func() { suite.SetupTest() // reset path = NewICAPath(suite.chainA, suite.chainB) - owner := TestOwnerAddress suite.coordinator.SetupConnections(path) - err := suite.SetupICAPath(path, owner) + err := suite.SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) portID = path.EndpointA.ChannelConfig.PortID + tc.malleate() _, err = suite.chainA.GetSimApp().ICAKeeper.TrySendTx(suite.chainA.GetContext(), portID, msg) @@ -106,6 +106,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { msg sdk.Msg txBytes []byte packetData []byte + sourcePort string ) testCases := []struct { @@ -119,6 +120,10 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { amount, _ := sdk.ParseCoinsNormalized("100stake") interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) msg = &banktypes.MsgSend{FromAddress: interchainAccountAddr, ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} + // build packet data + txBytes, err := suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, msg) + suite.Require().NoError(err) + data := types.IBCAccountPacketData{Type: types.EXECUTE_TX, Data: txBytes} packetData = data.GetBytes() @@ -146,18 +151,39 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { }, false, }, { - "Wrong data type", func() { + "Invalid packet type", func() { txBytes = []byte{} + // Type here is an ENUM + // Valid type is types.EXECUTE_TX data := types.IBCAccountPacketData{Type: 100, Data: txBytes} packetData = data.GetBytes() }, false, }, { - "Cannot unmarshal interchain account packet data", func() { + "Cannot unmarshal interchain account packet data into types.IBCAccountPacketData", func() { packetData = []byte{} }, false, }, + { + "Unauthorised: Interchain account not found for given source portID", func() { + sourcePort = "invalid-port-id" + }, false, + }, + { + "Unauthorised: Signer of message is not the interchain account associated with sourcePortID", func() { + // build MsgSend + amount, _ := sdk.ParseCoinsNormalized("100stake") + // Incorrect FromAddress + msg = &banktypes.MsgSend{FromAddress: suite.chainB.SenderAccount.GetAddress().String(), ToAddress: suite.chainB.SenderAccount.GetAddress().String(), Amount: amount} + // build packet data + txBytes, err := suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, msg) + suite.Require().NoError(err) + data := types.IBCAccountPacketData{Type: types.EXECUTE_TX, + Data: txBytes} + packetData = data.GetBytes() + }, false, + }, } for _, tc := range testCases { @@ -166,26 +192,27 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset - // setup interchain account - owner := suite.chainA.SenderAccount.GetAddress().String() path = NewICAPath(suite.chainA, suite.chainB) suite.coordinator.SetupConnections(path) - err := suite.SetupICAPath(path, owner) + err := suite.SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) // send 100stake to interchain account wallet amount, _ := sdk.ParseCoinsNormalized("100stake") interchainAccountAddr, _ := suite.chainB.GetSimApp().ICAKeeper.GetInterchainAccountAddress(suite.chainB.GetContext(), path.EndpointA.ChannelConfig.PortID) bankMsg := &banktypes.MsgSend{FromAddress: suite.chainB.SenderAccount.GetAddress().String(), ToAddress: interchainAccountAddr, Amount: amount} + _, err = suite.chainB.SendMsgs(bankMsg) + suite.Require().NoError(err) - txBytes, err = suite.chainA.GetSimApp().ICAKeeper.SerializeCosmosTx(suite.chainA.Codec, msg) - // Next we need to define the packet/data to pass into OnRecvPacket - seq := uint64(1) + // valid source port + sourcePort = path.EndpointA.ChannelConfig.PortID + // malleate packetData for test cases tc.malleate() - packet := channeltypes.NewPacket(packetData, seq, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) + seq := uint64(1) + packet := channeltypes.NewPacket(packetData, seq, sourcePort, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.NewHeight(0, 100), 0) // Pass it in here err = suite.chainB.GetSimApp().ICAKeeper.OnRecvPacket(suite.chainB.GetContext(), packet)