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 arbitrary passthrough fix #678

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
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
79 changes: 55 additions & 24 deletions examples/ibc/packet_forward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import (
"time"

"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/types/bech32"
transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"github.com/strangelove-ventures/interchaintest/v8/relayer"
"github.com/strangelove-ventures/interchaintest/v8/relayer/rly"
"github.com/strangelove-ventures/interchaintest/v8/testreporter"
"github.com/strangelove-ventures/interchaintest/v8/testutil"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -46,10 +49,10 @@ func TestPacketForwardMiddleware(t *testing.T) {
chainID_A, chainID_B, chainID_C, chainID_D := "chain-a", "chain-b", "chain-c", "chain-d"

cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{
{Name: "gaia", Version: "v9.0.1", ChainConfig: ibc.ChainConfig{ChainID: chainID_A, GasPrices: "0.0uatom"}},
{Name: "gaia", Version: "v9.0.1", ChainConfig: ibc.ChainConfig{ChainID: chainID_B, GasPrices: "0.0uatom"}},
{Name: "gaia", Version: "v9.0.1", ChainConfig: ibc.ChainConfig{ChainID: chainID_C, GasPrices: "0.0uatom"}},
{Name: "gaia", Version: "v9.0.1", ChainConfig: ibc.ChainConfig{ChainID: chainID_D, GasPrices: "0.0uatom"}},
{Name: "juno", Version: "andrew-pfm_arbitrary_passthrough", ChainConfig: ibc.ChainConfig{ChainID: chainID_A, GasPrices: "0.0ujuno"}},
{Name: "juno", Version: "andrew-pfm_arbitrary_passthrough", ChainConfig: ibc.ChainConfig{ChainID: chainID_B, GasPrices: "0.0ujuno"}},
{Name: "juno", Version: "andrew-pfm_arbitrary_passthrough", ChainConfig: ibc.ChainConfig{ChainID: chainID_C, GasPrices: "0.0ujuno"}},
{Name: "juno", Version: "andrew-pfm_arbitrary_passthrough", ChainConfig: ibc.ChainConfig{ChainID: chainID_D, GasPrices: "0.0ujuno"}},
})

chains, err := cf.Chains(t.Name())
Expand All @@ -60,6 +63,7 @@ func TestPacketForwardMiddleware(t *testing.T) {
r := interchaintest.NewBuiltinRelayerFactory(
ibc.CosmosRly,
zaptest.NewLogger(t),
relayer.CustomDockerImage(rly.DefaultContainerImage, "main", rly.RlyDefaultUidGid),
).Build(t, client, network)

const pathAB = "ab"
Expand Down Expand Up @@ -137,6 +141,10 @@ func TestPacketForwardMiddleware(t *testing.T) {
// Get original account balances
userA, userB, userC, userD := users[0], users[1], users[2], users[3]

const intermediateAddr = "pfm" // can be anything, just needs to be non-empty to pass validation for SendPacket.
var transferAmount math.Int = math.NewInt(100000)
var zeroBal = math.ZeroInt()

// Compose the prefixed denoms and ibc denom for asserting balances
firstHopDenom := transfertypes.GetPrefixedDenom(baChan.PortID, baChan.ChannelID, chainA.Config().Denom)
secondHopDenom := transfertypes.GetPrefixedDenom(cbChan.PortID, cbChan.ChannelID, firstHopDenom)
Expand All @@ -150,17 +158,24 @@ func TestPacketForwardMiddleware(t *testing.T) {
secondHopIBCDenom := secondHopDenomTrace.IBCDenom()
thirdHopIBCDenom := thirdHopDenomTrace.IBCDenom()

firstHopEscrowAccount := transfertypes.GetEscrowAddress(abChan.PortID, abChan.ChannelID).String()
secondHopEscrowAccount := transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID).String()
thirdHopEscrowAccount := transfertypes.GetEscrowAddress(cdChan.PortID, abChan.ChannelID).String()
firstHopEscrow := transfertypes.GetEscrowAddress(abChan.PortID, abChan.ChannelID)
firstHopEscrowAccount, err := bech32.ConvertAndEncode(chainA.Config().Bech32Prefix, firstHopEscrow.Bytes())
require.NoError(t, err)

zeroBal := math.ZeroInt()
transferAmount := math.NewInt(100_000)
secondHopEscrow := transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID)
secondHopEscrowAccount, err := bech32.ConvertAndEncode(chainB.Config().Bech32Prefix, secondHopEscrow.Bytes())
require.NoError(t, err)

thirdHopEscrow := transfertypes.GetEscrowAddress(cdChan.PortID, cdChan.ChannelID)
thirdHopEscrowAccount, err := bech32.ConvertAndEncode(chainC.Config().Bech32Prefix, thirdHopEscrow.Bytes())
require.NoError(t, err)

// transferAmount := math.NewInt(100_000)

t.Run("multi-hop a->b->c->d", func(t *testing.T) {
// Send packet from Chain A->Chain B->Chain C->Chain D
transfer := ibc.WalletAmount{
Address: userB.FormattedAddress(),
Address: intermediateAddr, // userB.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Denom: chainA.Config().Denom,
Amount: transferAmount,
}
Expand All @@ -178,7 +193,7 @@ func TestPacketForwardMiddleware(t *testing.T) {

firstHopMetadata := &PacketMetadata{
Forward: &ForwardMetadata{
Receiver: userC.FormattedAddress(),
Receiver: intermediateAddr, // userC.FormattedAddress(), // Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Channel: bcChan.ChannelID,
Port: bcChan.PortID,
Next: &next,
Expand Down Expand Up @@ -232,7 +247,7 @@ func TestPacketForwardMiddleware(t *testing.T) {
t.Run("multi-hop denom unwind d->c->b->a", func(t *testing.T) {
// Send packet back from Chain D->Chain C->Chain B->Chain A
transfer := ibc.WalletAmount{
Address: userC.FormattedAddress(),
Address: intermediateAddr, // userC.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Denom: thirdHopIBCDenom,
Amount: transferAmount,
}
Expand All @@ -252,7 +267,7 @@ func TestPacketForwardMiddleware(t *testing.T) {

firstHopMetadata := &PacketMetadata{
Forward: &ForwardMetadata{
Receiver: userB.FormattedAddress(),
Receiver: intermediateAddr, // userB.FormattedAddress(), // Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Channel: cbChan.ChannelID,
Port: cbChan.PortID,
Next: &next,
Expand Down Expand Up @@ -309,7 +324,7 @@ func TestPacketForwardMiddleware(t *testing.T) {
// Send a malformed packet with invalid receiver address from Chain A->Chain B->Chain C
// This should succeed in the first hop and fail to make the second hop; funds should then be refunded to Chain A.
transfer := ibc.WalletAmount{
Address: userB.FormattedAddress(),
Address: intermediateAddr, // userB.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Denom: chainA.Config().Denom,
Amount: transferAmount,
}
Expand Down Expand Up @@ -363,7 +378,7 @@ func TestPacketForwardMiddleware(t *testing.T) {
t.Run("forward timeout refund", func(t *testing.T) {
// Send packet from Chain A->Chain B->Chain C with the timeout so low for B->C transfer that it can not make it from B to C, which should result in a refund from B to A after two retries.
transfer := ibc.WalletAmount{
Address: userB.FormattedAddress(),
Address: intermediateAddr, // userB.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Denom: chainA.Config().Denom,
Amount: transferAmount,
}
Expand Down Expand Up @@ -421,7 +436,7 @@ func TestPacketForwardMiddleware(t *testing.T) {
// This should succeed in the first hop and second hop, then fail to make the third hop.
// Funds should be refunded to Chain B and then to Chain A via acknowledgements with errors.
transfer := ibc.WalletAmount{
Address: userB.FormattedAddress(),
Address: intermediateAddr, // userB.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Denom: chainA.Config().Denom,
Amount: transferAmount,
}
Expand All @@ -441,7 +456,7 @@ func TestPacketForwardMiddleware(t *testing.T) {

firstHopMetadata := &PacketMetadata{
Forward: &ForwardMetadata{
Receiver: userC.FormattedAddress(),
Receiver: intermediateAddr, // userC.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Channel: bcChan.ChannelID,
Port: bcChan.PortID,
Next: &next,
Expand Down Expand Up @@ -531,7 +546,11 @@ func TestPacketForwardMiddleware(t *testing.T) {
chainABalance, err := chainA.GetBalance(ctx, userA.FormattedAddress(), baIBCDenom)
require.NoError(t, err)

baEscrowBalance, err := chainB.GetBalance(ctx, transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID).String(), chainB.Config().Denom)
baEscrow := transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID)
baEscrowAccount, err := bech32.ConvertAndEncode(chainB.Config().Bech32Prefix, baEscrow.Bytes())
require.NoError(t, err)

baEscrowBalance, err := chainB.GetBalance(ctx, baEscrowAccount, chainB.Config().Denom)
require.NoError(t, err)

require.True(t, chainABalance.Equal(transferAmount))
Expand All @@ -541,7 +560,7 @@ func TestPacketForwardMiddleware(t *testing.T) {
// This should succeed in the first hop and second hop, then fail to make the third hop.
// Funds should be refunded to Chain B and then to Chain A via acknowledgements with errors.
transfer = ibc.WalletAmount{
Address: userB.FormattedAddress(),
Address: intermediateAddr, //userB.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Denom: baIBCDenom,
Amount: transferAmount,
}
Expand All @@ -561,7 +580,7 @@ func TestPacketForwardMiddleware(t *testing.T) {

firstHopMetadata := &PacketMetadata{
Forward: &ForwardMetadata{
Receiver: userC.FormattedAddress(),
Receiver: intermediateAddr, // userC.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Channel: bcChan.ChannelID,
Port: bcChan.PortID,
Next: &next,
Expand Down Expand Up @@ -599,14 +618,26 @@ func TestPacketForwardMiddleware(t *testing.T) {
require.True(t, chainCBalance.Equal(zeroBal))
require.True(t, chainDBalance.Equal(zeroBal))

cdEscrow := transfertypes.GetEscrowAddress(cdChan.PortID, cdChan.ChannelID)
cdEscrowAccount, err := bech32.ConvertAndEncode(chainC.Config().Bech32Prefix, cdEscrow.Bytes())
require.NoError(t, err)

// assert balances for IBC escrow accounts
cdEscrowBalance, err := chainC.GetBalance(ctx, transfertypes.GetEscrowAddress(cdChan.PortID, cdChan.ChannelID).String(), bcIBCDenom)
cdEscrowBalance, err := chainC.GetBalance(ctx, cdEscrowAccount, bcIBCDenom)
require.NoError(t, err)

bcEscrow := transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID)
bcEscrowAccount, err := bech32.ConvertAndEncode(chainB.Config().Bech32Prefix, bcEscrow.Bytes())
require.NoError(t, err)

bcEscrowBalance, err := chainB.GetBalance(ctx, bcEscrowAccount, chainB.Config().Denom)
require.NoError(t, err)

bcEscrowBalance, err := chainB.GetBalance(ctx, transfertypes.GetEscrowAddress(bcChan.PortID, bcChan.ChannelID).String(), chainB.Config().Denom)
baEscrow = transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID)
baEscrowAccount, err = bech32.ConvertAndEncode(chainB.Config().Bech32Prefix, baEscrow.Bytes())
require.NoError(t, err)

baEscrowBalance, err = chainB.GetBalance(ctx, transfertypes.GetEscrowAddress(baChan.PortID, baChan.ChannelID).String(), chainB.Config().Denom)
baEscrowBalance, err = chainB.GetBalance(ctx, baEscrowAccount, chainB.Config().Denom)
require.NoError(t, err)

require.True(t, baEscrowBalance.Equal(transferAmount))
Expand All @@ -623,7 +654,7 @@ func TestPacketForwardMiddleware(t *testing.T) {
require.NoError(t, err, "failed to get user a balance")

transfer := ibc.WalletAmount{
Address: userB.FormattedAddress(),
Address: intermediateAddr, // userB.FormattedAddress(), Receiver doesnt need to be valid, just non-empty, for intermediate chains as long as PFM exists.
Denom: chainA.Config().Denom,
Amount: transferAmount,
}
Expand Down