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 }