Skip to content

Commit

Permalink
E2E Test: TestMsgPayPacketFeeSingleSenderTimesOut (#1751)
Browse files Browse the repository at this point in the history
  • Loading branch information
chatton authored Jul 27, 2022
1 parent 85893ee commit 214e4a3
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 1 deletion.
122 changes: 121 additions & 1 deletion e2e/fee_middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package e2e
import (
"context"
"testing"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/strangelove-ventures/ibctest/broadcast"
Expand Down Expand Up @@ -79,7 +80,7 @@ func (s *FeeMiddlewareTestSuite) QueryIncentivizedPacketsForChannel(
return res.IncentivizedPackets, err
}

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

Expand Down Expand Up @@ -309,6 +310,125 @@ func (s *FeeMiddlewareTestSuite) TestMultiMsg_MsgPayPacketFeeSingleSender() {
})
}

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

relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, feeMiddlewareChannelOptions())
chainA, chainB := s.GetChains()

var (
chainADenom = chainA.Config().Denom
testFee = testvalues.DefaultFee(chainADenom)
chainATx ibc.Tx
payPacketFeeTxResp sdk.TxResponse
)

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

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

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

_, chainBRelayerUser := s.GetRelayerUsers(ctx)

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

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)
})

chainBWalletAmount := ibc.WalletAmount{
Address: chainBWallet.Bech32Address(chainB.Config().Bech32Prefix), // destination address
Denom: chainA.Config().Denom,
Amount: testvalues.IBCTransferAmount,
}

t.Run("Send IBC transfer", func(t *testing.T) {
chainATx, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName, chainBWalletAmount, testvalues.ImmediatelyTimeout())
s.Require().NoError(err)
s.Require().NoError(chainATx.Validate(), "source ibc transfer tx is invalid")
time.Sleep(time.Nanosecond * 1) // want it to timeout immediately
})

t.Run("tokens are escrowed", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)

expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount
s.Require().Equal(expected, actualBalance)
})

t.Run("pay packet fee", func(t *testing.T) {

packetId := channeltypes.NewPacketId(channelA.PortID, channelA.ChannelID, 1)
packetFee := feetypes.NewPacketFee(testFee, chainAWallet.Bech32Address(chainA.Config().Bech32Prefix), nil)

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)
})

t.Run("should succeed", func(t *testing.T) {
payPacketFeeTxResp, err = s.PayPacketFeeAsync(ctx, chainA, chainAWallet, packetId, packetFee)
s.Require().NoError(err)
s.AssertValidTxResponse(payPacketFeeTxResp)
})

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)

expected := testvalues.StartingTokenAmount - chainBWalletAmount.Amount - 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("recv and ack should be refunded", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)

expected := testvalues.StartingTokenAmount - testFee.TimeoutFee.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
8 changes: 8 additions & 0 deletions e2e/testvalues/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package testvalues

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/strangelove-ventures/ibctest/ibc"

feetypes "github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"
)
Expand All @@ -11,6 +12,13 @@ const (
IBCTransferAmount int64 = 10_000
)

// ImmediatelyTimeout returns an ibc.IBCTimeout which will cause an IBC transfer to timeout immediately.
func ImmediatelyTimeout() *ibc.IBCTimeout {
return &ibc.IBCTimeout{
NanoSeconds: 1,
}
}

func DefaultFee(denom string) feetypes.Fee {
return feetypes.Fee{
RecvFee: sdk.NewCoins(sdk.NewCoin(denom, sdk.NewInt(50))),
Expand Down

0 comments on commit 214e4a3

Please sign in to comment.