Skip to content

Commit

Permalink
Merge branch 'ics29-fee-middleware' into sean/issue#759-async-ack
Browse files Browse the repository at this point in the history
  • Loading branch information
seantking committed Feb 23, 2022
2 parents 64d6742 + 6999e10 commit fb0625e
Show file tree
Hide file tree
Showing 22 changed files with 332 additions and 121 deletions.
2 changes: 2 additions & 0 deletions docs/ibc/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,7 @@ RegisteredRelayerAddress contains the address and counterparty address for a spe
| ----- | ---- | ----- | ----------- |
| `address` | [string](#string) | | |
| `counterparty_address` | [string](#string) | | |
| `channel_id` | [string](#string) | | |



Expand Down Expand Up @@ -1041,6 +1042,7 @@ MsgRegisterCounterpartyAddress is the request type for registering the counterpa
| ----- | ---- | ----- | ----------- |
| `address` | [string](#string) | | |
| `counterparty_address` | [string](#string) | | |
| `channel_id` | [string](#string) | | |



Expand Down
4 changes: 2 additions & 2 deletions modules/apps/29-fee/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ func GetQueryCmd() *cobra.Command {
func NewTxCmd() *cobra.Command {
txCmd := &cobra.Command{
Use: "ibc-fee",
Short: "", // TODO
Short: "Transaction subcommand for IBC relayer incentivization",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

txCmd.AddCommand(
// TODO
NewPayPacketFeeAsyncTxCmd(),
)

return txCmd
Expand Down
98 changes: 97 additions & 1 deletion modules/apps/29-fee/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,99 @@
package cli

// TODO
import (
"fmt"
"strconv"
"strings"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/spf13/cobra"

"github.com/cosmos/ibc-go/v3/modules/apps/29-fee/types"
channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
)

const (
flagRecvFee = "recv-fee"
flagAckFee = "ack-fee"
flagTimeoutFee = "timeout-fee"
)

// NewPayPacketFeeAsyncTxCmd returns the command to create a MsgPayPacketFeeAsync
func NewPayPacketFeeAsyncTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "pay-packet-fee [src-port] [src-channel] [sequence]",
Short: "Pay a fee to incentivize an existing IBC packet",
Long: strings.TrimSpace(`Pay a fee to incentivize an existing IBC packet.`),
Example: fmt.Sprintf("%s tx pay-packet-fee transfer channel-0 1 --recv-fee 10stake --ack-fee 10stake --timeout-fee 10stake", version.AppName),
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

// NOTE: specifying non-nil relayers is currently unsupported
var relayers []string

sender := clientCtx.GetFromAddress().String()
seq, err := strconv.ParseUint(args[2], 10, 64)
if err != nil {
return err
}

packetID := channeltypes.NewPacketId(args[1], args[0], seq)

recvFeeStr, err := cmd.Flags().GetString(flagRecvFee)
if err != nil {
return err
}

recvFee, err := sdk.ParseCoinsNormalized(recvFeeStr)
if err != nil {
return err
}

ackFeeStr, err := cmd.Flags().GetString(flagAckFee)
if err != nil {
return err
}

ackFee, err := sdk.ParseCoinsNormalized(ackFeeStr)
if err != nil {
return err
}

timeoutFeeStr, err := cmd.Flags().GetString(flagTimeoutFee)
if err != nil {
return err
}

timeoutFee, err := sdk.ParseCoinsNormalized(timeoutFeeStr)
if err != nil {
return err
}

fee := types.Fee{
RecvFee: recvFee,
AckFee: ackFee,
TimeoutFee: timeoutFee,
}

identifiedPacketFee := types.NewIdentifiedPacketFee(packetID, fee, sender, relayers)

msg := types.NewMsgPayPacketFeeAsync(identifiedPacketFee)
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().String(flagRecvFee, "", "Fee paid to a relayer for relaying a packet receive.")
cmd.Flags().String(flagAckFee, "", "Fee paid to a relayer for relaying a packet acknowledgement.")
cmd.Flags().String(flagTimeoutFee, "", "Fee paid to a relayer for relaying a packet timeout.")
flags.AddTxFlagsToCmd(cmd)

return cmd
}
4 changes: 2 additions & 2 deletions modules/apps/29-fee/ibc_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func (im IBCModule) OnChanOpenAck(
}

if versionMetadata.FeeVersion != types.Version {
return sdkerrors.Wrapf(types.ErrInvalidVersion, "expected counterparty version: %s, got: %s", types.Version, versionMetadata.FeeVersion)
return sdkerrors.Wrapf(types.ErrInvalidVersion, "expected counterparty fee version: %s, got: %s", types.Version, versionMetadata.FeeVersion)
}

// call underlying app's OnChanOpenAck callback with the counterparty app version.
Expand Down Expand Up @@ -203,7 +203,7 @@ func (im IBCModule) OnRecvPacket(
}

// if forwardRelayer is not found we refund recv_fee
forwardRelayer, _ := im.keeper.GetCounterpartyAddress(ctx, relayer.String())
forwardRelayer, _ := im.keeper.GetCounterpartyAddress(ctx, relayer.String(), packet.GetSourceChannel())

return types.NewIncentivizedAcknowledgement(forwardRelayer, ack.Acknowledgement(), ack.Success())
}
Expand Down
4 changes: 2 additions & 2 deletions modules/apps/29-fee/ibc_module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ func (suite *FeeTestSuite) TestOnRecvPacket() {
{
"forward address is not found",
func() {
suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainB.GetContext(), suite.chainA.SenderAccount.GetAddress().String(), "")
suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainB.GetContext(), suite.chainA.SenderAccount.GetAddress().String(), "", suite.path.EndpointB.ChannelID)
},
false,
true,
Expand All @@ -514,7 +514,7 @@ func (suite *FeeTestSuite) TestOnRecvPacket() {
cbs, ok := suite.chainB.App.GetIBCKeeper().Router.GetRoute(module)
suite.Require().True(ok)

suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainB.GetContext(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String())
suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainB.GetContext(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), suite.path.EndpointB.ChannelID)

// malleate test case
tc.malleate()
Expand Down
4 changes: 2 additions & 2 deletions modules/apps/29-fee/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) {
k.SetFeeInEscrow(ctx, fee)
}

for _, addr := range state.RegisteredRelayers {
k.SetCounterpartyAddress(ctx, addr.Address, addr.CounterpartyAddress)
for _, relayer := range state.RegisteredRelayers {
k.SetCounterpartyAddress(ctx, relayer.Address, relayer.CounterpartyAddress, relayer.ChannelId)
}

for _, forwardAddr := range state.ForwardRelayers {
Expand Down
5 changes: 3 additions & 2 deletions modules/apps/29-fee/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (suite *KeeperTestSuite) TestInitGenesis() {
{
Address: sender,
CounterpartyAddress: counterparty,
ChannelId: ibctesting.FirstChannelID,
},
},
}
Expand All @@ -59,7 +60,7 @@ func (suite *KeeperTestSuite) TestInitGenesis() {
suite.Require().True(isEnabled)

// check relayers
addr, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetCounterpartyAddress(suite.chainA.GetContext(), sender)
addr, found := suite.chainA.GetSimApp().IBCFeeKeeper.GetCounterpartyAddress(suite.chainA.GetContext(), sender, ibctesting.FirstChannelID)
suite.Require().True(found)
suite.Require().Equal(genesisState.RegisteredRelayers[0].CounterpartyAddress, addr)
}
Expand All @@ -84,7 +85,7 @@ func (suite *KeeperTestSuite) TestExportGenesis() {
sender := suite.chainA.SenderAccount.GetAddress().String()
counterparty := suite.chainB.SenderAccount.GetAddress().String()
// set counterparty address
suite.chainA.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainA.GetContext(), sender, counterparty)
suite.chainA.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainA.GetContext(), sender, counterparty, ibctesting.FirstChannelID)

// set forward relayer address
suite.chainA.GetSimApp().IBCFeeKeeper.SetRelayerAddressForAsyncAck(suite.chainA.GetContext(), packetID, sender)
Expand Down
11 changes: 6 additions & 5 deletions modules/apps/29-fee/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,15 @@ func (k Keeper) DisableAllChannels(ctx sdk.Context) {

// SetCounterpartyAddress maps the destination chain relayer address to the source relayer address
// The receiving chain must store the mapping from: address -> counterpartyAddress for the given channel
func (k Keeper) SetCounterpartyAddress(ctx sdk.Context, address, counterpartyAddress string) {
func (k Keeper) SetCounterpartyAddress(ctx sdk.Context, address, counterpartyAddress, channelID string) {
store := ctx.KVStore(k.storeKey)
store.Set(types.KeyRelayerAddress(address), []byte(counterpartyAddress))
store.Set(types.KeyCounterpartyRelayer(address, channelID), []byte(counterpartyAddress))
}

// GetCounterpartyAddress gets the relayer counterparty address given a destination relayer address
func (k Keeper) GetCounterpartyAddress(ctx sdk.Context, address string) (string, bool) {
func (k Keeper) GetCounterpartyAddress(ctx sdk.Context, address, channelID string) (string, bool) {
store := ctx.KVStore(k.storeKey)
key := types.KeyRelayerAddress(address)
key := types.KeyCounterpartyRelayer(address, channelID)

if !store.Has(key) {
return "", false
Expand All @@ -156,7 +156,7 @@ func (k Keeper) GetCounterpartyAddress(ctx sdk.Context, address string) (string,
// GetAllRelayerAddresses returns all registered relayer addresses
func (k Keeper) GetAllRelayerAddresses(ctx sdk.Context) []types.RegisteredRelayerAddress {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, []byte(types.RelayerAddressKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte(types.CounterpartyRelayerAddressKeyPrefix))
defer iterator.Close()

var registeredAddrArr []types.RegisteredRelayerAddress
Expand All @@ -166,6 +166,7 @@ func (k Keeper) GetAllRelayerAddresses(ctx sdk.Context) []types.RegisteredRelaye
addr := types.RegisteredRelayerAddress{
Address: keySplit[1],
CounterpartyAddress: string(iterator.Value()),
ChannelId: keySplit[2],
}

registeredAddrArr = append(registeredAddrArr, addr)
Expand Down
3 changes: 2 additions & 1 deletion modules/apps/29-fee/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,13 @@ func (suite *KeeperTestSuite) TestGetAllRelayerAddresses() {
sender := suite.chainA.SenderAccount.GetAddress().String()
counterparty := suite.chainB.SenderAccount.GetAddress().String()

suite.chainA.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainA.GetContext(), sender, counterparty)
suite.chainA.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainA.GetContext(), sender, counterparty, ibctesting.FirstChannelID)

expectedAddr := []types.RegisteredRelayerAddress{
{
Address: sender,
CounterpartyAddress: counterparty,
ChannelId: ibctesting.FirstChannelID,
},
}

Expand Down
2 changes: 1 addition & 1 deletion modules/apps/29-fee/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (k Keeper) RegisterCounterpartyAddress(goCtx context.Context, msg *types.Ms
ctx := sdk.UnwrapSDKContext(goCtx)

k.SetCounterpartyAddress(
ctx, msg.Address, msg.CounterpartyAddress,
ctx, msg.Address, msg.CounterpartyAddress, msg.ChannelId,
)

k.Logger(ctx).Info("Registering counterparty address for relayer.", "Address:", msg.Address, "Counterparty Address:", msg.CounterpartyAddress)
Expand Down
5 changes: 3 additions & 2 deletions modules/apps/29-fee/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper_test
import (
"github.com/cosmos/ibc-go/v3/modules/apps/29-fee/types"
channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
ibctesting "github.com/cosmos/ibc-go/v3/testing"
)

func (suite *KeeperTestSuite) TestRegisterCounterpartyAddress() {
Expand Down Expand Up @@ -35,14 +36,14 @@ func (suite *KeeperTestSuite) TestRegisterCounterpartyAddress() {
sender = suite.chainA.SenderAccount.GetAddress().String()
counterparty = suite.chainB.SenderAccount.GetAddress().String()
tc.malleate()
msg := types.NewMsgRegisterCounterpartyAddress(sender, counterparty)
msg := types.NewMsgRegisterCounterpartyAddress(sender, counterparty, ibctesting.FirstChannelID)

_, err := suite.chainA.SendMsgs(msg)

if tc.expPass {
suite.Require().NoError(err) // message committed

counterpartyAddress, _ := suite.chainA.GetSimApp().IBCFeeKeeper.GetCounterpartyAddress(ctx, suite.chainA.SenderAccount.GetAddress().String())
counterpartyAddress, _ := suite.chainA.GetSimApp().IBCFeeKeeper.GetCounterpartyAddress(ctx, suite.chainA.SenderAccount.GetAddress().String(), ibctesting.FirstChannelID)
suite.Require().Equal(counterparty, counterpartyAddress)
} else {
suite.Require().Error(err)
Expand Down
6 changes: 3 additions & 3 deletions modules/apps/29-fee/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ func (k Keeper) WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.C

// it is possible that a relayer has not registered a counterparty address.
// if there is no registered counterparty address then write acknowledgement with empty relayer address and refund recv_fee.
forwardRelayer, _ := k.GetCounterpartyAddress(ctx, relayer)

k.DeleteForwardRelayerAddress(ctx, packetId)
forwardRelayer, _ := k.GetCounterpartyAddress(ctx, relayer, packet.GetSourceChannel())

ack := types.NewIncentivizedAcknowledgement(forwardRelayer, acknowledgement.Acknowledgement(), acknowledgement.Success())

k.DeleteForwardRelayerAddress(ctx, packetId)

// ics4Wrapper may be core IBC or higher-level middleware
return k.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, packet, ack)
}
2 changes: 1 addition & 1 deletion modules/apps/29-fee/keeper/relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (suite *KeeperTestSuite) TestWriteAcknowledgementAsync() {
"success",
func() {
suite.chainB.GetSimApp().IBCFeeKeeper.SetRelayerAddressForAsyncAck(suite.chainB.GetContext(), channeltypes.NewPacketId(suite.path.EndpointA.ChannelID, suite.path.EndpointA.ChannelConfig.PortID, 1), suite.chainA.SenderAccount.GetAddress().String())
suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainB.GetContext(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String())
suite.chainB.GetSimApp().IBCFeeKeeper.SetCounterpartyAddress(suite.chainB.GetContext(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), suite.path.EndpointA.ChannelID)
},
true,
},
Expand Down
2 changes: 1 addition & 1 deletion modules/apps/29-fee/transfer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (suite *FeeTestSuite) TestFeeTransfer() {
// to differentiate from the chainA.SenderAccount for checking successful relay payouts
relayerAddress := suite.chainB.SenderAccount.GetAddress()

msgRegister := types.NewMsgRegisterCounterpartyAddress(suite.chainB.SenderAccount.GetAddress().String(), relayerAddress.String())
msgRegister := types.NewMsgRegisterCounterpartyAddress(suite.chainB.SenderAccount.GetAddress().String(), relayerAddress.String(), ibctesting.FirstChannelID)
_, err = suite.chainB.SendMsgs(msgRegister)
suite.Require().NoError(err) // message committed

Expand Down
Loading

0 comments on commit fb0625e

Please sign in to comment.