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