Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2E Test: TestMsgPayPacketFeeSingleSender #1756

Merged
merged 10 commits into from
Jul 21, 2022
105 changes: 105 additions & 0 deletions e2e/fee_middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"e2e/testvalues"

feetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"
transfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
)

Expand Down Expand Up @@ -198,6 +200,109 @@ func (s *FeeMiddlewareTestSuite) TestMsgPayPacketFeeAsyncSingleSender() {
})
}

func (s *FeeMiddlewareTestSuite) TestMultiMsg_MsgPayPacketFeeSingleSender() {
t := s.T()
ctx := context.TODO()

relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions())
_ = relayer

chainA, chainB := s.GetChains()

var (
chainADenom = chainA.Config().Denom
testFee = testvalues.DefaultFee(chainADenom)
multiMsgTxResponse sdk.TxResponse
)

transferAmount := testvalues.DefaultTransferAmount(chainA.Config().Denom)

chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)
chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount)

t.Run("relayer wallets recovered", func(t *testing.T) {
err := s.RecoverRelayerWallets(ctx, relayer)
s.Require().NoError(err)
})

chainARelayerWallet, chainBRelayerWallet, err := s.GetRelayerWallets(relayer)
t.Run("relayer wallets fetched", func(t *testing.T) {
s.Require().NoError(err)
})

s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")

_, chainBRelayerUser := s.GetRelayerUsers(ctx)

t.Run("register counter party payee", func(t *testing.T) {
multiMsgTxResponse, err = s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.Address, chainARelayerWallet.Address)
s.Require().NoError(err)
s.AssertValidTxResponse(multiMsgTxResponse)
})

t.Run("verify counter party payee", func(t *testing.T) {
address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.Address, channelA.Counterparty.ChannelID)
s.Require().NoError(err)
s.Require().Equal(chainARelayerWallet.Address, address)
})

t.Run("no incentivized packets", func(t *testing.T) {
packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)
s.Require().Empty(packets)
})

payPacketFeeMsg := feetypes.NewMsgPayPacketFee(testFee, channelA.PortID, channelA.ChannelID, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), nil)
transferMsg := transfertypes.NewMsgTransfer(channelA.PortID, channelA.ChannelID, transferAmount, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), chainBWallet.Bech32Address(chainB.Config().Bech32Prefix), clienttypes.NewHeight(1, 1000), 0)
resp, err := s.BroadcastMessages(ctx, chainA, chainAWallet, payPacketFeeMsg, transferMsg)

t.Run("transfer successful", func(t *testing.T) {
s.AssertValidTxResponse(resp)
s.Require().NoError(err)
})

t.Run("there should be incentivized packets", func(t *testing.T) {
packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)
s.Require().Len(packets, 1)
actualFee := packets[0].PacketFees[0].Fee

s.Require().True(actualFee.RecvFee.IsEqual(testFee.RecvFee))
s.Require().True(actualFee.AckFee.IsEqual(testFee.AckFee))
s.Require().True(actualFee.TimeoutFee.IsEqual(testFee.TimeoutFee))
})

t.Run("balance should be lowered by sum of recv ack and timeout", func(t *testing.T) {
// The balance should be lowered by the sum of the recv, ack and timeout fees.
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)

gasFees := chainA.GetGasFeesInNativeDenom(multiMsgTxResponse.GasWanted)
expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount - gasFees - testFee.Total().AmountOf(chainADenom).Int64()
s.Require().Equal(expected, actualBalance)
})

t.Run("start relayer", func(t *testing.T) {
s.StartRelayer(relayer)
})

t.Run("packets are relayed", func(t *testing.T) {
packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)
s.Require().Empty(packets)
})

t.Run("timeout fee is refunded", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)

gasFees := chainA.GetGasFeesInNativeDenom(multiMsgTxResponse.GasWanted)
// once the relayer has relayed the packets, the timeout fee should be refunded.
expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount - gasFees - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64()
s.Require().Equal(expected, actualBalance)
})
}

// feeMiddlewareChannelOptions configures both of the chains to have fee middleware enabled.
func feeMiddlewareChannelOptions() func(options *ibc.CreateChannelOptions) {
return func(opts *ibc.CreateChannelOptions) {
Expand Down
4 changes: 4 additions & 0 deletions e2e/testvalues/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ func DefaultFee(denom string) feetypes.Fee {
TimeoutFee: sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(10))),
}
}

func DefaultTransferAmount(denom string) sdk.Coin {
return sdk.Coin{Denom: denom, Amount: sdk.NewInt(IBCTransferAmount)}
}