Skip to content

Commit

Permalink
chore: impl packet acknowledgement query
Browse files Browse the repository at this point in the history
  • Loading branch information
damiannolan committed Oct 22, 2024
1 parent fe9b9f6 commit aefd9d3
Show file tree
Hide file tree
Showing 10 changed files with 926 additions and 33 deletions.
15 changes: 15 additions & 0 deletions modules/core/04-channel/v2/client/cli/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,18 @@ func queryPacketCommitmentABCI(clientCtx client.Context, channelID string, seque

return types.NewQueryPacketCommitmentResponse(value, proofBz, proofHeight), nil
}

func queryPacketAcknowledgementABCI(clientCtx client.Context, channelID string, sequence uint64) (*types.QueryPacketAcknowledgementResponse, error) {
key := host.PacketAcknowledgementKey(channelID, sequence)
value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key)
if err != nil {
return nil, err
}

// check if packet commitment exists
if len(value) == 0 {
return nil, errorsmod.Wrapf(types.ErrAcknowledgementNotFound, "channelID (%s), sequence (%d)", channelID, sequence)
}

return types.NewQueryPacketAcknowledgementResponse(value, proofBz, proofHeight), nil
}
1 change: 1 addition & 0 deletions modules/core/04-channel/v2/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func GetQueryCmd() *cobra.Command {
queryCmd.AddCommand(
getCmdQueryChannel(),
getCmdQueryPacketCommitment(),
getCmdQueryPacketAcknowledgement(),
)

return queryCmd
Expand Down
51 changes: 51 additions & 0 deletions modules/core/04-channel/v2/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,54 @@ func getCmdQueryPacketCommitment() *cobra.Command {

return cmd
}

func getCmdQueryPacketAcknowledgement() *cobra.Command {
cmd := &cobra.Command{
Use: "packet-acknowledgement [channel-id] [sequence]",
Short: "Query a channel/v2 packet acknowledgement",
Long: "Query a channel/v2 packet acknowledgement by channel-id and sequence",
Example: fmt.Sprintf(
"%s query %s %s packet-acknowledgement [channel-id] [sequence]", version.AppName, exported.ModuleName, types.SubModuleName,
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

channelID := args[0]
seq, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return err
}

prove, err := cmd.Flags().GetBool(flags.FlagProve)
if err != nil {
return err
}

if prove {
res, err := queryPacketAcknowledgementABCI(clientCtx, channelID, seq)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.PacketAcknowledgement(cmd.Context(), types.NewQueryPacketAcknowledgementRequest(channelID, seq))
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results")
flags.AddQueryFlagsToCmd(cmd)

return cmd
}
26 changes: 26 additions & 0 deletions modules/core/04-channel/v2/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,29 @@ func (q *queryServer) PacketCommitment(ctx context.Context, req *types.QueryPack

return types.NewQueryPacketCommitmentResponse(commitment, nil, clienttypes.GetSelfHeight(ctx)), nil
}

// PacketAcknowledgement implements the Query/PacketAcknowledgement gRPC method.
func (q *queryServer) PacketAcknowledgement(ctx context.Context, req *types.QueryPacketAcknowledgementRequest) (*types.QueryPacketAcknowledgementResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

if err := host.ClientIdentifierValidator(req.ChannelId); err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}

if req.Sequence == 0 {
return nil, status.Error(codes.InvalidArgument, "packet sequence cannot be 0")
}

if !q.HasChannel(ctx, req.ChannelId) {
return nil, status.Error(codes.NotFound, errorsmod.Wrap(types.ErrChannelNotFound, req.ChannelId).Error())
}

acknowledgement := q.GetPacketAcknowledgement(ctx, req.ChannelId, req.Sequence)
if len(acknowledgement) == 0 {
return nil, status.Error(codes.NotFound, "packet acknowledgement hash not found")
}

return types.NewQueryPacketAcknowledgementResponse(acknowledgement, nil, clienttypes.GetSelfHeight(ctx)), nil
}
104 changes: 104 additions & 0 deletions modules/core/04-channel/v2/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,107 @@ func (suite *KeeperTestSuite) TestQueryPacketCommitment() {
})
}
}

func (suite *KeeperTestSuite) TestQueryPacketAcknowledgement() {
var (
expAcknowledgement []byte
path *ibctesting.Path
req *types.QueryPacketAcknowledgementRequest
)

testCases := []struct {
msg string
malleate func()
expError error
}{
{
"success",
func() {
path = ibctesting.NewPath(suite.chainA, suite.chainB)
path.SetupV2()

expAcknowledgement = []byte("acknowledgementHash")
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetPacketAcknowledgement(suite.chainA.GetContext(), path.EndpointA.ChannelID, 1, expAcknowledgement)

req = &types.QueryPacketAcknowledgementRequest{
ChannelId: path.EndpointA.ChannelID,
Sequence: 1,
}
},
nil,
},
{
"empty request",
func() {
req = nil
},
status.Error(codes.InvalidArgument, "empty request"),
},
{
"invalid channel ID",
func() {
req = &types.QueryPacketAcknowledgementRequest{
ChannelId: "",
Sequence: 1,
}
},
status.Error(codes.InvalidArgument, "identifier cannot be blank: invalid identifier"),
},
{
"invalid sequence",
func() {
req = &types.QueryPacketAcknowledgementRequest{
ChannelId: ibctesting.FirstChannelID,
Sequence: 0,
}
},
status.Error(codes.InvalidArgument, "packet sequence cannot be 0"),
},
{
"channel not found",
func() {
req = &types.QueryPacketAcknowledgementRequest{
ChannelId: "channel-141",
Sequence: 1,
}
},
status.Error(codes.NotFound, fmt.Sprintf("%s: channel not found", "channel-141")),
},
{
"acknowledgement not found",
func() {
path := ibctesting.NewPath(suite.chainA, suite.chainB)
path.SetupV2()

req = &types.QueryPacketAcknowledgementRequest{
ChannelId: path.EndpointA.ChannelID,
Sequence: 1,
}
},
status.Error(codes.NotFound, "packet acknowledgement hash not found"),
},
}

for _, tc := range testCases {
tc := tc

suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset

tc.malleate()

queryServer := keeper.NewQueryServer(suite.chainA.GetSimApp().IBCKeeper.ChannelKeeperV2)
res, err := queryServer.PacketAcknowledgement(suite.chainA.GetContext(), req)

expPass := tc.expError == nil
if expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expAcknowledgement, res.Acknowledgement)
} else {
suite.Require().ErrorIs(err, tc.expError)
suite.Require().Nil(res)
}
})
}
}
1 change: 1 addition & 0 deletions modules/core/04-channel/v2/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ var (
ErrSequenceSendNotFound = errorsmod.Register(SubModuleName, 6, "sequence send not found")
ErrInvalidAcknowledgement = errorsmod.Register(SubModuleName, 8, "invalid acknowledgement")
ErrPacketCommitmentNotFound = errorsmod.Register(SubModuleName, 9, "packet commitment not found")
ErrAcknowledgementNotFound = errorsmod.Register(SubModuleName, 10, "packet acknowledgement not found")
)
17 changes: 17 additions & 0 deletions modules/core/04-channel/v2/types/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,20 @@ func NewQueryPacketCommitmentResponse(commitmentHash []byte, proof []byte, proof
ProofHeight: proofHeight,
}
}

// NewQueryPacketAcknowledgementRequest creates and returns a new packet acknowledgement query request.
func NewQueryPacketAcknowledgementRequest(channelID string, sequence uint64) *QueryPacketAcknowledgementRequest {
return &QueryPacketAcknowledgementRequest{
ChannelId: channelID,
Sequence: sequence,
}
}

// NewQueryPacketAcknowledgementResponse creates and returns a new packet acknowledgement query response.
func NewQueryPacketAcknowledgementResponse(acknowledgementHash []byte, proof []byte, proofHeight clienttypes.Height) *QueryPacketAcknowledgementResponse {
return &QueryPacketAcknowledgementResponse{
Acknowledgement: acknowledgementHash,
Proof: proof,
ProofHeight: proofHeight,
}
}
Loading

0 comments on commit aefd9d3

Please sign in to comment.