Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add next sequence send query.
Browse files Browse the repository at this point in the history
DimitrisJim committed Nov 12, 2024
1 parent 5b3ce55 commit 2763648
Showing 9 changed files with 837 additions and 60 deletions.
19 changes: 19 additions & 0 deletions modules/core/04-channel/v2/client/cli/abci.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cli

import (
"encoding/binary"

errorsmod "cosmossdk.io/errors"

"github.com/cosmos/cosmos-sdk/client"
@@ -10,6 +12,23 @@ import (
ibcclient "github.com/cosmos/ibc-go/v9/modules/core/client"
)

func queryNextSequenceSendABCI(clientCtx client.Context, channelID string) (*types.QueryNextSequenceSendResponse, error) {
key := host.NextSequenceSendKey(channelID)
value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key)
if err != nil {
return nil, err
}

// check if next sequence send exists
if len(value) == 0 {
return nil, errorsmod.Wrapf(types.ErrSequenceSendNotFound, "channelID (%s)", channelID)
}

sequence := binary.BigEndian.Uint64(value)

return types.NewQueryNextSequenceSendResponse(sequence, proofBz, proofHeight), nil
}

func queryPacketCommitmentABCI(clientCtx client.Context, channelID string, sequence uint64) (*types.QueryPacketCommitmentResponse, error) {
key := host.PacketCommitmentKey(channelID, sequence)
value, proofBz, proofHeight, err := ibcclient.QueryTendermintProof(clientCtx, key)
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
@@ -20,6 +20,7 @@ func GetQueryCmd() *cobra.Command {

queryCmd.AddCommand(
getCmdQueryChannel(),
getCmdQueryNextSequenceSend(),
getCmdQueryPacketCommitment(),
getCmdQueryPacketCommitments(),
getCmdQueryPacketAcknowledgement(),
46 changes: 46 additions & 0 deletions modules/core/04-channel/v2/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -45,6 +45,52 @@ func getCmdQueryChannel() *cobra.Command {
return cmd
}

// getCmdQueryNextSequenceSend defines the command to query a next send sequence for a given channel
func getCmdQueryNextSequenceSend() *cobra.Command {
cmd := &cobra.Command{
Use: "next-sequence-send [channel-id]",
Short: "Query a next send sequence",
Long: "Query the next sequence send for a given channel",
Example: fmt.Sprintf(
"%s query %s %s next-sequence-send [channel-id]", version.AppName, exported.ModuleName, types.SubModuleName,
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
channelID := args[0]
prove, err := cmd.Flags().GetBool(flags.FlagProve)
if err != nil {
return err
}

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

return clientCtx.PrintProto(res)
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.NextSequenceSend(cmd.Context(), types.NewQueryNextSequenceSendRequest(channelID))
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
}

func getCmdQueryPacketCommitment() *cobra.Command {
cmd := &cobra.Command{
Use: "packet-commitment [channel-id] [sequence]",
20 changes: 20 additions & 0 deletions modules/core/04-channel/v2/keeper/grpc_query.go
Original file line number Diff line number Diff line change
@@ -52,6 +52,26 @@ func (q *queryServer) Channel(ctx context.Context, req *types.QueryChannelReques
return types.NewQueryChannelResponse(channel), nil
}

// NextSequenceSend implements the Query/NextSequenceSend gRPC method
func (q *queryServer) NextSequenceSend(ctx context.Context, req *types.QueryNextSequenceSendRequest) (*types.QueryNextSequenceSendResponse, 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())
}

sequence, found := q.GetNextSequenceSend(ctx, req.ChannelId)
if !found {
return nil, status.Error(
codes.NotFound,
errorsmod.Wrapf(types.ErrSequenceSendNotFound, "channel-id %s", req.ChannelId).Error(),
)
}
return types.NewQueryNextSequenceSendResponse(sequence, nil, clienttypes.GetSelfHeight(ctx)), nil
}

// PacketCommitment implements the Query/PacketCommitment gRPC method.
func (q *queryServer) PacketCommitment(ctx context.Context, req *types.QueryPacketCommitmentRequest) (*types.QueryPacketCommitmentResponse, error) {
if req == nil {
72 changes: 72 additions & 0 deletions modules/core/04-channel/v2/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
@@ -514,3 +514,75 @@ func (suite *KeeperTestSuite) TestQueryPacketReceipt() {
})
}
}

func (suite *KeeperTestSuite) TestQueryNextSequenceSend() {
var (
req *types.QueryNextSequenceSendRequest
expSeq uint64
)

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

expSeq = 42
seq := uint64(42)
suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SetNextSequenceSend(suite.chainA.GetContext(), path.EndpointA.ChannelID, seq)
req = types.NewQueryNextSequenceSendRequest(path.EndpointA.ChannelID)
},
nil,
},
{
"req is nil",
func() {
req = nil
},
status.Error(codes.InvalidArgument, "empty request"),
},
{
"invalid channel ID",
func() {
req = types.NewQueryNextSequenceSendRequest("")
},
status.Error(codes.InvalidArgument, "identifier cannot be blank: invalid identifier"),
},
{
"sequence send not found",
func() {
req = types.NewQueryNextSequenceSendRequest(ibctesting.FirstChannelID)
},
status.Error(codes.NotFound, fmt.Sprintf("channel-id %s: sequence send not found", ibctesting.FirstChannelID)),
},
}

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

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

tc.malleate()
ctx := suite.chainA.GetContext()

queryServer := keeper.NewQueryServer(suite.chainA.App.GetIBCKeeper().ChannelKeeperV2)
res, err := queryServer.NextSequenceSend(ctx, req)

expPass := tc.expError == nil
if expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expSeq, res.NextSequenceSend)
} else {
suite.Require().ErrorIs(err, tc.expError)
suite.Require().Nil(res)
}
})
}
}
18 changes: 18 additions & 0 deletions modules/core/04-channel/v2/types/query.go
Original file line number Diff line number Diff line change
@@ -16,6 +16,24 @@ func NewQueryChannelResponse(channel Channel) *QueryChannelResponse {
}
}

// NewQueryNextSequenceSendRequest creates a new next sequence send query.
func NewQueryNextSequenceSendRequest(channelID string) *QueryNextSequenceSendRequest {
return &QueryNextSequenceSendRequest{
ChannelId: channelID,
}
}

// NewQueryNextSequenceSendResponse creates a new QueryNextSequenceSendResponse instance
func NewQueryNextSequenceSendResponse(
sequence uint64, proof []byte, height clienttypes.Height,
) *QueryNextSequenceSendResponse {
return &QueryNextSequenceSendResponse{
NextSequenceSend: sequence,
Proof: proof,
ProofHeight: height,
}
}

// NewQueryPacketCommitmentRequest creates and returns a new packet commitment query request.
func NewQueryPacketCommitmentRequest(channelID string, sequence uint64) *QueryPacketCommitmentRequest {
return &QueryPacketCommitmentRequest{
599 changes: 539 additions & 60 deletions modules/core/04-channel/v2/types/query.pb.go

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions modules/core/04-channel/v2/types/query.pb.gw.go
21 changes: 21 additions & 0 deletions proto/ibc/core/channel/v2/query.proto
Original file line number Diff line number Diff line change
@@ -18,6 +18,11 @@ service Query {
option (google.api.http).get = "/ibc/core/channel/v2/channels/{channel_id}";
}

// NextSequenceSend returns the next send sequence for a given channel.
rpc NextSequenceSend(QueryNextSequenceSendRequest) returns (QueryNextSequenceSendResponse) {
option (google.api.http).get = "/ibc/core/channel/v2/channels/{channel_id}/next_sequence_send";
}

// PacketCommitment queries a stored packet commitment hash.
rpc PacketCommitment(QueryPacketCommitmentRequest) returns (QueryPacketCommitmentResponse) {
option (google.api.http).get = "/ibc/core/channel/v2/channels/{channel_id}/packet_commitments/{sequence}";
@@ -50,6 +55,22 @@ message QueryChannelResponse {
Channel channel = 1 [(gogoproto.nullable) = false];
}

// QueryNextSequenceSendRequest is the request type for the Query/QueryNextSequenceSend RPC method
message QueryNextSequenceSendRequest {
// channel unique identifier
string channel_id = 1;
}

// QueryNextSequenceSendResponse is the response type for the Query/QueryNextSequenceSend RPC method
message QueryNextSequenceSendResponse {
// next sequence send number
uint64 next_sequence_send = 1;
// merkle proof of existence
bytes proof = 2;
// height at which the proof was retrieved
ibc.core.client.v1.Height proof_height = 3 [(gogoproto.nullable) = false];
}

// QueryPacketCommitmentRequest is the request type for the Query/PacketCommitment RPC method.
message QueryPacketCommitmentRequest {
// channel unique identifier

0 comments on commit 2763648

Please sign in to comment.