Skip to content

Commit

Permalink
Impl msg server, keeper logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
DimitrisJim committed Dec 19, 2023
1 parent 9782bef commit 2b8147f
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 4 deletions.
47 changes: 44 additions & 3 deletions modules/core/04-channel/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,18 @@ func (k Keeper) SetPacketReceipt(ctx sdk.Context, portID, channelID string, sequ
store.Set(host.PacketReceiptKey(portID, channelID, sequence), []byte{byte(1)})
}

// HasPacketReceipt returns true if the packet receipt exists
func (k Keeper) HasPacketReceipt(ctx sdk.Context, portID, channelID string, sequence uint64) bool {
store := ctx.KVStore(k.storeKey)
return store.Has(host.PacketReceiptKey(portID, channelID, sequence))
}

// deletePacketReceipt deletes a packet receipt from the store
func (k Keeper) deletePacketReceipt(ctx sdk.Context, portID, channelID string, sequence uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(host.PacketReceiptKey(portID, channelID, sequence))
}

// GetPacketCommitment gets the packet commitment hash from the store
func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte {
store := ctx.KVStore(k.storeKey)
Expand Down Expand Up @@ -240,6 +252,12 @@ func (k Keeper) HasPacketAcknowledgement(ctx sdk.Context, portID, channelID stri
return store.Has(host.PacketAcknowledgementKey(portID, channelID, sequence))
}

// deletePacketAcknowledgement deletes the packet ack hash from the store
func (k Keeper) deletePacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(host.PacketAcknowledgementKey(portID, channelID, sequence))
}

// IteratePacketSequence provides an iterator over all send, receive or ack sequences.
// For each sequence, cb will be called. If the cb returns true, the iterator
// will close and stop.
Expand Down Expand Up @@ -629,8 +647,31 @@ func (k Keeper) SetAcknowledgementPruningSequence(ctx sdk.Context, portID, chann
store.Set(host.AckPruningSequenceKey(portID, channelID), bz)
}

// PruneAcknowledgements prunes packet acknowledgements from the store that have a sequence number less than or equal to the pruning sequence.
// PruneAcknowledgements prunes packet acknowledgements from the store that have a sequence number less than or equal to the last packet send.
// The number of packet acknowledgements pruned is equal to limit. Pruning only occurs after a channel has been upgraded.
func (Keeper) PruneAcknowledgements(ctx sdk.Context, portID, channelID string, limit, pruningSequence uint64) error {
return nil
//
// The pruningSequence keeps track of the packet acknowledgement that can be pruned next. When the pruning sequence reaches
// the last send sequence, pruning is complete.
func (k Keeper) PruneAcknowledgements(ctx sdk.Context, portID, channelID string, limit, pruningSequence uint64) uint64 {
// TODO(jim): Update to use last sequence send.
lastSequenceSend := uint64(0)

limit = pruningSequence + limit
for ; pruningSequence < limit; pruningSequence++ {
// break if the pruning sequence reaches the last send sequence
if pruningSequence >= lastSequenceSend {
break
}

if k.HasPacketAcknowledgement(ctx, portID, channelID, pruningSequence) {
k.deletePacketAcknowledgement(ctx, portID, channelID, pruningSequence)
}

// Note: packet ack at sequence `pruningSequence` does not imply packet receipt at sequence `pruningSequence` exists
if k.HasPacketReceipt(ctx, portID, channelID, pruningSequence) {
k.deletePacketReceipt(ctx, portID, channelID, pruningSequence)
}
}

return pruningSequence
}
1 change: 1 addition & 0 deletions modules/core/04-channel/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ var (
ErrPendingInflightPackets = errorsmod.Register(SubModuleName, 36, "pending inflight packets exist")
ErrUpgradeTimeoutFailed = errorsmod.Register(SubModuleName, 37, "upgrade timeout failed")
ErrInvalidPruningLimit = errorsmod.Register(SubModuleName, 38, "invalid pruning limit")
ErrPruningSequenceNotFound = errorsmod.Register(SubModuleName, 39, "pruning sequence not found")
)
14 changes: 13 additions & 1 deletion modules/core/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,18 @@ func (k Keeper) UpdateChannelParams(goCtx context.Context, msg *channeltypes.Msg
}

// PruneAcknowledgements defines a rpc handler method for MsgPruneAcknowledgements.
func (Keeper) PruneAcknowledgements(goCtx context.Context, msg *channeltypes.MsgPruneAcknowledgements) (*channeltypes.MsgPruneAcknowledgementsResponse, error) {
func (k Keeper) PruneAcknowledgements(goCtx context.Context, msg *channeltypes.MsgPruneAcknowledgements) (*channeltypes.MsgPruneAcknowledgementsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

sequence, found := k.ChannelKeeper.GetAcknowledgementPruningSequence(ctx, msg.PortId, msg.ChannelId)
if !found {
return nil, errorsmod.Wrapf(channeltypes.ErrPruningSequenceNotFound, "port ID (%s) channel ID (%s)", msg.PortId, msg.ChannelId)
}

sequence = k.ChannelKeeper.PruneAcknowledgements(ctx, msg.PortId, msg.ChannelId, msg.Limit, sequence)

// update pruning sequence in store
k.ChannelKeeper.SetAcknowledgementPruningSequence(ctx, msg.PortId, msg.ChannelId, sequence)

return &channeltypes.MsgPruneAcknowledgementsResponse{}, nil
}
63 changes: 63 additions & 0 deletions modules/core/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2016,3 +2016,66 @@ func (suite *KeeperTestSuite) TestUpdateConnectionParams() {
})
}
}

func (suite *KeeperTestSuite) TestPruneAcknowledgements() {
var path *ibctesting.Path

testCases := []struct {
name string
malleate func()
expErr error
}{
{
"success",
func() {},
nil,
},
{
"failure: pruning sequence not found",
func() {
store := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetKey(exported.ModuleName))
store.Delete(host.AckPruningSequenceKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID))
},
channeltypes.ErrPruningSequenceNotFound,
},
// TODO(jim): Exercise this path
// {
// "failure: pruning fails",
// func() {},
// nil,
// },
}

for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
suite.SetupTest()

path = ibctesting.NewPath(suite.chainA, suite.chainB)
suite.coordinator.Setup(path)

// TODO(jim): initiate full upgrade handshake when pruning seq PR is merged
// for now, just manually set a dummy pruning sequence.
suite.chainA.App.GetIBCKeeper().ChannelKeeper.SetAcknowledgementPruningSequence(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 10)

msg := channeltypes.NewMsgPruneAcknowledgements(
path.EndpointA.ChannelConfig.PortID,
path.EndpointA.ChannelID,
10,
suite.chainA.SenderAccount.GetAddress().String(),
)

tc.malleate()

resp, err := suite.chainA.App.GetIBCKeeper().PruneAcknowledgements(suite.chainA.GetContext(), msg)

if tc.expErr == nil {
suite.Require().NoError(err)
suite.Require().NotNil(resp)
} else {
suite.Require().Error(err)
suite.Require().Nil(resp)
}
})
}
}

0 comments on commit 2b8147f

Please sign in to comment.