github.com/okex/exchain@v1.8.0/libs/ibc-go/modules/core/04-channel/keeper/keeper_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	types2 "github.com/okex/exchain/libs/tendermint/types"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/suite"
     8  
     9  	"github.com/okex/exchain/libs/ibc-go/modules/core/04-channel/types"
    10  	ibctesting "github.com/okex/exchain/libs/ibc-go/testing"
    11  )
    12  
    13  // KeeperTestSuite is a testing suite to test keeper functions.
    14  type KeeperTestSuite struct {
    15  	suite.Suite
    16  
    17  	coordinator *ibctesting.Coordinator
    18  
    19  	// testing chains used for convenience and readability
    20  	chainA ibctesting.TestChainI
    21  	chainB ibctesting.TestChainI
    22  }
    23  
    24  // TestKeeperTestSuite runs all the tests within this package.
    25  func TestKeeperTestSuite(t *testing.T) {
    26  	suite.Run(t, new(KeeperTestSuite))
    27  }
    28  
    29  // SetupTest creates a coordinator with 2 test chains.
    30  func (suite *KeeperTestSuite) SetupTest() {
    31  	types2.UnittestOnlySetMilestoneVenus1Height(-1)
    32  	suite.coordinator = ibctesting.NewCoordinator(suite.T(), 2)
    33  	suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(0))
    34  	suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1))
    35  	// commit some blocks so that QueryProof returns valid proof (cannot return valid query if height <= 1)
    36  	suite.coordinator.CommitNBlocks(suite.chainA, 2)
    37  	suite.coordinator.CommitNBlocks(suite.chainB, 2)
    38  }
    39  
    40  // TestSetChannel create clients and connections on both chains. It tests for the non-existence
    41  // and existence of a channel in INIT on chainA.
    42  func (suite *KeeperTestSuite) TestSetChannel() {
    43  	// create client and connections on both chains
    44  	path := ibctesting.NewPath(suite.chainA, suite.chainB)
    45  	suite.coordinator.SetupConnections(path)
    46  
    47  	// check for channel to be created on chainA
    48  	_, found := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
    49  	suite.False(found)
    50  
    51  	path.SetChannelOrdered()
    52  
    53  	// init channel
    54  	err := path.EndpointA.ChanOpenInit()
    55  	suite.NoError(err)
    56  
    57  	storedChannel, found := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
    58  	// counterparty channel id is empty after open init
    59  	expectedCounterparty := types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, "")
    60  
    61  	suite.True(found)
    62  	suite.Equal(types.INIT, storedChannel.State)
    63  	suite.Equal(types.ORDERED, storedChannel.Ordering)
    64  	suite.Equal(expectedCounterparty, storedChannel.Counterparty)
    65  }
    66  
    67  // TestGetAllChannels creates multiple channels on chain A through various connections
    68  // and tests their retrieval. 2 channels are on connA0 and 1 channel is on connA1
    69  func (suite KeeperTestSuite) TestGetAllChannels() {
    70  	path := ibctesting.NewPath(suite.chainA, suite.chainB)
    71  	suite.coordinator.Setup(path)
    72  	// channel0 on first connection on chainA
    73  	counterparty0 := types.Counterparty{
    74  		PortId:    path.EndpointB.ChannelConfig.PortID,
    75  		ChannelId: path.EndpointB.ChannelID,
    76  	}
    77  
    78  	// path1 creates a second channel on first connection on chainA
    79  	path1 := ibctesting.NewPath(suite.chainA, suite.chainB)
    80  	path1.SetChannelOrdered()
    81  	path1.EndpointA.ClientID = path.EndpointA.ClientID
    82  	path1.EndpointB.ClientID = path.EndpointB.ClientID
    83  	path1.EndpointA.ConnectionID = path.EndpointA.ConnectionID
    84  	path1.EndpointB.ConnectionID = path.EndpointB.ConnectionID
    85  
    86  	suite.coordinator.CreateMockChannels(path1)
    87  	counterparty1 := types.Counterparty{
    88  		PortId:    path1.EndpointB.ChannelConfig.PortID,
    89  		ChannelId: path1.EndpointB.ChannelID,
    90  	}
    91  
    92  	path2 := ibctesting.NewPath(suite.chainA, suite.chainB)
    93  	suite.coordinator.SetupConnections(path2)
    94  
    95  	// path2 creates a second channel on chainA
    96  	err := path2.EndpointA.ChanOpenInit()
    97  	suite.Require().NoError(err)
    98  
    99  	// counterparty channel id is empty after open init
   100  	counterparty2 := types.Counterparty{
   101  		PortId:    path2.EndpointB.ChannelConfig.PortID,
   102  		ChannelId: "",
   103  	}
   104  
   105  	channel0 := types.NewChannel(
   106  		types.OPEN, types.UNORDERED,
   107  		counterparty0, []string{path.EndpointA.ConnectionID}, path.EndpointA.ChannelConfig.Version,
   108  	)
   109  	channel1 := types.NewChannel(
   110  		types.OPEN, types.ORDERED,
   111  		counterparty1, []string{path1.EndpointA.ConnectionID}, path1.EndpointA.ChannelConfig.Version,
   112  	)
   113  	channel2 := types.NewChannel(
   114  		types.INIT, types.UNORDERED,
   115  		counterparty2, []string{path2.EndpointA.ConnectionID}, path2.EndpointA.ChannelConfig.Version,
   116  	)
   117  
   118  	expChannels := []types.IdentifiedChannel{
   119  		types.NewIdentifiedChannel(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel0),
   120  		types.NewIdentifiedChannel(path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, channel1),
   121  		types.NewIdentifiedChannel(path2.EndpointA.ChannelConfig.PortID, path2.EndpointA.ChannelID, channel2),
   122  	}
   123  
   124  	ctxA := suite.chainA.GetContext()
   125  
   126  	channels := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllChannels(ctxA)
   127  	suite.Require().Len(channels, len(expChannels))
   128  	suite.Require().Equal(expChannels, channels)
   129  }
   130  
   131  // TestGetAllSequences sets all packet sequences for two different channels on chain A and
   132  // tests their retrieval.
   133  func (suite KeeperTestSuite) TestGetAllSequences() {
   134  	path := ibctesting.NewPath(suite.chainA, suite.chainB)
   135  	suite.coordinator.Setup(path)
   136  
   137  	path1 := ibctesting.NewPath(suite.chainA, suite.chainB)
   138  	path1.SetChannelOrdered()
   139  	path1.EndpointA.ClientID = path.EndpointA.ClientID
   140  	path1.EndpointB.ClientID = path.EndpointB.ClientID
   141  	path1.EndpointA.ConnectionID = path.EndpointA.ConnectionID
   142  	path1.EndpointB.ConnectionID = path.EndpointB.ConnectionID
   143  
   144  	suite.coordinator.CreateMockChannels(path1)
   145  
   146  	seq1 := types.NewPacketSequence(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1)
   147  	seq2 := types.NewPacketSequence(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 2)
   148  	seq3 := types.NewPacketSequence(path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, 3)
   149  
   150  	// seq1 should be overwritten by seq2
   151  	expSeqs := []types.PacketSequence{seq2, seq3}
   152  
   153  	ctxA := suite.chainA.GetContext()
   154  
   155  	for _, seq := range []types.PacketSequence{seq1, seq2, seq3} {
   156  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceSend(ctxA, seq.PortId, seq.ChannelId, seq.Sequence)
   157  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceRecv(ctxA, seq.PortId, seq.ChannelId, seq.Sequence)
   158  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceAck(ctxA, seq.PortId, seq.ChannelId, seq.Sequence)
   159  	}
   160  
   161  	sendSeqs := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllPacketSendSeqs(ctxA)
   162  	recvSeqs := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllPacketRecvSeqs(ctxA)
   163  	ackSeqs := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllPacketAckSeqs(ctxA)
   164  	suite.Len(sendSeqs, 2)
   165  	suite.Len(recvSeqs, 2)
   166  	suite.Len(ackSeqs, 2)
   167  
   168  	suite.Equal(expSeqs, sendSeqs)
   169  	suite.Equal(expSeqs, recvSeqs)
   170  	suite.Equal(expSeqs, ackSeqs)
   171  }
   172  
   173  // TestGetAllPacketState creates a set of acks, packet commitments, and receipts on two different
   174  // channels on chain A and tests their retrieval.
   175  func (suite KeeperTestSuite) TestGetAllPacketState() {
   176  	path := ibctesting.NewPath(suite.chainA, suite.chainB)
   177  	suite.coordinator.Setup(path)
   178  
   179  	path1 := ibctesting.NewPath(suite.chainA, suite.chainB)
   180  	path1.EndpointA.ClientID = path.EndpointA.ClientID
   181  	path1.EndpointB.ClientID = path.EndpointB.ClientID
   182  	path1.EndpointA.ConnectionID = path.EndpointA.ConnectionID
   183  	path1.EndpointB.ConnectionID = path.EndpointB.ConnectionID
   184  
   185  	suite.coordinator.CreateMockChannels(path1)
   186  
   187  	// channel 0 acks
   188  	ack1 := types.NewPacketState(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1, []byte("ack"))
   189  	ack2 := types.NewPacketState(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 2, []byte("ack"))
   190  
   191  	// duplicate ack
   192  	ack2dup := types.NewPacketState(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 2, []byte("ack"))
   193  
   194  	// channel 1 acks
   195  	ack3 := types.NewPacketState(path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, 1, []byte("ack"))
   196  
   197  	// create channel 0 receipts
   198  	receipt := string([]byte{byte(1)})
   199  	rec1 := types.NewPacketState(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1, []byte(receipt))
   200  	rec2 := types.NewPacketState(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 2, []byte(receipt))
   201  
   202  	// channel 1 receipts
   203  	rec3 := types.NewPacketState(path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, 1, []byte(receipt))
   204  	rec4 := types.NewPacketState(path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, 2, []byte(receipt))
   205  
   206  	// channel 0 packet commitments
   207  	comm1 := types.NewPacketState(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1, []byte("hash"))
   208  	comm2 := types.NewPacketState(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 2, []byte("hash"))
   209  
   210  	// channel 1 packet commitments
   211  	comm3 := types.NewPacketState(path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, 1, []byte("hash"))
   212  	comm4 := types.NewPacketState(path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, 2, []byte("hash"))
   213  
   214  	expAcks := []types.PacketState{ack1, ack2, ack3}
   215  	expReceipts := []types.PacketState{rec1, rec2, rec3, rec4}
   216  	expCommitments := []types.PacketState{comm1, comm2, comm3, comm4}
   217  
   218  	ctxA := suite.chainA.GetContext()
   219  
   220  	// set acknowledgements
   221  	for _, ack := range []types.PacketState{ack1, ack2, ack2dup, ack3} {
   222  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketAcknowledgement(ctxA, ack.PortId, ack.ChannelId, ack.Sequence, ack.Data)
   223  	}
   224  
   225  	// set packet receipts
   226  	for _, rec := range expReceipts {
   227  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketReceipt(ctxA, rec.PortId, rec.ChannelId, rec.Sequence)
   228  	}
   229  
   230  	// set packet commitments
   231  	for _, comm := range expCommitments {
   232  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketCommitment(ctxA, comm.PortId, comm.ChannelId, comm.Sequence, comm.Data)
   233  	}
   234  
   235  	acks := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllPacketAcks(ctxA)
   236  	receipts := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllPacketReceipts(ctxA)
   237  	commitments := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllPacketCommitments(ctxA)
   238  
   239  	suite.Require().Len(acks, len(expAcks))
   240  	suite.Require().Len(commitments, len(expCommitments))
   241  	suite.Require().Len(receipts, len(expReceipts))
   242  
   243  	suite.Require().Equal(expAcks, acks)
   244  	suite.Require().Equal(expReceipts, receipts)
   245  	suite.Require().Equal(expCommitments, commitments)
   246  }
   247  
   248  // TestSetSequence verifies that the keeper correctly sets the sequence counters.
   249  func (suite *KeeperTestSuite) TestSetSequence() {
   250  	path := ibctesting.NewPath(suite.chainA, suite.chainB)
   251  	suite.coordinator.Setup(path)
   252  
   253  	ctxA := suite.chainA.GetContext()
   254  	one := uint64(1)
   255  
   256  	// initialized channel has next send seq of 1
   257  	seq, found := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceSend(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   258  	suite.True(found)
   259  	suite.Equal(one, seq)
   260  
   261  	// initialized channel has next seq recv of 1
   262  	seq, found = suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceRecv(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   263  	suite.True(found)
   264  	suite.Equal(one, seq)
   265  
   266  	// initialized channel has next seq ack of
   267  	seq, found = suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceAck(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   268  	suite.True(found)
   269  	suite.Equal(one, seq)
   270  
   271  	nextSeqSend, nextSeqRecv, nextSeqAck := uint64(10), uint64(10), uint64(10)
   272  	suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceSend(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, nextSeqSend)
   273  	suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceRecv(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, nextSeqRecv)
   274  	suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceAck(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, nextSeqAck)
   275  
   276  	storedNextSeqSend, found := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceSend(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   277  	suite.True(found)
   278  	suite.Equal(nextSeqSend, storedNextSeqSend)
   279  
   280  	storedNextSeqRecv, found := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceSend(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   281  	suite.True(found)
   282  	suite.Equal(nextSeqRecv, storedNextSeqRecv)
   283  
   284  	storedNextSeqAck, found := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceAck(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   285  	suite.True(found)
   286  	suite.Equal(nextSeqAck, storedNextSeqAck)
   287  }
   288  
   289  // TestGetAllPacketCommitmentsAtChannel verifies that the keeper returns all stored packet
   290  // commitments for a specific channel. The test will store consecutive commitments up to the
   291  // value of "seq" and then add non-consecutive up to the value of "maxSeq". A final commitment
   292  // with the value maxSeq + 1 is set on a different channel.
   293  func (suite *KeeperTestSuite) TestGetAllPacketCommitmentsAtChannel() {
   294  	path := ibctesting.NewPath(suite.chainA, suite.chainB)
   295  	suite.coordinator.Setup(path)
   296  
   297  	// create second channel
   298  	path1 := ibctesting.NewPath(suite.chainA, suite.chainB)
   299  	path1.SetChannelOrdered()
   300  	path1.EndpointA.ClientID = path.EndpointA.ClientID
   301  	path1.EndpointB.ClientID = path.EndpointB.ClientID
   302  	path1.EndpointA.ConnectionID = path.EndpointA.ConnectionID
   303  	path1.EndpointB.ConnectionID = path.EndpointB.ConnectionID
   304  
   305  	suite.coordinator.CreateMockChannels(path1)
   306  
   307  	ctxA := suite.chainA.GetContext()
   308  	expectedSeqs := make(map[uint64]bool)
   309  	hash := []byte("commitment")
   310  
   311  	seq := uint64(15)
   312  	maxSeq := uint64(25)
   313  	suite.Require().Greater(maxSeq, seq)
   314  
   315  	// create consecutive commitments
   316  	for i := uint64(1); i < seq; i++ {
   317  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketCommitment(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, i, hash)
   318  		expectedSeqs[i] = true
   319  	}
   320  
   321  	// add non-consecutive commitments
   322  	for i := seq; i < maxSeq; i += 2 {
   323  		suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketCommitment(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, i, hash)
   324  		expectedSeqs[i] = true
   325  	}
   326  
   327  	// add sequence on different channel/port
   328  	suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketCommitment(ctxA, path1.EndpointA.ChannelConfig.PortID, path1.EndpointA.ChannelID, maxSeq+1, hash)
   329  
   330  	commitments := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetAllPacketCommitmentsAtChannel(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   331  
   332  	suite.Equal(len(expectedSeqs), len(commitments))
   333  	// ensure above for loops occurred
   334  	suite.NotEqual(0, len(commitments))
   335  
   336  	// verify that all the packet commitments were stored
   337  	for _, packet := range commitments {
   338  		suite.True(expectedSeqs[packet.Sequence])
   339  		suite.Equal(path.EndpointA.ChannelConfig.PortID, packet.PortId)
   340  		suite.Equal(path.EndpointA.ChannelID, packet.ChannelId)
   341  		suite.Equal(hash, packet.Data)
   342  
   343  		// prevent duplicates from passing checks
   344  		expectedSeqs[packet.Sequence] = false
   345  	}
   346  }
   347  
   348  // TestSetPacketAcknowledgement verifies that packet acknowledgements are correctly
   349  // set in the keeper.
   350  func (suite *KeeperTestSuite) TestSetPacketAcknowledgement() {
   351  	path := ibctesting.NewPath(suite.chainA, suite.chainB)
   352  	suite.coordinator.Setup(path)
   353  
   354  	ctxA := suite.chainA.GetContext()
   355  	seq := uint64(10)
   356  
   357  	storedAckHash, found := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetPacketAcknowledgement(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, seq)
   358  	suite.Require().False(found)
   359  	suite.Require().Nil(storedAckHash)
   360  
   361  	ackHash := []byte("ackhash")
   362  	suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketAcknowledgement(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, seq, ackHash)
   363  
   364  	storedAckHash, found = suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetPacketAcknowledgement(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, seq)
   365  	suite.Require().True(found)
   366  	suite.Require().Equal(ackHash, storedAckHash)
   367  	suite.Require().True(suite.chainA.App().GetIBCKeeper().ChannelKeeper.HasPacketAcknowledgement(ctxA, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, seq))
   368  }