Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: impl packet receipt query #7513

Merged
merged 8 commits into from
Oct 29, 2024
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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solid choice for channel id 🥇

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
Loading