Skip to content

Commit

Permalink
feat(delayedack): fulfill only by packet key and added query for gett…
Browse files Browse the repository at this point in the history
…ing recipient packets (#1338)
  • Loading branch information
keruch authored Oct 21, 2024
1 parent d9b6cb8 commit 43d8aca
Show file tree
Hide file tree
Showing 21 changed files with 1,149 additions and 1,403 deletions.
38 changes: 33 additions & 5 deletions app/apptesting/test_suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ import (
"strings"
"time"

bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"

"github.com/dymensionxyz/dymension/v3/app/params"
dymnstypes "github.com/dymensionxyz/dymension/v3/x/dymns/types"

"github.com/cometbft/cometbft/libs/rand"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
bankutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/dymensionxyz/sdk-utils/utils/urand"
"github.com/stretchr/testify/suite"

"github.com/dymensionxyz/dymension/v3/app"
"github.com/dymensionxyz/dymension/v3/app/params"
delayedackkeeper "github.com/dymensionxyz/dymension/v3/x/delayedack/keeper"
delayedacktypes "github.com/dymensionxyz/dymension/v3/x/delayedack/types"
dymnstypes "github.com/dymensionxyz/dymension/v3/x/dymns/types"
rollappkeeper "github.com/dymensionxyz/dymension/v3/x/rollapp/keeper"
rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types"
sequencerkeeper "github.com/dymensionxyz/dymension/v3/x/sequencer/keeper"
Expand Down Expand Up @@ -181,3 +183,29 @@ func FundForAliasRegistration(
bankKeeper, ctx, sdk.MustAccAddressFromBech32(msgCreateRollApp.Creator), aliasRegistrationCost,
)
}

func (s *KeeperTestHelper) FinalizeAllPendingPackets(rollappID, receiver string) int {
s.T().Helper()
// Query all pending packets by receiver
querier := delayedackkeeper.NewQuerier(s.App.DelayedAckKeeper)
resp, err := querier.GetPendingPacketsByReceiver(s.Ctx, &delayedacktypes.QueryPendingPacketsByReceiverRequest{
RollappId: rollappID,
Receiver: receiver,
})
s.Require().NoError(err)
// Finalize all packets and return the num of finalized
for _, packet := range resp.RollappPackets {
handler := s.App.MsgServiceRouter().Handler(new(delayedacktypes.MsgFinalizePacket))
resp, err := handler(s.Ctx, &delayedacktypes.MsgFinalizePacket{
Sender: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
RollappId: packet.RollappId,
PacketProofHeight: packet.ProofHeight,
PacketType: packet.Type,
PacketSrcChannel: packet.Packet.SourceChannel,
PacketSequence: packet.Packet.Sequence,
})
s.Require().NoError(err)
s.Require().NotNil(resp)
}
return len(resp.RollappPackets)
}
2 changes: 1 addition & 1 deletion ibctesting/bridging_fee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (s *bridgingFeeSuite) TestBridgingFee() {
s.Require().NoError(err)

// manually finalize packets through x/delayedack
s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
s.finalizeRollappPacketsByReceiver(s.hubChain().SenderAccount.GetAddress().String())

// check balance after finalization
expectedFee := s.hubApp().DelayedAckKeeper.BridgingFeeFromAmt(s.hubCtx(), transferredCoins.Amount)
Expand Down
4 changes: 2 additions & 2 deletions ibctesting/delayed_ack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (s *delayedAckSuite) TestTransferRollappToHubFinalization() {
s.Require().NoError(err)

// manually finalize packets through x/delayedack
s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
s.finalizeRollappPacketsByReceiver(s.hubChain().SenderAccount.GetAddress().String())

// Validate ack is found
found = hubIBCKeeper.ChannelKeeper.HasPacketAcknowledgement(s.hubCtx(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
Expand Down Expand Up @@ -230,7 +230,7 @@ func (s *delayedAckSuite) TestHubToRollappTimeout() {
_, err = s.finalizeRollappState(1, currentRollappBlockHeight)
s.Require().NoError(err)
// manually finalize packets through x/delayedack
s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
s.finalizeRollappPacketsByReceiver(receiverAccount.String())
// Validate funds are returned to the sender
postFinalizeBalance := bankKeeper.GetBalance(s.hubCtx(), senderAccount, sdk.DefaultBondDenom)
s.Require().Equal(preSendBalance.Amount, postFinalizeBalance.Amount)
Expand Down
6 changes: 3 additions & 3 deletions ibctesting/eibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func (s *eibcSuite) TestEIBCDemandOrderFulfillment() {
s.Require().NoError(err)

// manually finalize packets through x/delayedack
s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
s.finalizeRollappPacketsByReceiver(fulfiller.String())

// Check the fulfiller balance was updated fully with the IBC amount
isUpdated := false
Expand Down Expand Up @@ -346,7 +346,7 @@ func (s *eibcSuite) TestEIBCDemandOrderFulfillment() {
s.Require().NoError(err)

// manually finalize packets through x/delayedack
evts := s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
evts := s.finalizeRollappPacketsByReceiver(fulfiller.String())

ack, err := ibctesting.ParseAckFromEvents(evts)
s.Require().NoError(err)
Expand Down Expand Up @@ -509,7 +509,7 @@ func (s *eibcSuite) TestTimeoutEIBCDemandOrderFulfillment() {
_, err = s.finalizeRollappState(1, currentRollappBlockHeight)
s.Require().NoError(err)
// manually finalize packets through x/delayedack
s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
s.finalizeRollappPacketsByReceiver(receiverAccount.String())
// Funds are passed to the fulfiller
fulfillerAccountBalanceAfterTimeout := bankKeeper.GetBalance(s.hubCtx(), fulfillerAccount, sdk.DefaultBondDenom)
s.Require().True(fulfillerAccountBalanceAfterTimeout.IsEqual(fulfillerInitialBalance.Add(lastDemandOrder.Fee[0])))
Expand Down
29 changes: 22 additions & 7 deletions ibctesting/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
Expand All @@ -27,6 +28,7 @@ import (
"github.com/dymensionxyz/dymension/v3/app"
"github.com/dymensionxyz/dymension/v3/app/apptesting"
common "github.com/dymensionxyz/dymension/v3/x/common/types"
delayedackkeeper "github.com/dymensionxyz/dymension/v3/x/delayedack/keeper"
delayedacktypes "github.com/dymensionxyz/dymension/v3/x/delayedack/types"
eibctypes "github.com/dymensionxyz/dymension/v3/x/eibc/types"
rollappkeeper "github.com/dymensionxyz/dymension/v3/x/rollapp/keeper"
Expand Down Expand Up @@ -369,14 +371,27 @@ func (s *utilSuite) newTestChainWithSingleValidator(t *testing.T, coord *ibctest
return chain
}

func (s *utilSuite) finalizeRollappPacketsUntilHeight(height uint64) sdk.Events {
handler := s.hubApp().MsgServiceRouter().Handler(new(delayedacktypes.MsgFinalizePacketsUntilHeight))
resp, err := handler(s.hubCtx(), &delayedacktypes.MsgFinalizePacketsUntilHeight{
Sender: s.rollappChain().SenderAccount.GetAddress().String(),
func (s *utilSuite) finalizeRollappPacketsByReceiver(receiver string) sdk.Events {
s.T().Helper()
// Query all pending packets by receiver
querier := delayedackkeeper.NewQuerier(s.hubApp().DelayedAckKeeper)
resp, err := querier.GetPendingPacketsByReceiver(s.hubCtx(), &delayedacktypes.QueryPendingPacketsByReceiverRequest{
RollappId: rollappChainID(),
Height: height,
Receiver: receiver,
})
s.Require().NoError(err)
s.Require().NotNil(resp)
return resp.GetEvents()
// Finalize all packets are collect events
events := make(sdk.Events, 0)
for _, packet := range resp.RollappPackets {
k := common.EncodePacketKey(packet.RollappPacketKey())
handler := s.hubApp().MsgServiceRouter().Handler(new(delayedacktypes.MsgFinalizePacketByPacketKey))
resp, err := handler(s.hubCtx(), &delayedacktypes.MsgFinalizePacketByPacketKey{
Sender: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
PacketKey: k,
})
s.Require().NoError(err)
s.Require().NotNil(resp)
events = append(events, resp.GetEvents()...)
}
return events
}
16 changes: 16 additions & 0 deletions proto/dymensionxyz/dymension/delayedack/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ service Query {
rpc GetPackets(QueryRollappPacketsRequest) returns (QueryRollappPacketListResponse) {
option (google.api.http).get = "/dymensionxyz/dymension/delayedack/packets/{rollappId}/{status}";
}

// Queries a list of pending RollappPacket items by rollappID and receiver.
rpc GetPendingPacketsByReceiver(QueryPendingPacketsByReceiverRequest) returns (QueryPendingPacketByReceiverListResponse) {
option (google.api.http).get = "/dymensionxyz/dymension/delayedack/pending-receiver-packets/{rollappId}/{receiver}";
}
}

// QueryParamsRequest is request type for the Query/Params RPC method.
Expand All @@ -42,4 +47,15 @@ message QueryRollappPacketsRequest {
message QueryRollappPacketListResponse {
repeated common.RollappPacket rollappPackets = 1 [(gogoproto.nullable) = false];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}

message QueryPendingPacketsByReceiverRequest {
string rollappId = 1;
string receiver = 2;
cosmos.base.query.v1beta1.PageRequest pagination = 3;
}

message QueryPendingPacketByReceiverListResponse {
repeated common.RollappPacket rollappPackets = 1 [(gogoproto.nullable) = false];
cosmos.base.query.v1beta1.PageResponse pagination = 2;
}
36 changes: 0 additions & 36 deletions proto/dymensionxyz/dymension/delayedack/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ service Msg {
rpc FinalizePacket(MsgFinalizePacket) returns (MsgFinalizePacketResponse);

rpc FinalizePacketByPacketKey(MsgFinalizePacketByPacketKey) returns (MsgFinalizePacketByPacketKeyResponse);

// FinalizePacketsUntilHeight finalizes the packets for the given rollapp until the given height inclusively.
rpc FinalizePacketsUntilHeight(MsgFinalizePacketsUntilHeight) returns (MsgFinalizePacketsUntilHeightResponse);

// FinalizeRollappPacketsByReceiver finalizes the rollapp packets for the specified receiver until the latest
// finalized height inclusively.
rpc FinalizeRollappPacketsByReceiver(MsgFinalizeRollappPacketsByReceiver) returns (MsgFinalizeRollappPacketsByReceiverResponse);
}

// MsgFinalizePacket finalizes a single packet.
Expand Down Expand Up @@ -54,32 +47,3 @@ message MsgFinalizePacketByPacketKey {
}

message MsgFinalizePacketByPacketKeyResponse {}

// MsgFinalizePacketsUntilHeight finalizes packets for the given rollapp until the given height inclusively.
message MsgFinalizePacketsUntilHeight {
option (cosmos.msg.v1.signer) = "sender";

// Sender is the signer of the message.
string sender = 1;
// RollappID is the ID of the rollapp.
string rollapp_id = 2;
// Height is a height until which packets are to be finalized. Height is inclusive.
uint64 height = 3;
}

message MsgFinalizePacketsUntilHeightResponse {}

// MsgFinalizeRollappPacketsByReceiver finalizes the rollapp packets for the specified receiver until the latest
// finalized height inclusively.
message MsgFinalizeRollappPacketsByReceiver {
option (cosmos.msg.v1.signer) = "sender";

// Sender is the signer of the message.
string sender = 1;
// RollappID is the ID of the rollapp.
string rollapp_id = 2;
// Receiver is the one who waits tokens after the finalization.
string receiver = 3;
}

message MsgFinalizeRollappPacketsByReceiverResponse {}
20 changes: 20 additions & 0 deletions x/common/types/key_rollapp_packet.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package types

import (
"bytes"
"encoding/base64"
"encoding/binary"
fmt "fmt"

Expand Down Expand Up @@ -104,3 +106,21 @@ func MustGetStatusBytes(status Status) []byte {
panic(fmt.Sprintf("invalid packet status: %s", status))
}
}

// DecodePacketKey decodes packet key from base64 to bytes.
func DecodePacketKey(packetKey string) ([]byte, error) {
rollappPacketKeyBytes := make([]byte, base64.StdEncoding.DecodedLen(len(packetKey)))
_, err := base64.StdEncoding.Decode(rollappPacketKeyBytes, []byte(packetKey))
if err != nil {
return nil, err
}
rollappPacketKeyBytes = bytes.TrimRight(rollappPacketKeyBytes, "\x00") // remove padding
return rollappPacketKeyBytes, nil
}

// EncodePacketKey encodes packet key from bytes to base 64.
func EncodePacketKey(packetKey []byte) string {
rollappPacketKeyBytes := make([]byte, base64.StdEncoding.EncodedLen(len(packetKey)))
base64.StdEncoding.Encode(rollappPacketKeyBytes, packetKey)
return string(rollappPacketKeyBytes)
}
46 changes: 46 additions & 0 deletions x/common/types/key_rollapp_packet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package types_test

import (
"testing"

transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
"github.com/stretchr/testify/require"

"github.com/dymensionxyz/dymension/v3/x/common/types"
commontypes "github.com/dymensionxyz/dymension/v3/x/common/types"
)

func TestEncodeDecodePacketKey(t *testing.T) {
packet := commontypes.RollappPacket{
RollappId: "rollapp_1234-1",
Status: commontypes.Status_PENDING,
ProofHeight: 8,
Packet: getNewTestPacket(t),
}

expectedPK := packet.RollappPacketKey()

encoded := types.EncodePacketKey(expectedPK)
decoded, err := types.DecodePacketKey(encoded)
require.NoError(t, err)

require.Equal(t, expectedPK, decoded)
}

func getNewTestPacket(t *testing.T) *channeltypes.Packet {
t.Helper()
data := &transfertypes.FungibleTokenPacketData{
Receiver: "testReceiver",
}
pd, err := transfertypes.ModuleCdc.MarshalJSON(data)
require.NoError(t, err)
return &channeltypes.Packet{
SourcePort: "testSourcePort",
SourceChannel: "testSourceChannel",
DestinationPort: "testDestinationPort",
DestinationChannel: "testDestinationChannel",
Data: pd,
Sequence: 1,
}
}
31 changes: 31 additions & 0 deletions x/delayedack/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func GetQueryCmd() *cobra.Command {
cmd.AddCommand(CmdGetPacketsByRollapp())
cmd.AddCommand(CmdGetPacketsByStatus())
cmd.AddCommand(CmdGetPacketsByType())
cmd.AddCommand(CmdGetPendingPacketsByReceiver())

return cmd
}
Expand Down Expand Up @@ -217,3 +218,33 @@ func CmdGetPacketsByType() *cobra.Command {

return cmd
}

func CmdGetPendingPacketsByReceiver() *cobra.Command {
cmd := &cobra.Command{
Use: "pending-packets-by-receiver [rollapp-id] [receiver]",
Short: "Get pending packets by receiver",
Args: cobra.MinimumNArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.GetPendingPacketsByReceiver(cmd.Context(), &types.QueryPendingPacketsByReceiverRequest{
RollappId: args[0],
Receiver: args[1],
Pagination: nil, // TODO: handle pagination
})
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
Loading

0 comments on commit 43d8aca

Please sign in to comment.