cosmos-sdk/x/ibc/04-channel/keeper/grpc_query_test.go

1118 lines
27 KiB
Go
Raw Normal View History

package keeper_test
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
"github.com/cosmos/cosmos-sdk/x/ibc/exported"
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
)
func (suite *KeeperTestSuite) TestQueryChannel() {
var (
req *types.QueryChannelRequest
expChannel types.Channel
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid port ID",
func() {
req = &types.QueryChannelRequest{
PortId: "",
ChannelId: "test-channel-id",
}
},
false,
},
{
"invalid channel ID",
func() {
req = &types.QueryChannelRequest{
PortId: "test-port-id",
ChannelId: "",
}
},
false,
},
{"channel not found",
func() {
req = &types.QueryChannelRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
}
},
false,
},
{
"success",
func() {
_, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
// init channel
channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.TransferPort, ibctesting.TransferPort, types.ORDERED)
suite.Require().NoError(err)
expChannel = suite.chainA.GetChannel(channelA)
req = &types.QueryChannelRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.Channel(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(&expChannel, res.Channel)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryChannels() {
var (
req *types.QueryChannelsRequest
expChannels = []*types.IdentifiedChannel{}
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"empty pagination",
func() {
req = &types.QueryChannelsRequest{}
},
true,
},
{
"success",
func() {
_, _, connA0, connB0, testchannel0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
// channel0 on first connection on chainA
counterparty0 := types.Counterparty{
PortId: connB0.Channels[0].PortID,
ChannelId: connB0.Channels[0].ID,
}
// channel1 is second channel on first connection on chainA
testchannel1, _ := suite.coordinator.CreateMockChannels(suite.chainA, suite.chainB, connA0, connB0, types.ORDERED)
counterparty1 := types.Counterparty{
PortId: connB0.Channels[1].PortID,
ChannelId: connB0.Channels[1].ID,
}
channel0 := types.NewChannel(
types.OPEN, types.UNORDERED,
counterparty0, []string{connA0.ID}, testchannel0.Version,
)
channel1 := types.NewChannel(
types.OPEN, types.ORDERED,
counterparty1, []string{connA0.ID}, testchannel1.Version,
)
idCh0 := types.NewIdentifiedChannel(testchannel0.PortID, testchannel0.ID, channel0)
idCh1 := types.NewIdentifiedChannel(testchannel1.PortID, testchannel1.ID, channel1)
expChannels = []*types.IdentifiedChannel{&idCh0, &idCh1}
req = &types.QueryChannelsRequest{
Pagination: &query.PageRequest{
Key: nil,
Limit: 2,
CountTotal: true,
},
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.Channels(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expChannels, res.Channels)
suite.Require().Equal(len(expChannels), int(res.Pagination.Total))
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryConnectionChannels() {
var (
req *types.QueryConnectionChannelsRequest
expChannels = []*types.IdentifiedChannel{}
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid connection ID",
func() {
req = &types.QueryConnectionChannelsRequest{
Connection: "",
}
},
false,
},
{
"success",
func() {
_, _, connA0, connB0, testchannel0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
// channel0 on first connection on chainA
counterparty0 := types.Counterparty{
PortId: connB0.Channels[0].PortID,
ChannelId: connB0.Channels[0].ID,
}
// channel1 is second channel on first connection on chainA
testchannel1, _ := suite.coordinator.CreateMockChannels(suite.chainA, suite.chainB, connA0, connB0, types.ORDERED)
counterparty1 := types.Counterparty{
PortId: connB0.Channels[1].PortID,
ChannelId: connB0.Channels[1].ID,
}
channel0 := types.NewChannel(
types.OPEN, types.UNORDERED,
counterparty0, []string{connA0.ID}, testchannel0.Version,
)
channel1 := types.NewChannel(
types.OPEN, types.ORDERED,
counterparty1, []string{connA0.ID}, testchannel1.Version,
)
idCh0 := types.NewIdentifiedChannel(testchannel0.PortID, testchannel0.ID, channel0)
idCh1 := types.NewIdentifiedChannel(testchannel1.PortID, testchannel1.ID, channel1)
expChannels = []*types.IdentifiedChannel{&idCh0, &idCh1}
req = &types.QueryConnectionChannelsRequest{
Connection: connA0.ID,
Pagination: &query.PageRequest{
Key: nil,
Limit: 2,
CountTotal: true,
},
}
},
true,
},
{
"success, empty response",
func() {
suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
expChannels = []*types.IdentifiedChannel{}
req = &types.QueryConnectionChannelsRequest{
Connection: "externalConnID",
Pagination: &query.PageRequest{
Key: nil,
Limit: 2,
CountTotal: false,
},
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.ConnectionChannels(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expChannels, res.Channels)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryChannelClientState() {
var (
req *types.QueryChannelClientStateRequest
expIdentifiedClientState clienttypes.IdentifiedClientState
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid port ID",
func() {
req = &types.QueryChannelClientStateRequest{
PortId: "",
ChannelId: "test-channel-id",
}
},
false,
},
{
"invalid channel ID",
func() {
req = &types.QueryChannelClientStateRequest{
PortId: "test-port-id",
ChannelId: "",
}
},
false,
},
{
"channel not found",
func() {
req = &types.QueryChannelClientStateRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
}
},
false,
},
{
"connection not found",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
channel := suite.chainA.GetChannel(channelA)
// update channel to reference a connection that does not exist
channel.ConnectionHops[0] = "doesnotexist"
// set connection hops to wrong connection ID
suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel)
req = &types.QueryChannelClientStateRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
}
}, false,
},
{
"client state for channel's connection not found",
func() {
_, _, connA, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
// set connection to empty so clientID is empty
suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connectiontypes.ConnectionEnd{})
req = &types.QueryChannelClientStateRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
}
}, false,
},
{
"success",
func() {
clientA, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
// init channel
channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.TransferPort, ibctesting.TransferPort, types.ORDERED)
suite.Require().NoError(err)
expClientState := suite.chainA.GetClientState(clientA)
expIdentifiedClientState = clienttypes.NewIdentifiedClientState(clientA, expClientState)
req = &types.QueryChannelClientStateRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.ChannelClientState(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(&expIdentifiedClientState, res.IdentifiedClientState)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryChannelConsensusState() {
var (
req *types.QueryChannelConsensusStateRequest
expConsensusState exported.ConsensusState
expClientID string
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid port ID",
func() {
req = &types.QueryChannelConsensusStateRequest{
PortId: "",
ChannelId: "test-channel-id",
EpochNumber: 0,
EpochHeight: 1,
}
},
false,
},
{
"invalid channel ID",
func() {
req = &types.QueryChannelConsensusStateRequest{
PortId: "test-port-id",
ChannelId: "",
EpochNumber: 0,
EpochHeight: 1,
}
},
false,
},
{
"channel not found",
func() {
req = &types.QueryChannelConsensusStateRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
EpochNumber: 0,
EpochHeight: 1,
}
},
false,
},
{
"connection not found",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
channel := suite.chainA.GetChannel(channelA)
// update channel to reference a connection that does not exist
channel.ConnectionHops[0] = "doesnotexist"
// set connection hops to wrong connection ID
suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel)
req = &types.QueryChannelConsensusStateRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
EpochNumber: 0,
EpochHeight: 1,
}
}, false,
},
{
"consensus state for channel's connection not found",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
req = &types.QueryChannelConsensusStateRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
EpochNumber: 0,
EpochHeight: uint64(suite.chainA.GetContext().BlockHeight()), // use current height
}
}, false,
},
{
"success",
func() {
clientA, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint)
// init channel
channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.TransferPort, ibctesting.TransferPort, types.ORDERED)
suite.Require().NoError(err)
clientState := suite.chainA.GetClientState(clientA)
expConsensusState, _ = suite.chainA.GetConsensusState(clientA, clientState.GetLatestHeight())
suite.Require().NotNil(expConsensusState)
expClientID = clientA
req = &types.QueryChannelConsensusStateRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
EpochNumber: expConsensusState.GetHeight().GetEpochNumber(),
EpochHeight: expConsensusState.GetHeight().GetEpochHeight(),
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.ChannelConsensusState(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
consensusState, err := clienttypes.UnpackConsensusState(res.ConsensusState)
suite.Require().NoError(err)
suite.Require().Equal(expConsensusState, consensusState)
suite.Require().Equal(expClientID, res.ClientId)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryPacketCommitment() {
var (
req *types.QueryPacketCommitmentRequest
expCommitment []byte
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid port ID",
func() {
req = &types.QueryPacketCommitmentRequest{
PortId: "",
ChannelId: "test-channel-id",
Sequence: 0,
}
},
false,
},
{
"invalid channel ID",
func() {
req = &types.QueryPacketCommitmentRequest{
PortId: "test-port-id",
ChannelId: "",
Sequence: 0,
}
},
false,
},
{"invalid sequence",
func() {
req = &types.QueryPacketCommitmentRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
Sequence: 0,
}
},
false,
},
{"channel not found",
func() {
req = &types.QueryPacketCommitmentRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
Sequence: 1,
}
},
false,
},
{
"success",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
expCommitment = []byte("hash")
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), channelA.PortID, channelA.ID, 1, expCommitment)
req = &types.QueryPacketCommitmentRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
Sequence: 1,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.PacketCommitment(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expCommitment, res.Commitment)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryPacketCommitments() {
var (
req *types.QueryPacketCommitmentsRequest
expCommitments = []*types.PacketAckCommitment{}
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid ID",
func() {
req = &types.QueryPacketCommitmentsRequest{
PortId: "",
ChannelId: "test-channel-id",
}
},
false,
},
{
"success, empty res",
func() {
expCommitments = []*types.PacketAckCommitment{}
req = &types.QueryPacketCommitmentsRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
Pagination: &query.PageRequest{
Key: nil,
Limit: 2,
CountTotal: true,
},
}
},
true,
},
{
"success",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
expCommitments = make([]*types.PacketAckCommitment, 9)
for i := uint64(0); i < 9; i++ {
commitment := types.NewPacketAckCommitment(channelA.PortID, channelA.ID, i, []byte(fmt.Sprintf("hash_%d", i)))
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), commitment.PortId, commitment.ChannelId, commitment.Sequence, commitment.Hash)
expCommitments[i] = &commitment
}
req = &types.QueryPacketCommitmentsRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
Pagination: &query.PageRequest{
Key: nil,
Limit: 11,
CountTotal: true,
},
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.PacketCommitments(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expCommitments, res.Commitments)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryPacketAcknowledgement() {
var (
req *types.QueryPacketAcknowledgementRequest
expAck []byte
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid port ID",
func() {
req = &types.QueryPacketAcknowledgementRequest{
PortId: "",
ChannelId: "test-channel-id",
Sequence: 0,
}
},
false,
},
{
"invalid channel ID",
func() {
req = &types.QueryPacketAcknowledgementRequest{
PortId: "test-port-id",
ChannelId: "",
Sequence: 0,
}
},
false,
},
{"invalid sequence",
func() {
req = &types.QueryPacketAcknowledgementRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
Sequence: 0,
}
},
false,
},
{"channel not found",
func() {
req = &types.QueryPacketAcknowledgementRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
Sequence: 1,
}
},
false,
},
{
"success",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
expAck = []byte("hash")
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), channelA.PortID, channelA.ID, 1, expAck)
req = &types.QueryPacketAcknowledgementRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
Sequence: 1,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.PacketAcknowledgement(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expAck, res.Acknowledgement)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryUnrelayedPackets() {
var (
req *types.QueryUnrelayedPacketsRequest
expSeq = []uint64{}
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid port ID",
func() {
req = &types.QueryUnrelayedPacketsRequest{
PortId: "",
ChannelId: "test-channel-id",
}
},
false,
},
{
"invalid channel ID",
func() {
req = &types.QueryUnrelayedPacketsRequest{
PortId: "test-port-id",
ChannelId: "",
}
},
false,
},
{
"invalid seq",
func() {
req = &types.QueryUnrelayedPacketsRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
PacketCommitmentSequences: []uint64{0},
}
},
false,
},
{
"basic success unrelayed packet commitments",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
// no ack exists
expSeq = []uint64{1}
req = &types.QueryUnrelayedPacketsRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
PacketCommitmentSequences: []uint64{1},
Acknowledgements: false,
}
},
true,
},
{
"basic success unrelayed packet commitments, nothing to relay",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
// ack exists
ack := types.NewPacketAckCommitment(channelA.PortID, channelA.ID, 1, []byte("hash"))
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), channelA.PortID, channelA.ID, 1, ack.Hash)
expSeq = []uint64{}
req = &types.QueryUnrelayedPacketsRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
PacketCommitmentSequences: []uint64{1},
Acknowledgements: false,
}
},
true,
},
{
"basic success unrelayed acknowledgements",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
// ack exists
ack := types.NewPacketAckCommitment(channelA.PortID, channelA.ID, 1, []byte("hash"))
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), channelA.PortID, channelA.ID, 1, ack.Hash)
expSeq = []uint64{1}
req = &types.QueryUnrelayedPacketsRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
PacketCommitmentSequences: []uint64{1},
Acknowledgements: true,
}
},
true,
},
{
"basic success unrelayed acknowledgements, nothing to relay",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
// no ack exists
expSeq = []uint64{}
req = &types.QueryUnrelayedPacketsRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
PacketCommitmentSequences: []uint64{1},
Acknowledgements: true,
}
},
true,
},
{
"success multiple unrelayed packet commitments",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
expSeq = []uint64{} // reset
packetCommitments := []uint64{}
// set ack for every other sequence
for seq := uint64(1); seq < 10; seq++ {
packetCommitments = append(packetCommitments, seq)
if seq%2 == 0 {
ack := types.NewPacketAckCommitment(channelA.PortID, channelA.ID, seq, []byte("hash"))
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), channelA.PortID, channelA.ID, seq, ack.Hash)
} else {
expSeq = append(expSeq, seq)
}
}
req = &types.QueryUnrelayedPacketsRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
PacketCommitmentSequences: packetCommitments,
Acknowledgements: false,
}
},
true,
},
{
"success multiple unrelayed acknowledgements",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
expSeq = []uint64{} // reset
packetCommitments := []uint64{}
// set ack for every other sequence
for seq := uint64(1); seq < 10; seq++ {
packetCommitments = append(packetCommitments, seq)
if seq%2 == 0 {
ack := types.NewPacketAckCommitment(channelA.PortID, channelA.ID, seq, []byte("hash"))
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), channelA.PortID, channelA.ID, seq, ack.Hash)
expSeq = append(expSeq, seq)
}
}
req = &types.QueryUnrelayedPacketsRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
PacketCommitmentSequences: packetCommitments,
Acknowledgements: true,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.UnrelayedPackets(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expSeq, res.Sequences)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryNextSequenceReceive() {
var (
req *types.QueryNextSequenceReceiveRequest
expSeq uint64
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = nil
},
false,
},
{
"invalid port ID",
func() {
req = &types.QueryNextSequenceReceiveRequest{
PortId: "",
ChannelId: "test-channel-id",
}
},
false,
},
{
"invalid channel ID",
func() {
req = &types.QueryNextSequenceReceiveRequest{
PortId: "test-port-id",
ChannelId: "",
}
},
false,
},
{"channel not found",
func() {
req = &types.QueryNextSequenceReceiveRequest{
PortId: "test-port-id",
ChannelId: "test-channel-id",
}
},
false,
},
{
"success",
func() {
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED)
expSeq = 1
suite.chainA.App.IBCKeeper.ChannelKeeper.SetNextSequenceRecv(suite.chainA.GetContext(), channelA.PortID, channelA.ID, expSeq)
req = &types.QueryNextSequenceReceiveRequest{
PortId: channelA.PortID,
ChannelId: channelA.ID,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.chainA.QueryServer.NextSequenceReceive(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expSeq, res.NextSequenceReceive)
} else {
suite.Require().Error(err)
}
})
}
}