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

     1  package keeper_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	types2 "github.com/fibonacci-chain/fbc/libs/tendermint/types"
     7  
     8  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     9  	icatypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/types"
    10  	channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types"
    11  	ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing"
    12  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    13  	"github.com/stretchr/testify/suite"
    14  )
    15  
    16  var (
    17  	// TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module()
    18  	// https://github.com/cosmos/cosmos-sdk/issues/10225
    19  	//
    20  	// TestAccAddress defines a resuable bech32 address for testing purposes
    21  	TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), ibctesting.FirstConnectionID, TestPortID)
    22  
    23  	// TestOwnerAddress defines a reusable bech32 address for testing purposes
    24  	TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs"
    25  
    26  	// TestPortID defines a resuable port identifier for testing purposes
    27  	TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress)
    28  
    29  	// TestVersion defines a resuable interchainaccounts version string for testing purposes
    30  	TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{
    31  		Version:                icatypes.Version,
    32  		ControllerConnectionId: ibctesting.FirstConnectionID,
    33  		HostConnectionId:       ibctesting.FirstConnectionID,
    34  		Encoding:               icatypes.EncodingProtobuf,
    35  		TxType:                 icatypes.TxTypeSDKMultiMsg,
    36  	}))
    37  )
    38  
    39  type KeeperTestSuite struct {
    40  	suite.Suite
    41  
    42  	coordinator *ibctesting.Coordinator
    43  
    44  	// testing chains used for convenience and readability
    45  	chainA ibctesting.TestChainI
    46  	chainB ibctesting.TestChainI
    47  	chainC ibctesting.TestChainI
    48  }
    49  
    50  func (suite *KeeperTestSuite) SetupTest() {
    51  	types2.UnittestOnlySetMilestoneVenus1Height(-1)
    52  	types2.UnittestOnlySetMilestoneVenus4Height(-1)
    53  	suite.coordinator = ibctesting.NewCoordinator(suite.T(), 3)
    54  	suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(0))
    55  	suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1))
    56  	suite.chainC = suite.coordinator.GetChain(ibctesting.GetChainID(2))
    57  }
    58  
    59  func NewICAPath(chainA, chainB ibctesting.TestChainI) *ibctesting.Path {
    60  	path := ibctesting.NewPath(chainA, chainB)
    61  	path.EndpointA.ChannelConfig.PortID = icatypes.PortID
    62  	path.EndpointB.ChannelConfig.PortID = icatypes.PortID
    63  	path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED
    64  	path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED
    65  	path.EndpointA.ChannelConfig.Version = TestVersion
    66  	path.EndpointB.ChannelConfig.Version = TestVersion
    67  
    68  	return path
    69  }
    70  
    71  // SetupICAPath invokes the InterchainAccounts entrypoint and subsequent channel handshake handlers
    72  func SetupICAPath(path *ibctesting.Path, owner string) error {
    73  	if err := RegisterInterchainAccount(path.EndpointA, owner); err != nil {
    74  		return err
    75  	}
    76  
    77  	if err := path.EndpointB.ChanOpenTry(); err != nil {
    78  		return err
    79  	}
    80  
    81  	if err := path.EndpointA.ChanOpenAck(); err != nil {
    82  		return err
    83  	}
    84  
    85  	if err := path.EndpointB.ChanOpenConfirm(); err != nil {
    86  		return err
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  // RegisterInterchainAccount is a helper function for starting the channel handshake
    93  func RegisterInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error {
    94  	portID, err := icatypes.NewControllerPortID(owner)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	channelSequence := endpoint.Chain.GetSimApp().GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext())
   100  
   101  	if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.RegisterInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner, TestVersion); err != nil {
   102  		return err
   103  	}
   104  
   105  	// commit state changes for proof verification
   106  	endpoint.Chain.Coordinator().CommitBlock(endpoint.Chain)
   107  
   108  	// update port/channel ids
   109  	endpoint.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence)
   110  	endpoint.ChannelConfig.PortID = portID
   111  
   112  	return nil
   113  }
   114  
   115  func TestKeeperTestSuite(t *testing.T) {
   116  	suite.Run(t, new(KeeperTestSuite))
   117  }
   118  
   119  func (suite *KeeperTestSuite) TestIsBound() {
   120  	suite.SetupTest()
   121  
   122  	path := NewICAPath(suite.chainA, suite.chainB)
   123  	suite.coordinator.SetupConnections(path)
   124  
   125  	err := SetupICAPath(path, TestOwnerAddress)
   126  	suite.Require().NoError(err)
   127  
   128  	isBound := suite.chainA.GetSimApp().ICAControllerKeeper.IsBound(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID)
   129  	suite.Require().True(isBound)
   130  }
   131  
   132  func (suite *KeeperTestSuite) TestGetAllPorts() {
   133  	suite.SetupTest()
   134  
   135  	path := NewICAPath(suite.chainA, suite.chainB)
   136  	suite.coordinator.SetupConnections(path)
   137  
   138  	err := SetupICAPath(path, TestOwnerAddress)
   139  	suite.Require().NoError(err)
   140  
   141  	expectedPorts := []string{TestPortID}
   142  
   143  	ports := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllPorts(suite.chainA.GetContext())
   144  	suite.Require().Len(ports, len(expectedPorts))
   145  	suite.Require().Equal(expectedPorts, ports)
   146  }
   147  
   148  func (suite *KeeperTestSuite) TestGetInterchainAccountAddress() {
   149  	suite.SetupTest()
   150  
   151  	path := NewICAPath(suite.chainA, suite.chainB)
   152  	suite.coordinator.SetupConnections(path)
   153  
   154  	err := SetupICAPath(path, TestOwnerAddress)
   155  	suite.Require().NoError(err)
   156  
   157  	counterpartyPortID := path.EndpointA.ChannelConfig.PortID
   158  	expectedAddr := icatypes.GenerateAddress(suite.chainA.GetSimApp().SupplyKeeper.GetModuleAddress(icatypes.ModuleName), ibctesting.FirstConnectionID, counterpartyPortID)
   159  
   160  	retrievedAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, counterpartyPortID)
   161  	suite.Require().True(found)
   162  	suite.Require().Equal(expectedAddr.String(), retrievedAddr)
   163  
   164  	retrievedAddr, found = suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), "invalid conn", "invalid port")
   165  	suite.Require().False(found)
   166  	suite.Require().Empty(retrievedAddr)
   167  }
   168  
   169  func (suite *KeeperTestSuite) TestGetAllActiveChannels() {
   170  	var (
   171  		expectedChannelID string = "test-channel"
   172  		expectedPortID    string = "test-port"
   173  	)
   174  
   175  	suite.SetupTest()
   176  
   177  	path := NewICAPath(suite.chainA, suite.chainB)
   178  	suite.coordinator.SetupConnections(path)
   179  
   180  	err := SetupICAPath(path, TestOwnerAddress)
   181  	suite.Require().NoError(err)
   182  
   183  	suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedChannelID)
   184  
   185  	expectedChannels := []icatypes.ActiveChannel{
   186  		{
   187  			ConnectionId: ibctesting.FirstConnectionID,
   188  			PortId:       TestPortID,
   189  			ChannelId:    path.EndpointA.ChannelID,
   190  		},
   191  		{
   192  			ConnectionId: ibctesting.FirstConnectionID,
   193  			PortId:       expectedPortID,
   194  			ChannelId:    expectedChannelID,
   195  		},
   196  	}
   197  
   198  	activeChannels := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllActiveChannels(suite.chainA.GetContext())
   199  	suite.Require().Len(activeChannels, len(expectedChannels))
   200  	suite.Require().Equal(expectedChannels, activeChannels)
   201  }
   202  
   203  func (suite *KeeperTestSuite) TestGetAllInterchainAccounts() {
   204  	var (
   205  		expectedAccAddr string = "test-acc-addr"
   206  		expectedPortID  string = "test-port"
   207  	)
   208  
   209  	suite.SetupTest()
   210  
   211  	path := NewICAPath(suite.chainA, suite.chainB)
   212  	suite.coordinator.SetupConnections(path)
   213  
   214  	err := SetupICAPath(path, TestOwnerAddress)
   215  	suite.Require().NoError(err)
   216  
   217  	suite.chainA.GetSimApp().ICAControllerKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr)
   218  
   219  	expectedAccounts := []icatypes.RegisteredInterchainAccount{
   220  		{
   221  			ConnectionId:   ibctesting.FirstConnectionID,
   222  			PortId:         TestPortID,
   223  			AccountAddress: TestAccAddress.String(),
   224  		},
   225  		{
   226  			ConnectionId:   ibctesting.FirstConnectionID,
   227  			PortId:         expectedPortID,
   228  			AccountAddress: expectedAccAddr,
   229  		},
   230  	}
   231  
   232  	interchainAccounts := suite.chainA.GetSimApp().ICAControllerKeeper.GetAllInterchainAccounts(suite.chainA.GetContext())
   233  	suite.Require().Len(interchainAccounts, len(expectedAccounts))
   234  	suite.Require().Equal(expectedAccounts, interchainAccounts)
   235  }
   236  
   237  func (suite *KeeperTestSuite) TestIsActiveChannel() {
   238  	suite.SetupTest()
   239  
   240  	path := NewICAPath(suite.chainA, suite.chainB)
   241  	owner := TestOwnerAddress
   242  	suite.coordinator.SetupConnections(path)
   243  
   244  	err := SetupICAPath(path, owner)
   245  	suite.Require().NoError(err)
   246  	portID := path.EndpointA.ChannelConfig.PortID
   247  
   248  	isActive := suite.chainA.GetSimApp().ICAControllerKeeper.IsActiveChannel(suite.chainA.GetContext(), ibctesting.FirstConnectionID, portID)
   249  	suite.Require().Equal(isActive, true)
   250  }
   251  
   252  func (suite *KeeperTestSuite) TestSetInterchainAccountAddress() {
   253  	var (
   254  		expectedAccAddr string = "test-acc-addr"
   255  		expectedPortID  string = "test-port"
   256  	)
   257  
   258  	suite.chainA.GetSimApp().ICAControllerKeeper.SetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID, expectedAccAddr)
   259  
   260  	retrievedAddr, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, expectedPortID)
   261  	suite.Require().True(found)
   262  	suite.Require().Equal(expectedAccAddr, retrievedAddr)
   263  }