github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types"
     5  	icatypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/types"
     6  	channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types"
     7  	host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
     8  	ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing"
     9  )
    10  
    11  func (suite *KeeperTestSuite) TestOnChanOpenInit() {
    12  	var (
    13  		channel  *channeltypes.Channel
    14  		path     *ibctesting.Path
    15  		chanCap  *capabilitytypes.Capability
    16  		metadata icatypes.Metadata
    17  	)
    18  
    19  	testCases := []struct {
    20  		name     string
    21  		malleate func()
    22  		expPass  bool
    23  	}{
    24  		{
    25  			"success",
    26  			func() {
    27  				path.EndpointA.SetChannel(*channel)
    28  			},
    29  			true,
    30  		},
    31  		{
    32  			"success: previous active channel closed",
    33  			func() {
    34  				suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
    35  
    36  				counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)
    37  				channel := channeltypes.Channel{
    38  					State:          channeltypes.CLOSED,
    39  					Ordering:       channeltypes.ORDERED,
    40  					Counterparty:   counterparty,
    41  					ConnectionHops: []string{path.EndpointA.ConnectionID},
    42  					Version:        TestVersion,
    43  				}
    44  
    45  				path.EndpointA.SetChannel(channel)
    46  			},
    47  			true,
    48  		},
    49  		{
    50  			"success: empty channel version returns default metadata JSON string",
    51  			func() {
    52  				channel.Version = ""
    53  			},
    54  			true,
    55  		},
    56  		{
    57  			"invalid metadata -  previous metadata is different",
    58  			func() {
    59  				// set active channel to closed
    60  				suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
    61  
    62  				counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)
    63  				closedChannel := channeltypes.Channel{
    64  					State:          channeltypes.CLOSED,
    65  					Ordering:       channeltypes.ORDERED,
    66  					Counterparty:   counterparty,
    67  					ConnectionHops: []string{path.EndpointA.ConnectionID},
    68  					Version:        TestVersion,
    69  				}
    70  
    71  				path.EndpointA.SetChannel(closedChannel)
    72  
    73  				// modify metadata
    74  				metadata.Version = "ics27-2"
    75  
    76  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
    77  				suite.Require().NoError(err)
    78  
    79  				channel.Version = string(versionBytes)
    80  			},
    81  			false,
    82  		},
    83  		{
    84  			"invalid order - UNORDERED",
    85  			func() {
    86  				channel.Ordering = channeltypes.UNORDERED
    87  			},
    88  			false,
    89  		},
    90  		{
    91  			"invalid port ID",
    92  			func() {
    93  				path.EndpointA.ChannelConfig.PortID = "invalid-port-id"
    94  			},
    95  			false,
    96  		},
    97  		{
    98  			"invalid counterparty port ID",
    99  			func() {
   100  				path.EndpointA.SetChannel(*channel)
   101  				channel.Counterparty.PortId = "invalid-port-id"
   102  			},
   103  			false,
   104  		},
   105  		{
   106  			"invalid metadata bytestring",
   107  			func() {
   108  				path.EndpointA.SetChannel(*channel)
   109  				channel.Version = "invalid-metadata-bytestring"
   110  			},
   111  			false,
   112  		},
   113  		{
   114  			"unsupported encoding format",
   115  			func() {
   116  				metadata.Encoding = "invalid-encoding-format"
   117  
   118  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   119  				suite.Require().NoError(err)
   120  
   121  				channel.Version = string(versionBytes)
   122  				path.EndpointA.SetChannel(*channel)
   123  			},
   124  			false,
   125  		},
   126  		{
   127  			"unsupported transaction type",
   128  			func() {
   129  				metadata.TxType = "invalid-tx-types"
   130  
   131  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   132  				suite.Require().NoError(err)
   133  
   134  				channel.Version = string(versionBytes)
   135  				path.EndpointA.SetChannel(*channel)
   136  			},
   137  			false,
   138  		},
   139  		{
   140  			"connection not found",
   141  			func() {
   142  				channel.ConnectionHops = []string{"invalid-connnection-id"}
   143  				path.EndpointA.SetChannel(*channel)
   144  			},
   145  			false,
   146  		},
   147  		{
   148  			"connection not found with default empty channel version",
   149  			func() {
   150  				channel.ConnectionHops = []string{"connection-10"}
   151  				channel.Version = ""
   152  			},
   153  			false,
   154  		},
   155  		{
   156  			"invalid controller connection ID",
   157  			func() {
   158  				metadata.ControllerConnectionId = "invalid-connnection-id"
   159  
   160  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   161  				suite.Require().NoError(err)
   162  
   163  				channel.Version = string(versionBytes)
   164  				path.EndpointA.SetChannel(*channel)
   165  			},
   166  			false,
   167  		},
   168  		{
   169  			"invalid host connection ID",
   170  			func() {
   171  				metadata.HostConnectionId = "invalid-connnection-id"
   172  
   173  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   174  				suite.Require().NoError(err)
   175  
   176  				channel.Version = string(versionBytes)
   177  				path.EndpointA.SetChannel(*channel)
   178  			},
   179  			false,
   180  		},
   181  		{
   182  			"invalid version",
   183  			func() {
   184  				metadata.Version = "invalid-version"
   185  
   186  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   187  				suite.Require().NoError(err)
   188  
   189  				channel.Version = string(versionBytes)
   190  				path.EndpointA.SetChannel(*channel)
   191  			},
   192  			false,
   193  		},
   194  		{
   195  			"channel is already active",
   196  			func() {
   197  				suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   198  
   199  				counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)
   200  				channel := channeltypes.Channel{
   201  					State:          channeltypes.OPEN,
   202  					Ordering:       channeltypes.ORDERED,
   203  					Counterparty:   counterparty,
   204  					ConnectionHops: []string{path.EndpointA.ConnectionID},
   205  					Version:        TestVersion,
   206  				}
   207  				suite.chainA.GetSimApp().IBCKeeper.V2Keeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel)
   208  			},
   209  			false,
   210  		},
   211  	}
   212  
   213  	for _, tc := range testCases {
   214  		tc := tc
   215  
   216  		suite.Run(tc.name, func() {
   217  			suite.SetupTest() // reset
   218  
   219  			path = NewICAPath(suite.chainA, suite.chainB)
   220  			suite.coordinator.SetupConnections(path)
   221  
   222  			// mock init interchain account
   223  			portID, err := icatypes.NewControllerPortID(TestOwnerAddress)
   224  			suite.Require().NoError(err)
   225  
   226  			portCap := suite.chainA.GetSimApp().IBCKeeper.V2Keeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID)
   227  			suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID))
   228  			path.EndpointA.ChannelConfig.PortID = portID
   229  
   230  			// default values
   231  			metadata = icatypes.NewMetadata(icatypes.Version, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID, "", icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg)
   232  			versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   233  			suite.Require().NoError(err)
   234  
   235  			counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)
   236  			channel = &channeltypes.Channel{
   237  				State:          channeltypes.INIT,
   238  				Ordering:       channeltypes.ORDERED,
   239  				Counterparty:   counterparty,
   240  				ConnectionHops: []string{path.EndpointA.ConnectionID},
   241  				Version:        string(versionBytes),
   242  			}
   243  
   244  			chanCap, err = suite.chainA.GetSimApp().GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID))
   245  			suite.Require().NoError(err)
   246  
   247  			tc.malleate() // malleate mutates test data
   248  
   249  			version, err := suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
   250  				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.Version,
   251  			)
   252  
   253  			if tc.expPass {
   254  				suite.Require().NoError(err)
   255  				suite.Require().Equal(string(versionBytes), version)
   256  			} else {
   257  				suite.Require().Error(err)
   258  			}
   259  		})
   260  	}
   261  }
   262  
   263  func (suite *KeeperTestSuite) TestOnChanOpenAck() {
   264  	var (
   265  		path     *ibctesting.Path
   266  		metadata icatypes.Metadata
   267  	)
   268  
   269  	testCases := []struct {
   270  		name     string
   271  		malleate func()
   272  		expPass  bool
   273  	}{
   274  		{
   275  			"success", func() {}, true,
   276  		},
   277  		{
   278  			"invalid port ID - host chain",
   279  			func() {
   280  				path.EndpointA.ChannelConfig.PortID = icatypes.PortID
   281  			},
   282  			false,
   283  		},
   284  		{
   285  			"invalid port ID - unexpected prefix",
   286  			func() {
   287  				path.EndpointA.ChannelConfig.PortID = "invalid-port-id"
   288  			},
   289  			false,
   290  		},
   291  		{
   292  			"invalid metadata bytestring",
   293  			func() {
   294  				path.EndpointA.Counterparty.ChannelConfig.Version = "invalid-metadata-bytestring"
   295  			},
   296  			false,
   297  		},
   298  		{
   299  			"unsupported encoding format",
   300  			func() {
   301  				metadata.Encoding = "invalid-encoding-format"
   302  
   303  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   304  				suite.Require().NoError(err)
   305  
   306  				path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes)
   307  			},
   308  			false,
   309  		},
   310  		{
   311  			"unsupported transaction type",
   312  			func() {
   313  				metadata.TxType = "invalid-tx-types"
   314  
   315  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   316  				suite.Require().NoError(err)
   317  
   318  				path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes)
   319  			},
   320  			false,
   321  		},
   322  		{
   323  			"invalid account address",
   324  			func() {
   325  				metadata.Address = "invalid-account-address"
   326  
   327  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   328  				suite.Require().NoError(err)
   329  
   330  				path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes)
   331  			},
   332  			false,
   333  		},
   334  		{
   335  			"empty account address",
   336  			func() {
   337  				metadata.Address = ""
   338  
   339  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   340  				suite.Require().NoError(err)
   341  
   342  				path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes)
   343  			},
   344  			false,
   345  		},
   346  		{
   347  			"invalid counterparty version",
   348  			func() {
   349  				metadata.Version = "invalid-version"
   350  
   351  				versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   352  				suite.Require().NoError(err)
   353  
   354  				path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes)
   355  			},
   356  			false,
   357  		},
   358  		{
   359  			"active channel already set",
   360  			func() {
   361  				// create a new channel and set it in state
   362  				ch := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, ibctesting.DefaultChannelVersion)
   363  				suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ch)
   364  
   365  				// set the active channelID in state
   366  				suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   367  			}, false,
   368  		},
   369  	}
   370  
   371  	for _, tc := range testCases {
   372  		tc := tc
   373  
   374  		suite.Run(tc.name, func() {
   375  			suite.SetupTest() // reset
   376  
   377  			path = NewICAPath(suite.chainA, suite.chainB)
   378  			suite.coordinator.SetupConnections(path)
   379  
   380  			err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress)
   381  			suite.Require().NoError(err)
   382  
   383  			err = path.EndpointB.ChanOpenTry()
   384  			suite.Require().NoError(err)
   385  
   386  			metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, TestAccAddress.String(), icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg)
   387  			versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata)
   388  			suite.Require().NoError(err)
   389  
   390  			path.EndpointB.ChannelConfig.Version = string(versionBytes)
   391  
   392  			tc.malleate() // malleate mutates test data
   393  
   394  			err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenAck(suite.chainA.GetContext(),
   395  				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointA.Counterparty.ChannelConfig.Version,
   396  			)
   397  
   398  			if tc.expPass {
   399  				suite.Require().NoError(err)
   400  
   401  				activeChannelID, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID)
   402  				suite.Require().True(found)
   403  
   404  				suite.Require().Equal(path.EndpointA.ChannelID, activeChannelID)
   405  
   406  				interchainAccAddress, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID)
   407  				suite.Require().True(found)
   408  
   409  				suite.Require().Equal(metadata.Address, interchainAccAddress)
   410  			} else {
   411  				suite.Require().Error(err)
   412  			}
   413  		})
   414  	}
   415  }
   416  
   417  func (suite *KeeperTestSuite) TestOnChanCloseConfirm() {
   418  	var path *ibctesting.Path
   419  
   420  	testCases := []struct {
   421  		name     string
   422  		malleate func()
   423  		expPass  bool
   424  	}{
   425  		{
   426  			"success", func() {}, true,
   427  		},
   428  	}
   429  
   430  	for _, tc := range testCases {
   431  		suite.Run(tc.name, func() {
   432  			suite.SetupTest() // reset
   433  
   434  			path = NewICAPath(suite.chainA, suite.chainB)
   435  			suite.coordinator.SetupConnections(path)
   436  
   437  			err := SetupICAPath(path, TestOwnerAddress)
   438  			suite.Require().NoError(err)
   439  
   440  			tc.malleate() // malleate mutates test data
   441  
   442  			err = suite.chainB.GetSimApp().ICAControllerKeeper.OnChanCloseConfirm(suite.chainB.GetContext(),
   443  				path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)
   444  
   445  			activeChannelID, found := suite.chainB.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointB.ChannelConfig.PortID)
   446  
   447  			if tc.expPass {
   448  				suite.Require().NoError(err)
   449  				suite.Require().False(found)
   450  				suite.Require().Empty(activeChannelID)
   451  			} else {
   452  				suite.Require().Error(err)
   453  			}
   454  		})
   455  	}
   456  }