Skip to content

Commit

Permalink
chore: impl packet receipt query (#7513)
Browse files Browse the repository at this point in the history
* feat: add v2 packet commitment query

* chore: add cli for packet commitment query with abci proof

* chore: impl packet acknowledgement query

* fix: update identifier validation in grpcs

* chore: impl packet receipt query
  • Loading branch information
damiannolan authored Oct 29, 2024
1 parent e0b40f0 commit a5bff0b
Show file tree
Hide file tree
Showing 9 changed files with 987 additions and 40 deletions.
11 changes: 11 additions & 0 deletions modules/core/04-channel/v2/client/cli/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,14 @@ func queryPacketAcknowledgementABCI(clientCtx client.Context, channelID string,

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

func queryPacketReceiptABCI(clientCtx client.Context, channelID string, sequence uint64) (*types.QueryPacketReceiptResponse, error) {
key := host.PacketReceiptKey(channelID, sequence)

value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key)
if err != nil {
return nil, err
}

return types.NewQueryPacketReceiptResponse(value != nil, 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 @@ -22,6 +22,7 @@ func GetQueryCmd() *cobra.Command {
getCmdQueryChannel(),
getCmdQueryPacketCommitment(),
getCmdQueryPacketAcknowledgement(),
getCmdQueryPacketReceipt(),
)

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 @@ -146,3 +146,54 @@ func getCmdQueryPacketAcknowledgement() *cobra.Command {

return cmd
}

func getCmdQueryPacketReceipt() *cobra.Command {
cmd := &cobra.Command{
Use: "packet-receipt [channel-id] [sequence]",
Short: "Query a channel/v2 packet receipt",
Long: "Query a channel/v2 packet receipt by channel-id and sequence",
Example: fmt.Sprintf(
"%s query %s %s packet-receipt [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 := queryPacketReceiptABCI(clientCtx, channelID, seq)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.PacketReceipt(cmd.Context(), types.NewQueryPacketReceiptRequest(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
}
23 changes: 23 additions & 0 deletions modules/core/04-channel/v2/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,26 @@ func (q *queryServer) PacketAcknowledgement(ctx context.Context, req *types.Quer

return types.NewQueryPacketAcknowledgementResponse(acknowledgement, nil, clienttypes.GetSelfHeight(ctx)), nil
}

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

if err := host.ChannelIdentifierValidator(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())
}

hasReceipt := q.HasPacketReceipt(ctx, req.ChannelId, req.Sequence)

return types.NewQueryPacketReceiptResponse(hasReceipt, nil, clienttypes.GetSelfHeight(ctx)), nil
}
105 changes: 105 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 @@ -294,3 +294,108 @@ func (suite *KeeperTestSuite) TestQueryPacketAcknowledgement() {
})
}
}

func (suite *KeeperTestSuite) TestQueryPacketReceipt() {
var (
expReceipt bool
path *ibctesting.Path
req *types.QueryPacketReceiptRequest
)

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

suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetPacketReceipt(suite.chainA.GetContext(), path.EndpointA.ChannelID, 1)

expReceipt = true
req = &types.QueryPacketReceiptRequest{
ChannelId: path.EndpointA.ChannelID,
Sequence: 1,
}
},
nil,
},
{
"success with no receipt",
func() {
path = ibctesting.NewPath(suite.chainA, suite.chainB)
path.SetupV2()

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

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.PacketReceipt(suite.chainA.GetContext(), req)

expPass := tc.expError == nil
if expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expReceipt, res.Received)
} else {
suite.Require().ErrorIs(err, tc.expError)
suite.Require().Nil(res)
}
})
}
}
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 @@ -49,3 +49,20 @@ func NewQueryPacketAcknowledgementResponse(acknowledgementHash []byte, proof []b
ProofHeight: proofHeight,
}
}

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

// NewQueryPacketReceiptResponse creates and returns a new packet receipt query response.
func NewQueryPacketReceiptResponse(exists bool, proof []byte, height clienttypes.Height) *QueryPacketReceiptResponse {
return &QueryPacketReceiptResponse{
Received: exists,
Proof: proof,
ProofHeight: height,
}
}
Loading

0 comments on commit a5bff0b

Please sign in to comment.