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

Harry/fee middleware #1174

Merged
merged 11 commits into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"reflect"
"strings"
"time"

"github.com/cosmos/relayer/v2/relayer"
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
"github.com/cosmos/relayer/v2/relayer/chains/penumbra"
Expand Down Expand Up @@ -668,4 +668,4 @@ func (c *Config) ValidateConnection(ctx context.Context, chain *relayer.Chain, h
}

return nil
}
}
37 changes: 37 additions & 0 deletions cmd/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Most of these commands take a [path] argument. Make sure:
createChannelCmd(a),
closeChannelCmd(a),
lineBreakCommand(),
registerCounterpartyCmd(a),
)

return cmd
Expand Down Expand Up @@ -1037,3 +1038,39 @@ func ensureKeysExist(chains map[string]*relayer.Chain) error {

return nil
}

// MsgRegisterCounterpartyPayee registers the counterparty_payee
func registerCounterpartyCmd(a *appState) *cobra.Command {
cmd := &cobra.Command{
Use: "register-counterparty chain_name channel_id port_id relay_addr counterparty_payee",
Aliases: []string{"reg-cpt"},
Short: "register the counterparty relayer address for ics-29 fee middleware",
Args: withUsage(cobra.MatchAll(cobra.ExactArgs(5))),
Example: strings.TrimSpace(fmt.Sprintf(`
$ %s register-counterparty channel-1 transfer cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk juno1g0ny488ws4064mjjxk4keenwfjrthn503ngjxd
$ %s reg-cpt channel-1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk juno1g0ny488ws4064mjjxk4keenwfjrthn503ngjxd`,
appName, appName)),
RunE: func(cmd *cobra.Command, args []string) error {

chain, ok := a.config.Chains[args[0]]
if !ok {
return errChainNotFound(args[0])
}

channelID := args[1]
portID := args[2]

relayerAddr := args[3]
counterpartyPayee := args[4]

msg, err := chain.ChainProvider.MsgRegisterCounterpartyPayee(portID, channelID, relayerAddr, counterpartyPayee)
if err != nil {
return err
}
res, success, err := chain.ChainProvider.SendMessage(cmd.Context(), msg, "")
fmt.Println(res, success, err)
return nil
},
}
return cmd
}
6 changes: 6 additions & 0 deletions go.work
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
go 1.20

use (
./interchaintest
.
)
442 changes: 442 additions & 0 deletions go.work.sum

Large diffs are not rendered by default.

202 changes: 202 additions & 0 deletions interchaintest/fee_middleware_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package interchaintest_test

import (
"context"
"fmt"
"testing"

transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
relayertest "github.com/cosmos/relayer/v2/interchaintest"
interchaintest "github.com/strangelove-ventures/interchaintest/v7"
"github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
ibc "github.com/strangelove-ventures/interchaintest/v7/ibc"
"github.com/strangelove-ventures/interchaintest/v7/testreporter"
"github.com/strangelove-ventures/interchaintest/v7/testutil"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)

func TestScenarioFeeMiddleware(t *testing.T) {
if testing.Short() {
t.Skip()
}

t.Parallel()

nv := 1
nf := 0

// Get both chains
cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{
{Name: "juno", ChainName: "chaina", Version: "v13.0.0", NumValidators: &nv, NumFullNodes: &nf, ChainConfig: ibc.ChainConfig{ChainID: "chaina", GasPrices: "0.0ujuno"}},
{Name: "juno", ChainName: "chainb", Version: "v13.0.0", NumValidators: &nv, NumFullNodes: &nf, ChainConfig: ibc.ChainConfig{ChainID: "chainb", GasPrices: "0.0ujuno"}}},
)

chains, err := cf.Chains(t.Name())
require.NoError(t, err)
chainA, chainB := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain)

ctx := context.Background()
client, network := interchaintest.DockerSetup(t)

rf := relayertest.NewRelayerFactory(relayertest.RelayerConfig{InitialBlockHistory: 50})
r := rf.Build(t, client, network)

const pathChainAChainB = "chainA-chainB"

// Build the network
ic := interchaintest.NewInterchain().
AddChain(chainA).
AddChain(chainB).
AddRelayer(r, "relayer").
AddLink(interchaintest.InterchainLink{
Chain1: chainA,
Chain2: chainB,
Relayer: r,
Path: pathChainAChainB,
CreateChannelOpts: ibc.CreateChannelOptions{
SourcePortName: "transfer",
DestPortName: "transfer",
Order: ibc.Unordered,
Version: "{\"fee_version\":\"ics29-1\",\"app_version\":\"ics20-1\"}",
},
CreateClientOpts: ibc.DefaultClientOpts(),
})

rep := testreporter.NewNopReporter()
eRep := rep.RelayerExecReporter(t)

require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{
TestName: t.Name(),
Client: client,
NetworkID: network,
SkipPathCreation: false,
}))

t.Cleanup(func() {
_ = ic.Close()
})

err = testutil.WaitForBlocks(ctx, 10, chainA, chainB)
require.NoError(t, err)

// ChainID of ChainA
chainIDA := chainA.Config().ChainID

// Channel of ChainA
chA, err := r.GetChannels(ctx, eRep, chainIDA)
require.NoError(t, err)
channelA := chA[0]

// Fund a user account on chain1 and chain2
const userFunds = int64(1_000_000_000_000)
users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), userFunds, chainA, chainB)
userA := users[0]
userAddressA := userA.FormattedAddress()
userB := users[1]
userAddressB := userB.FormattedAddress()

// Addresses of both the chains
walletA, _ := r.GetWallet(chainA.Config().ChainID)
rlyAddressA := walletA.FormattedAddress()

walletB, _ := r.GetWallet(chainB.Config().ChainID)
rlyAddressB := walletB.FormattedAddress()

// register CounterpartyPayee
cmd := []string{
"tx", "register-counterparty",
chainA.Config().Name,
channelA.ChannelID,
"transfer",
rlyAddressA,
rlyAddressB,
}
_ = r.Exec(ctx, eRep, cmd, nil)
require.NoError(t, err)

// Query the relayer CounterpartyPayee on a given channel
query := []string{
chainA.Config().Bin, "query", "ibc-fee", "counterparty-payee", channelA.ChannelID, rlyAddressA,
"--chain-id", chainIDA,
"--node", chainA.GetRPCAddress(),
"--home", chainA.HomeDir(),
"--trace",
}
_, _, err = chainA.Exec(ctx, query, nil)
require.NoError(t, err)

// Get initial account balances
userAOrigBal, err := chainA.GetBalance(ctx, userAddressA, chainA.Config().Denom)
require.NoError(t, err)
require.Equal(t, userFunds, userAOrigBal)

userBOrigBal, err := chainB.GetBalance(ctx, userAddressB, chainB.Config().Denom)
require.NoError(t, err)
require.Equal(t, userFunds, userBOrigBal)

rlyAOrigBal, err := chainA.GetBalance(ctx, rlyAddressA, chainA.Config().Denom)
require.NoError(t, err)
require.Equal(t, userFunds, rlyAOrigBal)

rlyBOrigBal, err := chainB.GetBalance(ctx, rlyAddressB, chainB.Config().Denom)
require.NoError(t, err)
require.Equal(t, userFunds, rlyBOrigBal)

// send tx
const txAmount = 1000
transfer := ibc.WalletAmount{Address: userAddressB, Denom: chainA.Config().Denom, Amount: txAmount}
_, err = chainA.SendIBCTransfer(ctx, channelA.ChannelID, userAddressA, transfer, ibc.TransferOptions{})
require.NoError(t, err)

// Incentivizing async packet by returning MsgPayPacketFeeAsync
packetFeeAsync := []string{
chainA.Config().Bin, "tx", "ibc-fee", "pay-packet-fee", "transfer", channelA.ChannelID, "1",
"--recv-fee", fmt.Sprintf("1000%s", chainA.Config().Denom),
"--ack-fee", fmt.Sprintf("1000%s", chainA.Config().Denom),
"--timeout-fee", fmt.Sprintf("1000%s", chainA.Config().Denom),
"--chain-id", chainIDA,
"--node", chainA.GetRPCAddress(),
"--from", userA.FormattedAddress(),
"--keyring-backend", "test",
"--gas", "400000",
"--yes",
"--home", chainA.HomeDir(),
}
_, _, err = chainA.Exec(ctx, packetFeeAsync, nil)
require.NoError(t, err)

// start the relayer
err = r.StartRelayer(ctx, eRep, pathChainAChainB)
require.NoError(t, err)

t.Cleanup(
func() {
err := r.StopRelayer(ctx, eRep)
if err != nil {
t.Logf("an error occured while stopping the relayer: %s", err)
}
},
)

// Wait for relayer to run
err = testutil.WaitForBlocks(ctx, 5, chainA, chainB)
require.NoError(t, err)

// Assigning denom
chainATokenDenom := transfertypes.GetPrefixedDenom(channelA.PortID, channelA.ChannelID, chainA.Config().Denom)
chainADenomTrace := transfertypes.ParseDenomTrace(chainATokenDenom)

// Get balances after the fees
chainABal, err := chainA.GetBalance(ctx, userAddressA, chainA.Config().Denom)
require.NoError(t, err)
require.Equal(t, userAOrigBal-(txAmount+1000), chainABal)
Cosmos-Harry marked this conversation as resolved.
Show resolved Hide resolved

chainBBal, err := chainB.GetBalance(ctx, userAddressB, chainADenomTrace.IBCDenom())
require.NoError(t, err)
require.Equal(t, int64(txAmount), chainBBal)

rlyABal, err := chainA.GetBalance(ctx, rlyAddressA, chainA.Config().Denom)
require.NoError(t, err)
require.Equal(t, rlyAOrigBal+1000, rlyABal)
}
17 changes: 2 additions & 15 deletions interchaintest/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import (
"testing"

"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/relayer/v2/cmd"
"github.com/cosmos/relayer/v2/internal/relayertest"
"github.com/cosmos/relayer/v2/relayer"
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
"github.com/cosmos/relayer/v2/relayer/provider"
interchaintestcosmos "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v7/ibc"
"github.com/stretchr/testify/require"
"github.com/strangelove-ventures/interchaintest/v7/relayer/rly"
"go.uber.org/zap"
"go.uber.org/zap/zaptest"
)
Expand Down Expand Up @@ -338,26 +337,14 @@ func (r *Relayer) GetWallet(chainID string) (ibc.Wallet, bool) {
}
address := strings.TrimSpace(res.Stdout.String())

var chainCfg ibc.ChainConfig
var keyName string
config := r.sys().MustGetConfig(r.t)
for _, v := range config.ProviderConfigs {
if c, ok := v.Value.(cosmos.CosmosProviderConfig); ok {
if c.ChainID == chainID {
keyName = c.Key
chainCfg = ibc.ChainConfig{
Type: v.Type,
Name: c.ChainName,
ChainID: c.ChainID,
Bech32Prefix: c.AccountPrefix,
GasPrices: c.GasPrices,
GasAdjustment: c.GasAdjustment,
}
}
}
}

addressBz, err := types.GetFromBech32(address, chainCfg.Bech32Prefix)
require.NoError(r.t, err, "failed to decode bech32 wallet")
return interchaintestcosmos.NewWallet(keyName, addressBz, "", chainCfg), true
return rly.NewWallet(keyName, address, ""), true
Cosmos-Harry marked this conversation as resolved.
Show resolved Hide resolved
}
5 changes: 3 additions & 2 deletions internal/relayertest/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zaptest"
"gopkg.in/yaml.v3"
)

// System is a system under test.
Expand Down Expand Up @@ -129,10 +130,10 @@ func (s *System) MustAddChain(t *testing.T, chainName string, pcw cmd.ProviderCo
func (s *System) MustGetConfig(t *testing.T) (config cmd.ConfigInputWrapper) {
t.Helper()

configBz, err := os.ReadFile(filepath.Join(s.HomeDir, "config.yaml"))
configBz, err := os.ReadFile(filepath.Join(s.HomeDir, "config", "config.yaml"))
Cosmos-Harry marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(t, err, "failed to read config file")

err = json.Unmarshal(configBz, &config)
err = yaml.Unmarshal(configBz, &config)
require.NoError(t, err, "failed to unmarshal config file")

return config
Expand Down
2 changes: 2 additions & 0 deletions relayer/chains/cosmos/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking"
"github.com/cosmos/cosmos-sdk/x/upgrade"
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
ibcfee "github.com/cosmos/ibc-go/v7/modules/apps/29-fee"
"github.com/cosmos/ibc-go/v7/modules/apps/transfer"
ibc "github.com/cosmos/ibc-go/v7/modules/core"

Expand Down Expand Up @@ -58,6 +59,7 @@ var ModuleBasics = []module.AppModuleBasic{
ibc.AppModuleBasic{},
cosmosmodule.AppModuleBasic{},
stride.AppModuleBasic{},
ibcfee.AppModuleBasic{},
}

type Codec struct {
Expand Down
7 changes: 7 additions & 0 deletions relayer/chains/cosmos/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/cosmos/cosmos-sdk/store/rootmulti"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
feetypes "github.com/cosmos/ibc-go/v7/modules/apps/29-fee/types"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
Expand Down Expand Up @@ -1272,6 +1273,12 @@ func (cc *CosmosProvider) UpdateFeesSpent(chain, key string, fees sdk.Coins) {
}
}

// MsgRegisterCounterpartyPayee creates an sdk.Msg to broadcast the counterparty address
func (cc *CosmosProvider) MsgRegisterCounterpartyPayee(portID, channelID, relayerAddr, counterpartyPayee string) (provider.RelayerMessage,error) {
msg := feetypes.NewMsgRegisterCounterpartyPayee(portID, channelID, relayerAddr, counterpartyPayee)
return NewCosmosMessage(msg),nil
}

// PrepareFactory mutates the tx factory with the appropriate account number, sequence number, and min gas settings.
func (cc *CosmosProvider) PrepareFactory(txf tx.Factory) (tx.Factory, error) {
var (
Expand Down
7 changes: 6 additions & 1 deletion relayer/chains/penumbra/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,6 @@ func (cc *PenumbraProvider) MsgConnectionOpenTry(msgOpenInit provider.Connection
return cosmos.NewCosmosMessage(msg), nil
}


func (cc *PenumbraProvider) MsgConnectionOpenAck(msgOpenTry provider.ConnectionInfo, proof provider.ConnectionProof) (provider.RelayerMessage, error) {
signer, err := cc.Address()
if err != nil {
Expand Down Expand Up @@ -2233,3 +2232,9 @@ func (cc *PenumbraProvider) SendMessagesToMempool(ctx context.Context, msgs []pr
cc.log.Debug("Received response from sending messages", zap.Any("response", sendRsp), zap.Error(err))
return err
}

// MsgRegisterCounterpartyPayee creates an sdk.Msg to broadcast the counterparty address
func (cc *PenumbraProvider) MsgRegisterCounterpartyPayee(portID, channelID, relayerAddr, counterpartyPayee string) (provider.RelayerMessage, error) {
//TODO implement me
panic("implement me")
}
Loading