Skip to content

Commit

Permalink
feat(delayedack): made packet finalization manual (#1205)
Browse files Browse the repository at this point in the history
  • Loading branch information
keruch authored Sep 21, 2024
1 parent 14877e9 commit 045e6c3
Show file tree
Hide file tree
Showing 34 changed files with 3,783 additions and 105 deletions.
2 changes: 1 addition & 1 deletion app/keepers/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func (a *AppKeepers) SetupModules(
sequencermodule.NewAppModule(appCodec, a.SequencerKeeper, a.AccountKeeper, a.BankKeeper, a.GetSubspace(sequencertypes.ModuleName)),
sponsorship.NewAppModule(a.SponsorshipKeeper),
streamermodule.NewAppModule(a.StreamerKeeper, a.AccountKeeper, a.BankKeeper, a.EpochsKeeper),
delayedackmodule.NewAppModule(appCodec, a.DelayedAckKeeper),
delayedackmodule.NewAppModule(appCodec, a.DelayedAckKeeper, a.delayedAckMiddleware),
denommetadatamodule.NewAppModule(a.DenomMetadataKeeper, *a.EvmKeeper, a.BankKeeper),
eibcmodule.NewAppModule(appCodec, a.EIBCKeeper, a.AccountKeeper, a.BankKeeper),
dymnsmodule.NewAppModule(appCodec, a.DymNSKeeper),
Expand Down
3 changes: 3 additions & 0 deletions ibctesting/bridging_fee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ func (s *bridgingFeeSuite) TestBridgingFee() {
_, err = s.finalizeRollappState(1, currentRollappBlockHeight)
s.Require().NoError(err)

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

// check balance after finalization
expectedFee := s.hubApp().DelayedAckKeeper.BridgingFeeFromAmt(s.hubCtx(), transferredCoins.Amount)
expectedBalance := initialBalance.Add(transferredCoins).Sub(sdk.NewCoin(denom, expectedFee))
Expand Down
8 changes: 6 additions & 2 deletions ibctesting/delayed_ack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/suite"

"github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
ibctesting "github.com/cosmos/ibc-go/v7/testing"
"github.com/stretchr/testify/suite"
)

const (
Expand Down Expand Up @@ -174,6 +173,9 @@ func (s *delayedAckSuite) TestTransferRollappToHubFinalization() {
_, err = s.finalizeRollappState(1, currentRollappBlockHeight)
s.Require().NoError(err)

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

// Validate ack is found
found = hubIBCKeeper.ChannelKeeper.HasPacketAcknowledgement(s.hubCtx(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
s.Require().True(found)
Expand Down Expand Up @@ -226,6 +228,8 @@ func (s *delayedAckSuite) TestHubToRollappTimeout() {
currentRollappBlockHeight := uint64(s.rollappCtx().BlockHeight())
_, err = s.finalizeRollappState(1, currentRollappBlockHeight)
s.Require().NoError(err)
// manually finalize packets through x/delayedack
s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
// Validate funds are returned to the sender
postFinalizeBalance := bankKeeper.GetBalance(s.hubCtx(), senderAccount, sdk.DefaultBondDenom)
s.Require().Equal(preSendBalance.Amount, postFinalizeBalance.Amount)
Expand Down
11 changes: 10 additions & 1 deletion ibctesting/eibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ func (s *eibcSuite) TestEIBCDemandOrderFulfillment() {
currentRollappBlockHeight = uint64(s.rollappCtx().BlockHeight())
_, err := s.finalizeRollappState(rollappStateIndex, currentRollappBlockHeight)
s.Require().NoError(err)

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

// Check the fulfiller balance was updated fully with the IBC amount
isUpdated := false
fulfillerAccountBalanceAfterFinalization := s.hubApp().BankKeeper.SpendableCoins(s.hubCtx(), fulfiller)
Expand Down Expand Up @@ -337,9 +341,12 @@ func (s *eibcSuite) TestEIBCDemandOrderFulfillment() {

// Finalize rollapp and check fulfiller balance was updated with fee
currentRollappBlockHeight = uint64(s.rollappCtx().BlockHeight())
evts, err := s.finalizeRollappState(rollappStateIndex, currentRollappBlockHeight)
_, err = s.finalizeRollappState(rollappStateIndex, currentRollappBlockHeight)
s.Require().NoError(err)

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

ack, err := ibctesting.ParseAckFromEvents(evts)
s.Require().NoError(err)

Expand Down Expand Up @@ -500,6 +507,8 @@ func (s *eibcSuite) TestTimeoutEIBCDemandOrderFulfillment() {
currentRollappBlockHeight := uint64(s.rollappCtx().BlockHeight())
_, err = s.finalizeRollappState(1, currentRollappBlockHeight)
s.Require().NoError(err)
// manually finalize packets through x/delayedack
s.finalizeRollappPacketsUntilHeight(currentRollappBlockHeight)
// 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
13 changes: 13 additions & 0 deletions ibctesting/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/dymensionxyz/dymension/v3/app"
"github.com/dymensionxyz/dymension/v3/app/apptesting"
common "github.com/dymensionxyz/dymension/v3/x/common/types"
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"
rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types"
Expand Down Expand Up @@ -346,3 +347,15 @@ 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(),
RollappId: rollappChainID(),
Height: height,
})
s.Require().NoError(err)
s.Require().NotNil(resp)
return resp.GetEvents()
}
46 changes: 46 additions & 0 deletions proto/dymensionxyz/dymension/delayedack/events.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
syntax = "proto3";
package dymensionxyz.dymension.delayedack;

import "dymensionxyz/dymension/common/rollapp_packet.proto";

option go_package = "github.com/dymensionxyz/dymension/v3/x/delayedack/types";

message EventFinalizePacket {
// Sender is the signer of the message.
string sender = 1;
// RollappID is the ID of the rollapp.
string rollapp_id = 2;
// PacketProofHeight height at which the proof was retrieved.
uint64 packet_proof_height = 3;
// PacketType is a type of the packet. Eg, RECV, ACK, TIMEOUT.
dymensionxyz.dymension.common.RollappPacket.Type packet_type = 4;
// PacketSrcChannel identifies the channel end on the sending chain.
string packet_src_channel = 5;
// PacketSequence is a sequence number of the packet.
uint64 packet_sequence = 6;
}

message EventFinalizePacketsUntilHeight {
// 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;
// FinalizedNum is the number of finalized packets.
uint64 finalized_num = 4;
}

message EventFinalizeRollappPacketsByReceiver {
// 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;
// Height is a height until which packets are to be finalized.
uint64 height = 4;
// FinalizedNum is the number of finalized packets.
uint64 finalized_num = 5;

}
71 changes: 71 additions & 0 deletions proto/dymensionxyz/dymension/delayedack/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
syntax = "proto3";
package dymensionxyz.dymension.delayedack;

import "cosmos/msg/v1/msg.proto";
import "dymensionxyz/dymension/common/rollapp_packet.proto";

option go_package = "github.com/dymensionxyz/dymension/v3/x/delayedack/types";

// Msg defines the Msg service.
service Msg {
option (cosmos.msg.v1.service) = true;

// FinalizePacket finalizes a singe packet.
rpc FinalizePacket(MsgFinalizePacket) returns (MsgFinalizePacketResponse);

// 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.
message MsgFinalizePacket {
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;
// PacketProofHeight is a height at which the proof was retrieved.
uint64 packet_proof_height = 3;
// PacketType is a type of the packet. Eg, RECV, ACK, TIMEOUT.
dymensionxyz.dymension.common.RollappPacket.Type packet_type = 4;
// PacketSrcChannel identifies the channel end on the sending chain.
string packet_src_channel = 5;
// PacketSequence is a sequence number of the packet.
uint64 packet_sequence = 6;
}

message MsgFinalizePacketResponse {}

// 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 {}
4 changes: 4 additions & 0 deletions testutil/keeper/delayedack.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ func (r RollappKeeperStub) MustGetStateInfo(ctx sdk.Context, rollappId string, i
return rollapptypes.StateInfo{}
}

func (r RollappKeeperStub) GetLatestStateInfo(ctx sdk.Context, rollappId string) (rollapptypes.StateInfo, bool) {
return rollapptypes.StateInfo{}, false
}

func (RollappKeeperStub) GetLatestFinalizedStateIndex(ctx sdk.Context, rollappId string) (val rollapptypes.StateInfoIndex, found bool) {
return rollapptypes.StateInfoIndex{}, false
}
Expand Down
29 changes: 23 additions & 6 deletions x/common/types/key_rollapp_packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,37 @@ var (
// Example would be, both rollapp and hub have channel-0 and we have at the same proof height of the rollapp
// AckPacket with sequence 1 (originated on the hub) and OnRecvPacket with sequence 1 (originated on the rollapp).
// Adding the packet type guarantees uniqueness as the type differentiates the source.
func RollappPacketKey(rollappPacket *RollappPacket) []byte {
func (p *RollappPacket) RollappPacketKey() []byte {
return RollappPacketKey(
p.Status,
p.RollappId,
p.ProofHeight,
p.Type,
p.Packet.SourceChannel,
p.Packet.Sequence,
)
}

func RollappPacketKey(
status Status,
rollappID string,
proofHeight uint64,
packetType RollappPacket_Type,
packetSrcChannel string,
packetSequence uint64,
) []byte {
// Get the bytes rep
srppPrefix := RollappPacketByStatusByRollappIDByProofHeightPrefix(rollappPacket.RollappId, rollappPacket.Status, rollappPacket.ProofHeight)
packetTypeBytes := []byte(rollappPacket.Type.String())
packetSequenceBytes := sdk.Uint64ToBigEndian(rollappPacket.Packet.Sequence)
packetSourceChannelBytes := []byte(rollappPacket.Packet.SourceChannel)
srppPrefix := RollappPacketByStatusByRollappIDByProofHeightPrefix(rollappID, status, proofHeight)
packetTypeBytes := []byte(packetType.String())
packetSequenceBytes := sdk.Uint64ToBigEndian(packetSequence)
packetSourceChannelBytes := []byte(packetSrcChannel)
// Construct the key
result := append(srppPrefix, keySeparatorBytes...)
result = append(result, packetTypeBytes...)
result = append(result, keySeparatorBytes...)
result = append(result, packetSourceChannelBytes...)
result = append(result, keySeparatorBytes...)
result = append(result, packetSequenceBytes...)

return result
}

Expand Down
2 changes: 1 addition & 1 deletion x/delayedack/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd(queryRoute string) *cobra.Command {
func GetQueryCmd() *cobra.Command {
// Group eibc queries under a subcommand
cmd := &cobra.Command{
Use: types.ModuleName,
Expand Down
Loading

0 comments on commit 045e6c3

Please sign in to comment.