github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/apps/29-fee/keeper/msg_server_test.go (about) 1 package keeper_test 2 3 import ( 4 "fmt" 5 6 ibcmock "github.com/fibonacci-chain/fbc/libs/ibc-go/testing/mock" 7 8 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 9 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/29-fee/types" 10 transfertypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/transfer/types" 11 clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 12 channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 13 ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing" 14 ) 15 16 func (suite *KeeperTestSuite) TestRegisterPayee() { 17 var msg *types.MsgRegisterPayee 18 19 testCases := []struct { 20 name string 21 expPass bool 22 malleate func() 23 }{ 24 { 25 "success", 26 true, 27 func() {}, 28 }, 29 { 30 "channel does not exist", 31 false, 32 func() { 33 msg.ChannelId = "channel-100" 34 }, 35 }, 36 { 37 "channel is not fee enabled", 38 false, 39 func() { 40 suite.chainA.GetSimApp().IBCFeeKeeper.DeleteFeeEnabled(suite.chainA.GetContext(), suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID) 41 }, 42 }, 43 { 44 "given payee is not an sdk address", 45 false, 46 func() { 47 msg.Payee = "invalid-addr" 48 }, 49 }, 50 { 51 "payee is a blocked address", 52 false, 53 func() { 54 msg.Payee = suite.chainA.GetSimApp().SupplyKeeper.GetModuleAddress(transfertypes.ModuleName).String() 55 }, 56 }, 57 } 58 59 for _, tc := range testCases { 60 suite.SetupTest() 61 suite.coordinator.Setup(suite.path) 62 63 msg = types.NewMsgRegisterPayee( 64 suite.path.EndpointA.ChannelConfig.PortID, 65 suite.path.EndpointA.ChannelID, 66 suite.chainA.SenderAccounts()[0].SenderAccount.GetAddress().String(), 67 suite.chainA.SenderAccounts()[1].SenderAccount.GetAddress().String(), 68 ) 69 70 tc.malleate() 71 72 res, err := suite.chainA.GetSimApp().IBCFeeKeeper.RegisterPayee(sdk.WrapSDKContext(suite.chainA.GetContext()), msg) 73 74 if tc.expPass { 75 suite.Require().NoError(err) 76 suite.Require().NotNil(res) 77 78 payeeAddr, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetPayeeAddress( 79 suite.chainA.GetContext(), 80 suite.chainA.SenderAccounts()[0].SenderAccount.GetAddress().String(), 81 suite.path.EndpointA.ChannelID, 82 ) 83 84 suite.Require().True(found) 85 suite.Require().Equal(suite.chainA.SenderAccounts()[1].SenderAccount.GetAddress().String(), payeeAddr) 86 } else { 87 suite.Require().Error(err) 88 } 89 } 90 } 91 92 func (suite *KeeperTestSuite) TestRegisterCounterpartyPayee() { 93 var ( 94 msg *types.MsgRegisterCounterpartyPayee 95 expCounterpartyPayee string 96 ) 97 98 testCases := []struct { 99 name string 100 expPass bool 101 malleate func() 102 }{ 103 { 104 "success", 105 true, 106 func() {}, 107 }, 108 { 109 "counterparty payee is an arbitrary string", 110 true, 111 func() { 112 msg.CounterpartyPayee = "arbitrary-string" 113 expCounterpartyPayee = "arbitrary-string" 114 }, 115 }, 116 { 117 "channel does not exist", 118 false, 119 func() { 120 msg.ChannelId = "channel-100" 121 }, 122 }, 123 { 124 "channel is not fee enabled", 125 false, 126 func() { 127 suite.chainA.GetSimApp().IBCFeeKeeper.DeleteFeeEnabled(suite.chainA.GetContext(), suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID) 128 }, 129 }, 130 } 131 132 for _, tc := range testCases { 133 suite.SetupTest() 134 suite.coordinator.Setup(suite.path) // setup channel 135 136 expCounterpartyPayee = suite.chainA.SenderAccounts()[1].SenderAccount.GetAddress().String() 137 msg = types.NewMsgRegisterCounterpartyPayee( 138 suite.path.EndpointA.ChannelConfig.PortID, 139 suite.path.EndpointA.ChannelID, 140 suite.chainA.SenderAccounts()[0].SenderAccount.GetAddress().String(), 141 expCounterpartyPayee, 142 ) 143 144 tc.malleate() 145 146 res, err := suite.chainA.GetSimApp().IBCFeeKeeper.RegisterCounterpartyPayee(sdk.WrapSDKContext(suite.chainA.GetContext()), msg) 147 148 if tc.expPass { 149 suite.Require().NoError(err) 150 suite.Require().NotNil(res) 151 152 counterpartyPayee, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetCounterpartyPayeeAddress( 153 suite.chainA.GetContext(), 154 suite.chainA.SenderAccounts()[0].SenderAccount.GetAddress().String(), 155 ibctesting.FirstChannelID, 156 ) 157 158 suite.Require().True(found) 159 suite.Require().Equal(expCounterpartyPayee, counterpartyPayee) 160 } else { 161 suite.Require().Error(err) 162 } 163 } 164 } 165 166 func (suite *KeeperTestSuite) TestPayPacketFee() { 167 var ( 168 expEscrowBalance sdk.Coins 169 expFeesInEscrow []types.PacketFee 170 msg *types.MsgPayPacketFee 171 fee types.Fee 172 ) 173 174 testCases := []struct { 175 name string 176 malleate func() 177 expPass bool 178 }{ 179 //{ 180 // "success", 181 // func() {}, 182 // true, 183 //}, 184 //{ 185 // "success with existing packet fees in escrow", 186 // func() { 187 // fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) 188 // 189 // packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) 190 // packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount().GetAddress().String(), nil) 191 // feesInEscrow := types.NewPacketFees([]types.PacketFee{packetFee}) 192 // 193 // suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), packetID, feesInEscrow) 194 // err := suite.chainA.GetSimApp().SupplyKeeper.SendCoinsFromAccountToModule(suite.chainA.GetContext(), suite.chainA.SenderAccount().GetAddress(), types.ModuleName, fee.Total().ToCoins()) 195 // suite.Require().NoError(err) 196 // 197 // expEscrowBalance = expEscrowBalance.Add(fee.Total().ToCoins()...) 198 // expFeesInEscrow = append(expFeesInEscrow, packetFee) 199 // }, 200 // true, 201 //}, 202 { 203 "refund account is module account", 204 func() { 205 msg.Signer = suite.chainA.GetSimApp().SupplyKeeper.GetModuleAddress(ibcmock.ModuleName).String() 206 addr := suite.chainA.GetSimApp().SupplyKeeper.GetModuleAccount(suite.chainA.GetContext(), ibcmock.ModuleName) 207 suite.chainA.GetSimApp().SupplyKeeper.SendCoins(suite.chainA.GetContext(), suite.chainA.SenderAccount().GetAddress(), addr.GetAddress(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)))) 208 expPacketFee := types.NewPacketFee(fee, msg.Signer, nil) 209 expFeesInEscrow = []types.PacketFee{expPacketFee} 210 }, 211 true, 212 }, 213 { 214 "fee module is locked", 215 func() { 216 lockFeeModule(suite.chainA) 217 }, 218 false, 219 }, 220 { 221 "fee module disabled on channel", 222 func() { 223 msg.SourcePortId = "invalid-port" 224 msg.SourceChannelId = "invalid-channel" 225 }, 226 false, 227 }, 228 { 229 "invalid refund address", 230 func() { 231 msg.Signer = "invalid-address" 232 }, 233 false, 234 }, 235 { 236 "refund account does not exist", 237 func() { 238 msg.Signer = suite.chainB.SenderAccount().GetAddress().String() 239 }, 240 false, 241 }, 242 { 243 "refund account is a blocked address", 244 func() { 245 blockedAddr := suite.chainA.GetSimApp().SupplyKeeper.GetModuleAccount(suite.chainA.GetContext(), transfertypes.ModuleName).GetAddress() 246 msg.Signer = blockedAddr.String() 247 }, 248 false, 249 }, 250 { 251 "acknowledgement fee balance not found", 252 func() { 253 msg.Fee.AckFee = invalidCoinsNotExist 254 }, 255 false, 256 }, 257 { 258 "receive fee balance not found", 259 func() { 260 msg.Fee.RecvFee = invalidCoinsNotExist 261 }, 262 false, 263 }, 264 { 265 "timeout fee balance not found", 266 func() { 267 msg.Fee.TimeoutFee = invalidCoinsNotExist 268 }, 269 false, 270 }, 271 } 272 273 for _, tc := range testCases { 274 tc := tc 275 276 suite.Run(tc.name, func() { 277 suite.SetupTest() 278 suite.coordinator.Setup(suite.path) // setup channel 279 280 fee = types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) 281 msg = types.NewMsgPayPacketFee( 282 fee, 283 suite.path.EndpointA.ChannelConfig.PortID, 284 suite.path.EndpointA.ChannelID, 285 suite.chainA.SenderAccount().GetAddress().String(), 286 nil, 287 ) 288 289 expEscrowBalance = fee.Total().ToCoins() 290 expPacketFee := types.NewPacketFee(fee, suite.chainA.SenderAccount().GetAddress().String(), nil) 291 expFeesInEscrow = []types.PacketFee{expPacketFee} 292 293 tc.malleate() 294 295 _, err := suite.chainA.GetSimApp().IBCFeeKeeper.PayPacketFee(sdk.WrapSDKContext(suite.chainA.GetContext()), msg) 296 297 if tc.expPass { 298 suite.Require().NoError(err) // message committed 299 300 packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) 301 feesInEscrow, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) 302 suite.Require().True(found) 303 suite.Require().Equal(expFeesInEscrow, feesInEscrow.PacketFees) 304 305 escrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.GetSimApp().IBCFeeKeeper.GetFeeModuleAddress(), sdk.DefaultBondDenom) 306 suite.Require().Equal(expEscrowBalance.AmountOf(sdk.DefaultBondDenom), escrowBalance.Amount) 307 } else { 308 suite.Require().Error(err) 309 310 escrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.GetSimApp().IBCFeeKeeper.GetFeeModuleAddress(), sdk.DefaultBondDenom) 311 suite.Require().Equal(sdk.NewInt(0), escrowBalance.Amount.TruncateInt()) 312 } 313 }) 314 } 315 } 316 317 func (suite *KeeperTestSuite) TestPayPacketFeeAsync() { 318 var ( 319 packet channeltypes.Packet 320 expEscrowBalance sdk.CoinAdapters 321 expFeesInEscrow []types.PacketFee 322 msg *types.MsgPayPacketFeeAsync 323 ) 324 325 testCases := []struct { 326 name string 327 malleate func() 328 expPass bool 329 }{ 330 { 331 "success", 332 func() {}, 333 true, 334 }, 335 { 336 "success with existing packet fees in escrow", 337 func() { 338 fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) 339 340 packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) 341 packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount().GetAddress().String(), nil) 342 feesInEscrow := types.NewPacketFees([]types.PacketFee{packetFee}) 343 344 suite.chainA.GetSimApp().IBCFeeKeeper.SetFeesInEscrow(suite.chainA.GetContext(), packetID, feesInEscrow) 345 err := suite.chainA.GetSimApp().SupplyKeeper.SendCoinsFromAccountToModule(suite.chainA.GetContext(), suite.chainA.SenderAccount().GetAddress(), types.ModuleName, fee.Total().ToCoins()) 346 suite.Require().NoError(err) 347 348 expEscrowBalance = expEscrowBalance.Add(fee.Total()...) 349 expFeesInEscrow = append(expFeesInEscrow, packetFee) 350 }, 351 true, 352 }, 353 { 354 "fee module is locked", 355 func() { 356 lockFeeModule(suite.chainA) 357 }, 358 false, 359 }, 360 { 361 "fee module disabled on channel", 362 func() { 363 msg.PacketId.PortId = "invalid-port" 364 msg.PacketId.ChannelId = "invalid-channel" 365 }, 366 false, 367 }, 368 { 369 "channel does not exist", 370 func() { 371 msg.PacketId.ChannelId = "channel-100" 372 373 // to test this functionality, we must set the fee to enabled for this non existent channel 374 // NOTE: the channel doesn't exist in 04-channel keeper, but we will add a mapping within ics29 anyways 375 suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), msg.PacketId.PortId, msg.PacketId.ChannelId) 376 }, 377 false, 378 }, 379 { 380 "packet not sent", 381 func() { 382 msg.PacketId.Sequence = msg.PacketId.Sequence + 1 383 }, 384 false, 385 }, 386 { 387 "packet already acknowledged", 388 func() { 389 err := suite.path.RelayPacketV4(packet) 390 suite.Require().NoError(err) 391 }, 392 false, 393 }, 394 { 395 "packet already timed out", 396 func() { 397 // try to incentivze a packet which is timed out 398 packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, msg.PacketId.Sequence+1) 399 packet = channeltypes.NewPacket(ibctesting.MockPacketData, packetID.Sequence, packetID.PortId, packetID.ChannelId, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), 0) 400 401 err := suite.path.EndpointA.SendPacket(packet) 402 suite.Require().NoError(err) 403 404 // need to update chainA's client representing chainB to prove missing ack 405 err = suite.path.EndpointA.UpdateClient() 406 suite.Require().NoError(err) 407 408 err = suite.path.EndpointA.TimeoutPacket(packet) 409 suite.Require().NoError(err) 410 411 msg.PacketId = packetID 412 }, 413 false, 414 }, 415 { 416 "invalid refund address", 417 func() { 418 msg.PacketFee.RefundAddress = "invalid-address" 419 }, 420 false, 421 }, 422 { 423 "refund account does not exist", 424 func() { 425 msg.PacketFee.RefundAddress = suite.chainB.SenderAccount().GetAddress().String() 426 }, 427 false, 428 }, 429 { 430 "refund account is a blocked address", 431 func() { 432 blockedAddr := suite.chainA.GetSimApp().SupplyKeeper.GetModuleAccount(suite.chainA.GetContext(), transfertypes.ModuleName).GetAddress() 433 msg.PacketFee.RefundAddress = blockedAddr.String() 434 }, 435 false, 436 }, 437 { 438 "acknowledgement fee balance not found", 439 func() { 440 msg.PacketFee.Fee.AckFee = invalidCoinsNotExist 441 }, 442 false, 443 }, 444 { 445 "receive fee balance not found", 446 func() { 447 msg.PacketFee.Fee.RecvFee = invalidCoinsNotExist 448 }, 449 false, 450 }, 451 { 452 "timeout fee balance not found", 453 func() { 454 msg.PacketFee.Fee.TimeoutFee = invalidCoinsNotExist 455 }, 456 false, 457 }, 458 } 459 460 for _, tc := range testCases { 461 tc := tc 462 463 suite.Run(tc.name, func() { 464 suite.SetupTest() 465 suite.coordinator.Setup(suite.path) // setup channel 466 467 // send a packet to incentivize 468 packetID := channeltypes.NewPacketId(suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, 1) 469 packet = channeltypes.NewPacket(ibctesting.MockPacketData, packetID.Sequence, packetID.PortId, packetID.ChannelId, suite.path.EndpointB.ChannelConfig.PortID, suite.path.EndpointB.ChannelID, clienttypes.NewHeight(clienttypes.ParseChainID(suite.chainB.ChainID()), 100), 0) 470 err := suite.path.EndpointA.SendPacket(packet) 471 suite.Require().NoError(err) 472 473 fee := types.NewFee(defaultRecvFee, defaultAckFee, defaultTimeoutFee) 474 packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount().GetAddress().String(), nil) 475 476 expEscrowBalance = fee.Total() 477 expFeesInEscrow = []types.PacketFee{packetFee} 478 msg = types.NewMsgPayPacketFeeAsync(packetID, packetFee) 479 480 tc.malleate() 481 482 _, err = suite.chainA.GetSimApp().IBCFeeKeeper.PayPacketFeeAsync(sdk.WrapSDKContext(suite.chainA.GetContext()), msg) 483 484 if tc.expPass { 485 suite.Require().NoError(err) // message committed 486 487 feesInEscrow, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetFeesInEscrow(suite.chainA.GetContext(), packetID) 488 suite.Require().True(found) 489 suite.Require().Equal(expFeesInEscrow, feesInEscrow.PacketFees) 490 491 escrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.GetSimApp().IBCFeeKeeper.GetFeeModuleAddress(), sdk.DefaultBondDenom) 492 suite.Require().Equal(expEscrowBalance.ToCoins().AmountOf(sdk.DefaultBondDenom), escrowBalance.Amount) 493 } else { 494 suite.Require().Error(err) 495 496 escrowBalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.GetSimApp().IBCFeeKeeper.GetFeeModuleAddress(), sdk.DefaultBondDenom) 497 fmt.Println(escrowBalance.String()) 498 suite.Require().Equal(sdk.NewInt(0), escrowBalance.Amount.TruncateInt()) 499 } 500 }) 501 } 502 }