551 lines
16 KiB
Go
551 lines
16 KiB
Go
package keeper_test
|
|
|
|
import (
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
|
|
connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
|
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
|
|
)
|
|
|
|
// TestQueryChannels tests singular, multiple, and no connection for
|
|
// correct retrieval of all channels.
|
|
func (suite *KeeperTestSuite) TestQueryChannels() {
|
|
path := []string{types.SubModuleName, types.QueryAllChannels}
|
|
var (
|
|
expRes []byte
|
|
err error
|
|
)
|
|
|
|
params := types.NewQueryAllChannelsParams(1, 100)
|
|
data, err := suite.chainA.App.AppCodec().MarshalJSON(params)
|
|
suite.Require().NoError(err)
|
|
|
|
query := abci.RequestQuery{
|
|
Path: "",
|
|
Data: data,
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
setup func()
|
|
}{
|
|
{
|
|
"success with different connection channels",
|
|
func() {
|
|
channels := make([]types.IdentifiedChannel, 0, 2)
|
|
|
|
// create first connection/channel
|
|
clientA, clientB, _, _, channelA0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
channels = append(channels,
|
|
types.NewIdentifiedChannel(
|
|
channelA0.PortID,
|
|
channelA0.ID,
|
|
suite.chainA.GetChannel(channelA0),
|
|
),
|
|
)
|
|
|
|
// create second connection
|
|
connA1, connB1 := suite.coordinator.CreateConnection(suite.chainA, suite.chainB, clientA, clientB)
|
|
|
|
// create second channel on second connection
|
|
channelA1, _ := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA1, connB1, types.ORDERED)
|
|
|
|
channels = append(channels,
|
|
types.NewIdentifiedChannel(
|
|
channelA1.PortID,
|
|
channelA1.ID,
|
|
suite.chainA.GetChannel(channelA1),
|
|
),
|
|
)
|
|
|
|
// set expected result
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), channels)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
{
|
|
"success with singular connection channels",
|
|
func() {
|
|
channels := make([]types.IdentifiedChannel, 0, 2)
|
|
|
|
// create first connection/channel
|
|
_, _, connA, connB, channelA0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
channels = append(channels,
|
|
types.NewIdentifiedChannel(
|
|
channelA0.PortID,
|
|
channelA0.ID,
|
|
suite.chainA.GetChannel(channelA0),
|
|
),
|
|
)
|
|
|
|
// create second channel on the same connection
|
|
channelA1, _ := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, types.UNORDERED)
|
|
channels = append(channels,
|
|
types.NewIdentifiedChannel(
|
|
channelA1.PortID,
|
|
channelA1.ID,
|
|
suite.chainA.GetChannel(channelA1),
|
|
),
|
|
)
|
|
|
|
// set expected result
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), channels)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
{
|
|
"success no channels",
|
|
func() {
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), []types.IdentifiedChannel{})
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, tc := range testCases {
|
|
suite.SetupTest() // reset
|
|
tc.setup()
|
|
|
|
bz, err := suite.chainA.Querier(suite.chainA.GetContext(), path, query)
|
|
|
|
suite.Require().NoError(err, "test case %d failed: %s", i, tc.name)
|
|
suite.Require().Equal(expRes, bz, "test case %d failed: %s", i, tc.name)
|
|
}
|
|
}
|
|
|
|
// TestQueryConnectionChannel tests querying existing channels on a singular connection.
|
|
func (suite *KeeperTestSuite) TestQueryConnectionChannels() {
|
|
path := []string{types.SubModuleName, types.QueryConnectionChannels}
|
|
|
|
var (
|
|
expRes []byte
|
|
params types.QueryConnectionChannelsParams
|
|
err error
|
|
)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
setup func()
|
|
}{
|
|
{
|
|
"success with singular connection channels",
|
|
func() {
|
|
channels := make([]types.IdentifiedChannel, 0, 2)
|
|
|
|
// create first connection/channel
|
|
_, _, connA, connB, channelA0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
channels = append(channels,
|
|
types.NewIdentifiedChannel(
|
|
channelA0.PortID,
|
|
channelA0.ID,
|
|
suite.chainA.GetChannel(channelA0),
|
|
),
|
|
)
|
|
|
|
// create second channel on the same connection
|
|
channelA1, _ := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, types.ORDERED)
|
|
channels = append(channels,
|
|
types.NewIdentifiedChannel(
|
|
channelA1.PortID,
|
|
channelA1.ID,
|
|
suite.chainA.GetChannel(channelA1),
|
|
),
|
|
)
|
|
|
|
params = types.NewQueryConnectionChannelsParams(connA.ID, 1, 100)
|
|
|
|
// set expected result
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), channels)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
{
|
|
"success multiple connection channels",
|
|
func() {
|
|
channels := make([]types.IdentifiedChannel, 0, 1)
|
|
|
|
// create first connection/channel
|
|
clientA, clientB, connA, _, channelA0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
channels = append(channels,
|
|
types.NewIdentifiedChannel(
|
|
channelA0.PortID,
|
|
channelA0.ID,
|
|
suite.chainA.GetChannel(channelA0),
|
|
),
|
|
)
|
|
|
|
// create second connection
|
|
connA1, connB1 := suite.coordinator.CreateConnection(suite.chainA, suite.chainB, clientA, clientB)
|
|
|
|
// create second channel on second connection
|
|
suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA1, connB1, types.ORDERED)
|
|
|
|
params = types.NewQueryConnectionChannelsParams(connA.ID, 1, 100)
|
|
|
|
// set expected result
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), channels)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
{
|
|
"success no channels",
|
|
func() {
|
|
// create connection but no channels
|
|
_, _, connA, _ := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint)
|
|
params = types.NewQueryConnectionChannelsParams(connA.ID, 1, 100)
|
|
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), []types.IdentifiedChannel{})
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, tc := range testCases {
|
|
suite.SetupTest() // reset
|
|
tc.setup()
|
|
|
|
data, err := suite.chainA.App.AppCodec().MarshalJSON(params)
|
|
suite.Require().NoError(err)
|
|
|
|
query := abci.RequestQuery{
|
|
Path: "",
|
|
Data: data,
|
|
}
|
|
|
|
bz, err := suite.chainA.Querier(suite.chainA.GetContext(), path, query)
|
|
|
|
suite.Require().NoError(err, "test case %d failed: %s", i, tc.name)
|
|
suite.Require().Equal(expRes, bz, "test case %d failed: %s", i, tc.name)
|
|
}
|
|
}
|
|
|
|
// TestQuerierChannelClientState verifies correct querying of client state associated
|
|
// with a channel end.
|
|
func (suite *KeeperTestSuite) TestQuerierChannelClientState() {
|
|
path := []string{types.SubModuleName, types.QueryChannelClientState}
|
|
|
|
var (
|
|
clientID string
|
|
params types.QueryChannelClientStateParams
|
|
)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
setup func()
|
|
expPass bool
|
|
}{
|
|
{
|
|
"channel not found",
|
|
func() {
|
|
clientA, err := suite.coordinator.CreateClient(suite.chainA, suite.chainB, clientexported.Tendermint)
|
|
suite.Require().NoError(err)
|
|
|
|
clientID = clientA
|
|
params = types.NewQueryChannelClientStateParams("doesnotexist", "doesnotexist")
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"connection for channel not found",
|
|
func() {
|
|
// connection for channel is deleted from state
|
|
clientA, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
channel := suite.chainA.GetChannel(channelA)
|
|
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)
|
|
|
|
clientID = clientA
|
|
params = types.NewQueryChannelClientStateParams(channelA.PortID, channelA.ID)
|
|
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"client state for channel's connection not found",
|
|
func() {
|
|
clientA, _, connA, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
// setting connection to empty results in wrong clientID used
|
|
suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connectiontypes.ConnectionEnd{})
|
|
|
|
clientID = clientA
|
|
params = types.NewQueryChannelClientStateParams(channelA.PortID, channelA.ID)
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"success",
|
|
func() {
|
|
clientA, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
clientID = clientA
|
|
params = types.NewQueryChannelClientStateParams(channelA.PortID, channelA.ID)
|
|
},
|
|
true,
|
|
},
|
|
}
|
|
|
|
for i, tc := range testCases {
|
|
suite.SetupTest() // reset
|
|
tc.setup()
|
|
|
|
data, err := suite.chainA.App.AppCodec().MarshalJSON(params)
|
|
suite.Require().NoError(err)
|
|
|
|
query := abci.RequestQuery{
|
|
Path: "",
|
|
Data: data,
|
|
}
|
|
|
|
clientState, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientID)
|
|
bz, err := suite.chainA.Querier(suite.chainA.GetContext(), path, query)
|
|
|
|
if tc.expPass {
|
|
// set expected result
|
|
expRes, merr := codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), clientState)
|
|
suite.Require().NoError(merr)
|
|
suite.Require().True(found, "test case %d failed: %s", i, tc.name)
|
|
suite.Require().NoError(err, "test case %d failed: %s", i, tc.name)
|
|
suite.Require().Equal(string(expRes), string(bz), "test case %d failed: %s", i, tc.name)
|
|
} else {
|
|
suite.Require().Error(err, "test case %d passed: %s", i, tc.name)
|
|
suite.Require().Nil(bz, "test case %d passed: %s", i, tc.name)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestQueryPacketCommitments tests querying packet commitments on a specified channel end.
|
|
func (suite *KeeperTestSuite) TestQueryPacketCommitments() {
|
|
path := []string{types.SubModuleName, types.QueryPacketCommitments}
|
|
|
|
var (
|
|
expRes []byte
|
|
params types.QueryPacketCommitmentsParams
|
|
err error
|
|
)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
setup func()
|
|
}{
|
|
{
|
|
"success",
|
|
func() {
|
|
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
seq := uint64(1)
|
|
commitments := []uint64{}
|
|
|
|
// create several commitments on the same channel and port
|
|
for i := seq; i < 10; i++ {
|
|
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), channelA.PortID, channelA.ID, i, []byte("ack"))
|
|
commitments = append(commitments, i)
|
|
}
|
|
|
|
params = types.NewQueryPacketCommitmentsParams(channelA.PortID, channelA.ID, 1, 100)
|
|
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), commitments)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
{
|
|
"success with multiple channels",
|
|
func() {
|
|
_, _, connA, connB, channelA0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
seq := uint64(1)
|
|
commitments := []uint64{}
|
|
|
|
// create several commitments on the same channel and port
|
|
for i := seq; i < 10; i++ {
|
|
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), channelA0.PortID, channelA0.ID, i, []byte("ack"))
|
|
commitments = append(commitments, i)
|
|
}
|
|
|
|
// create second channel
|
|
channelA1, _ := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, types.ORDERED)
|
|
|
|
// create several commitments on a different channel and port
|
|
for i := seq; i < 10; i++ {
|
|
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), channelA1.PortID, channelA1.ID, i, []byte("ack"))
|
|
}
|
|
|
|
params = types.NewQueryPacketCommitmentsParams(channelA0.PortID, channelA1.ID, 1, 100)
|
|
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), commitments)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
{
|
|
"success no packet commitments",
|
|
func() {
|
|
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
params = types.NewQueryPacketCommitmentsParams(channelA.PortID, channelA.ID, 1, 100)
|
|
|
|
expRes, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), []uint64{})
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, tc := range testCases {
|
|
suite.SetupTest() // reset
|
|
tc.setup()
|
|
|
|
data, err := suite.chainA.App.AppCodec().MarshalJSON(params)
|
|
suite.Require().NoError(err)
|
|
|
|
query := abci.RequestQuery{
|
|
Path: "",
|
|
Data: data,
|
|
}
|
|
|
|
bz, err := suite.chainA.Querier(suite.chainA.GetContext(), path, query)
|
|
|
|
suite.Require().NoError(err, "test case %d failed: %s", i, tc.name)
|
|
suite.Require().Equal(expRes, bz, "test case %d failed: %s", i, tc.name)
|
|
}
|
|
|
|
}
|
|
|
|
// TestQueryUnrelayedPackets tests querying unrelayed acknowledgements and unrelayed packets sends
|
|
// on a specified channel end.
|
|
func (suite *KeeperTestSuite) TestQueryUnrelayedAcks() {
|
|
pathAck := []string{types.SubModuleName, types.QueryUnrelayedAcknowledgements}
|
|
pathSend := []string{types.SubModuleName, types.QueryUnrelayedPacketSends}
|
|
sequences := []uint64{1, 2, 3, 4, 5}
|
|
|
|
var (
|
|
expResAck []byte
|
|
expResSend []byte
|
|
params types.QueryUnrelayedPacketsParams
|
|
err error
|
|
)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
setup func()
|
|
}{
|
|
{
|
|
"success",
|
|
func() {
|
|
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
unrelayedAcks := []uint64{}
|
|
unrelayedSends := []uint64{}
|
|
|
|
// create acknowledgements for first 3 sequences
|
|
for _, seq := range sequences {
|
|
if seq < 4 {
|
|
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), channelA.PortID, channelA.ID, seq, []byte("ack"))
|
|
unrelayedAcks = append(unrelayedAcks, seq)
|
|
} else {
|
|
unrelayedSends = append(unrelayedSends, seq)
|
|
}
|
|
}
|
|
|
|
params = types.NewQueryUnrelayedPacketsParams(channelA.PortID, channelA.ID, sequences, 1, 100)
|
|
|
|
expResAck, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), unrelayedAcks)
|
|
suite.Require().NoError(err)
|
|
|
|
expResSend, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), unrelayedSends)
|
|
suite.Require().NoError(err)
|
|
|
|
},
|
|
},
|
|
{
|
|
"success with multiple channels",
|
|
func() {
|
|
_, _, connA, connB, channelA0, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
ctxA := suite.chainA.GetContext()
|
|
|
|
unrelayedAcks := []uint64{}
|
|
unrelayedSends := []uint64{}
|
|
|
|
// create acknowledgements for first 3 sequences
|
|
for _, seq := range sequences {
|
|
if seq < 4 {
|
|
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(ctxA, channelA0.PortID, channelA0.ID, seq, []byte("ack"))
|
|
unrelayedAcks = append(unrelayedAcks, seq)
|
|
} else {
|
|
unrelayedSends = append(unrelayedSends, seq)
|
|
}
|
|
}
|
|
|
|
// create second channel
|
|
channelA1, _ := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, types.UNORDERED)
|
|
|
|
// create acknowledgements for other sequences on different channel/port
|
|
for _, seq := range sequences {
|
|
if seq >= 4 {
|
|
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(ctxA, channelA1.PortID, channelA1.ID, seq, []byte("ack"))
|
|
}
|
|
}
|
|
|
|
params = types.NewQueryUnrelayedPacketsParams(channelA0.PortID, channelA0.ID, sequences, 1, 100)
|
|
|
|
expResAck, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), unrelayedAcks)
|
|
suite.Require().NoError(err)
|
|
|
|
expResSend, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), unrelayedSends)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
{
|
|
"success no unrelayed acks",
|
|
func() {
|
|
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
|
|
|
// create acknowledgements for all sequences
|
|
for _, seq := range sequences {
|
|
suite.chainA.App.IBCKeeper.ChannelKeeper.SetPacketAcknowledgement(suite.chainA.GetContext(), channelA.PortID, channelA.ID, seq, []byte("ack"))
|
|
}
|
|
|
|
params = types.NewQueryUnrelayedPacketsParams(channelA.PortID, channelA.ID, sequences, 1, 100)
|
|
|
|
expResSend, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), []uint64{})
|
|
suite.Require().NoError(err)
|
|
|
|
expResAck, err = codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), sequences)
|
|
suite.Require().NoError(err)
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, tc := range testCases {
|
|
suite.SetupTest() // reset
|
|
tc.setup()
|
|
|
|
data, err := suite.chainA.App.AppCodec().MarshalJSON(params)
|
|
suite.Require().NoError(err)
|
|
|
|
query := abci.RequestQuery{
|
|
Path: "",
|
|
Data: data,
|
|
}
|
|
|
|
bz, err := suite.chainA.Querier(suite.chainA.GetContext(), pathAck, query)
|
|
|
|
suite.Require().NoError(err, "test case %d failed: %s", i, tc.name)
|
|
suite.Require().Equal(expResAck, bz, "test case %d failed: %s", i, tc.name)
|
|
|
|
bz, err = suite.chainA.Querier(suite.chainA.GetContext(), pathSend, query)
|
|
|
|
suite.Require().NoError(err, "test case %d failed: %s", i, tc.name)
|
|
suite.Require().Equal(expResSend, bz, "test case %d failed: %s", i, tc.name)
|
|
|
|
}
|
|
|
|
}
|