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

test: Add tests for OnTimeoutPacket when middle chain times out packet #6596

Merged
merged 36 commits into from
Jun 19, 2024
Merged
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
013f883
Create ontimeoutpacket test for forwarding
bznein Jun 13, 2024
83f4582
Propagate ack on A
bznein Jun 13, 2024
59b93ed
Refactoring
bznein Jun 13, 2024
ff35ada
Minor changes
bznein Jun 13, 2024
926d8da
Added comments
bznein Jun 13, 2024
8a3dd36
Merge branch 'feat/ics20-v2-path-forwarding' into bznein/6384/ontimeo…
bznein Jun 13, 2024
3f5dc6c
Fix type name.
bznein Jun 14, 2024
10592e1
Gofumpt
bznein Jun 14, 2024
907de8e
Merge branch 'feat/ics20-v2-path-forwarding' into bznein/6384/ontimeo…
bznein Jun 14, 2024
6787c74
Update modules/apps/transfer/keeper/relay_forwarding_test.go
bznein Jun 14, 2024
37375ba
Update modules/apps/transfer/keeper/relay_forwarding_test.go
bznein Jun 14, 2024
65a0d0a
Update modules/apps/transfer/keeper/relay_forwarding_test.go
bznein Jun 14, 2024
ca59adf
Update modules/apps/transfer/keeper/relay_forwarding_test.go
bznein Jun 14, 2024
1492378
Add godoc to test.
bznein Jun 14, 2024
288f5f6
Changed trace construction
bznein Jun 14, 2024
d4e9b59
Merge branch 'feat/ics20-v2-path-forwarding' into bznein/6384/ontimeo…
bznein Jun 17, 2024
a70e56d
Update modules/apps/transfer/keeper/relay_forwarding_test.go
bznein Jun 17, 2024
6a33a57
remove error msg parameter from helper function
bznein Jun 14, 2024
7fb5569
Add test for forwarded packet
bznein Jun 17, 2024
774d971
Merge branch 'feat/ics20-v2-path-forwarding' into bznein/6384/ontimeo…
bznein Jun 17, 2024
ad4e6f6
Construct packet for B ack check.
bznein Jun 18, 2024
3acd732
Merge branch 'feat/ics20-v2-path-forwarding' into bznein/6384/ontimeo…
bznein Jun 18, 2024
139facf
PR feedback
bznein Jun 18, 2024
0670659
chore(transfer): make Forwarding non-null (#6618)
DimitrisJim Jun 18, 2024
745e4be
chore: restructure functions with logical ordering (#6638)
damiannolan Jun 18, 2024
b8e36ec
chore(deps): bump bufbuild/buf-setup-action from 1.32.2 to 1.33.0 (#6…
dependabot[bot] Jun 16, 2024
6dabf17
chore: fix spelling errors (#6603)
jgscr Jun 16, 2024
ede7ea6
chore: mergify for v7.6.x (#6611)
crodriguezvega Jun 17, 2024
56ec67e
chore(deps): bump github.com/spf13/cobra from 1.8.0 to 1.8.1 (#6615)
dependabot[bot] Jun 17, 2024
bb4024a
Update adr-015-ibc-packet-receiver.md (#6620)
lido333 Jun 17, 2024
3729544
chore(deps): bump docker/build-push-action from 5.4.0 to 6.0.0 (#6617)
dependabot[bot] Jun 17, 2024
d02c4cc
tests(e2e): ics20 v2 multidenom (#6290)
crodriguezvega Jun 17, 2024
d9d30f8
fix comments (#6628)
winniehere Jun 18, 2024
0aee2d3
revert the mess I made
bznein Jun 18, 2024
c095d35
Change forwarding to non-pointer
bznein Jun 18, 2024
1c5decb
Merge branch 'feat/ics20-v2-path-forwarding' into bznein/6384/ontimeo…
bznein Jun 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions modules/apps/transfer/keeper/relay_forwarding_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package keeper_test

import (
"errors"
"fmt"
"time"

sdkmath "cosmossdk.io/math"

Expand Down Expand Up @@ -609,3 +611,178 @@ Test async ack is properly relayed to middle hop after forwarding transfer compl
// TODO
Tiemout during forwarding after middle hop execution reverts properly the state changes
*/

func (suite *KeeperTestSuite) setupForwardingPaths() (pathAtoB, pathBtoC *ibctesting.Path) {
pathAtoB = ibctesting.NewTransferPath(suite.chainA, suite.chainB)
pathBtoC = ibctesting.NewTransferPath(suite.chainB, suite.chainC)
pathAtoB.Setup()
pathBtoC.Setup()
return pathAtoB, pathBtoC
}

type amountType int

const (
escrow amountType = iota
balance
)

func (suite *KeeperTestSuite) assertAmountOnChain(chain *ibctesting.TestChain, balanceType amountType, amount sdkmath.Int, denom string) {
var total sdk.Coin
switch balanceType {
case escrow:
total = chain.GetSimApp().TransferKeeper.GetTotalEscrowForDenom(chain.GetContext(), denom)
case balance:
total = chain.GetSimApp().BankKeeper.GetBalance(chain.GetContext(), chain.SenderAccounts[0].SenderAccount.GetAddress(), denom)
default:
suite.Fail("invalid amountType %s", balanceType)
}
suite.Require().Equal(amount, total.Amount, fmt.Sprintf("Chain %s: got balance of %d, wanted %d", chain.Name(), total.Amount, amount))
}

// TestOnTimeoutPacketForwarding tests the scenario in which a packet goes from
// A to C, using B as a forwarding hop. The packet times out when going to C
// from B and we verify that funds are properly returned to A.
func (suite *KeeperTestSuite) TestOnTimeoutPacketForwarding() {
DimitrisJim marked this conversation as resolved.
Show resolved Hide resolved
pathAtoB, pathBtoC := suite.setupForwardingPaths()

amount := sdkmath.NewInt(100)
coin := sdk.NewCoin(sdk.DefaultBondDenom, amount)
sender := suite.chainA.SenderAccounts[0].SenderAccount
receiver := suite.chainC.SenderAccounts[0].SenderAccount

denomA := types.NewDenom(coin.Denom)
denomAB := types.NewDenom(coin.Denom, types.NewTrace(pathAtoB.EndpointB.ChannelConfig.PortID, pathAtoB.EndpointB.ChannelID))
denomABC := types.NewDenom(coin.Denom, append(denomAB.Trace, types.NewTrace(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID))...)

originalABalance := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), sender.GetAddress(), coin.Denom)

forwarding := types.Forwarding{
Hops: []types.Hop{
{
PortId: pathBtoC.EndpointA.ChannelConfig.PortID,
ChannelId: pathBtoC.EndpointA.ChannelID,
},
},
}

transferMsg := types.NewMsgTransfer(
pathAtoB.EndpointA.ChannelConfig.PortID,
pathAtoB.EndpointA.ChannelID,
sdk.NewCoins(coin),
sender.GetAddress().String(),
receiver.GetAddress().String(),
clienttypes.ZeroHeight(),
uint64(suite.chainA.GetContext().BlockTime().Add(time.Minute*5).UnixNano()),
"",
forwarding,
)

result, err := suite.chainA.SendMsgs(transferMsg)
suite.Require().NoError(err) // message committed

// parse the packet from result events and recv packet on chainB
packet, err := ibctesting.ParsePacketFromEvents(result.Events)
suite.Require().NoError(err)
suite.Require().NotNil(packet)

err = pathAtoB.EndpointB.UpdateClient()
suite.Require().NoError(err)

// Receive packet on B.
result, err = pathAtoB.EndpointB.RecvPacketWithResult(packet)
suite.Require().NoError(err)
suite.Require().NotNil(result)
colin-axner marked this conversation as resolved.
Show resolved Hide resolved

err = pathBtoC.EndpointA.UpdateClient()
suite.Require().NoError(err)

err = pathBtoC.EndpointB.UpdateClient()
suite.Require().NoError(err)

// Make sure funds went from A to B's escrow account.
suite.assertAmountOnChain(suite.chainA, balance, originalABalance.Amount.Sub(amount), denomA.IBCDenom())
suite.assertAmountOnChain(suite.chainB, escrow, amount, denomAB.IBCDenom())

// Check that forwarded packet exists
forwardedPacket, found := suite.chainB.GetSimApp().TransferKeeper.GetForwardedPacket(suite.chainB.GetContext(), pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, packet.Sequence)
suite.Require().True(found, "Chain B has no forwarded packet")
suite.Require().Equal(packet, forwardedPacket, "ForwardedPacket stored in ChainB is not the same that was sent")

crodriguezvega marked this conversation as resolved.
Show resolved Hide resolved
address := types.GetForwardAddress(packet.DestinationPort, packet.DestinationChannel).String()
data := types.NewFungibleTokenPacketDataV2(
[]types.Token{
{
Denom: types.NewDenom(sdk.DefaultBondDenom, types.NewTrace(pathAtoB.EndpointA.ChannelConfig.PortID, pathAtoB.EndpointA.ChannelID)),
Amount: "100",
},
},
address,
receiver.GetAddress().String(),
"", types.Forwarding{},
)

packet = channeltypes.NewPacket(
data.GetBytes(),
1,
pathBtoC.EndpointA.ChannelConfig.PortID,
pathBtoC.EndpointA.ChannelID,
pathBtoC.EndpointB.ChannelConfig.PortID,
pathBtoC.EndpointB.ChannelID,
crodriguezvega marked this conversation as resolved.
Show resolved Hide resolved
packet.TimeoutHeight,
packet.TimeoutTimestamp)

// retrieve module callbacks
module, _, err := suite.chainB.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainB.GetContext(), pathBtoC.EndpointA.ChannelConfig.PortID)
suite.Require().NoError(err)

cbs, ok := suite.chainB.App.GetIBCKeeper().PortKeeper.Route(module)
suite.Require().True(ok)

// Trigger OnTimeoutPacket for chainB
err = cbs.OnTimeoutPacket(suite.chainB.GetContext(), packet, nil)
suite.Require().NoError(err)

// Ensure that chainB has an ack.
storedAck, found := suite.chainB.App.GetIBCKeeper().ChannelKeeper.GetPacketAcknowledgement(suite.chainB.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
suite.Require().True(found, "chainB does not have an ack")

// And that this ack is of the type we expect (Error due to time out)
ack := channeltypes.NewErrorAcknowledgement(errors.New("forwarded packet timed out"))
ackbytes := channeltypes.CommitAcknowledgement(ack.Acknowledgement())
suite.Require().Equal(ackbytes, storedAck)

data = types.NewFungibleTokenPacketDataV2(
[]types.Token{
{
Denom: types.NewDenom(sdk.DefaultBondDenom),
Amount: "100",
},
},
sender.GetAddress().String(),
receiver.GetAddress().String(),
"", forwarding,
)

packet = channeltypes.NewPacket(
data.GetBytes(),
1,
pathAtoB.EndpointA.ChannelConfig.PortID,
pathAtoB.EndpointA.ChannelID,
pathAtoB.EndpointB.ChannelConfig.PortID,
pathAtoB.EndpointB.ChannelID,
packet.TimeoutHeight,
packet.TimeoutTimestamp)

// Send the ack to chain A.
err = suite.chainA.GetSimApp().TransferKeeper.OnAcknowledgementPacket(suite.chainA.GetContext(), packet, data, ack)
suite.Require().NoError(err)

// Finally, check that A,B, and C escrow accounts do not have fund.
suite.assertAmountOnChain(suite.chainC, escrow, sdkmath.NewInt(0), denomABC.IBCDenom())
suite.assertAmountOnChain(suite.chainB, escrow, sdkmath.NewInt(0), denomAB.IBCDenom())
suite.assertAmountOnChain(suite.chainA, escrow, sdkmath.NewInt(0), denomA.IBCDenom())

// And that A has its original balance back.
suite.assertAmountOnChain(suite.chainA, balance, originalABalance.Amount, coin.Denom)
}
Loading