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

[OTE-221] Add query for PendingSendPacket #1176

Merged
merged 13 commits into from
Mar 22, 2024
11 changes: 11 additions & 0 deletions proto/dydxprotocol/ratelimit/pending_send_packet.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";
package dydxprotocol.ratelimit;

option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types";

// PendingSendPacket contains the channel_id and sequence pair to identify a
// pending packet
message PendingSendPacket {
string channel_id = 1;
uint64 sequence = 2;
}
18 changes: 18 additions & 0 deletions proto/dydxprotocol/ratelimit/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "dydxprotocol/ratelimit/limit_params.proto";
import "dydxprotocol/ratelimit/capacity.proto";
import "dydxprotocol/ratelimit/pending_send_packet.proto";

option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types";

Expand All @@ -23,6 +24,12 @@ service Query {
option (google.api.http).get =
"/dydxprotocol/v4/ratelimit/capacity_by_denom";
}
// Get all pending send packets
rpc GetAllPendingSendPackets(GetAllPendingSendPacketsRequest)
affanv14 marked this conversation as resolved.
Show resolved Hide resolved
returns (GetAllPendingSendPacketsResponse) {
option (google.api.http).get =
"/dydxprotocol/v4/ratelimit/get_all_pending_send_packet";
}
}

// ListLimitParamsRequest is a request type of the ListLimitParams RPC method.
Expand All @@ -43,3 +50,14 @@ message QueryCapacityByDenomResponse {
repeated LimiterCapacity limiter_capacity_list = 1
[ (gogoproto.nullable) = false ];
}

// GetAllPendingSendPacketsRequest is a request type for the
// GetAllPendingSendPackets RPC
message GetAllPendingSendPacketsRequest {}

// GetAllPendingSendPacketsResponse is a response type of the
// GetAllPendingSendPackets RPC
message GetAllPendingSendPacketsResponse {
repeated PendingSendPacket pending_send_packets = 1
[ (gogoproto.nullable) = false ];
}
2 changes: 1 addition & 1 deletion protocol/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0
google.golang.org/protobuf v1.32.0
gotest.tools/v3 v3.5.1
)

require (
Expand Down Expand Up @@ -405,7 +406,6 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
honnef.co/go/tools v0.4.6 // indirect
mvdan.cc/gofumpt v0.6.0 // indirect
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
Expand Down
35 changes: 35 additions & 0 deletions protocol/x/ratelimit/client/cli/pending_send_packets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cli

import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types"
"github.com/spf13/cobra"
)

func CmdPendingSendPackets() *cobra.Command {
cmd := &cobra.Command{
Use: "pending-send-packets",
Short: "gets all pending send packets",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.GetAllPendingSendPackets(cmd.Context(), &types.GetAllPendingSendPacketsRequest{})
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
30 changes: 30 additions & 0 deletions protocol/x/ratelimit/client/cli/pending_send_packets_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//go:build all || integration_test

package cli_test

import (
"fmt"
"testing"

tmcli "github.com/cometbft/cometbft/libs/cli"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/client/cli"
"github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
)

func TestPendingSendPackets(t *testing.T) {
net, ctx := setupNetwork(t)

out, err := clitestutil.ExecTestCLICmd(ctx,
cli.CmdPendingSendPackets(),
[]string{
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
})

require.NoError(t, err)
var resp types.GetAllPendingSendPacketsResponse
require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp))
assert.Equal(t, 0, len(resp.PendingSendPackets))
}
1 change: 1 addition & 0 deletions protocol/x/ratelimit/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command {

cmd.AddCommand(CmdListLimitParams())
cmd.AddCommand(CmdQueryCapacityByDenom())
cmd.AddCommand(CmdPendingSendPackets())

return cmd
}
26 changes: 26 additions & 0 deletions protocol/x/ratelimit/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"context"

"cosmossdk.io/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -47,3 +48,28 @@ func (k Keeper) CapacityByDenom(
LimiterCapacityList: limiterCapacityList,
}, nil
}

func (k Keeper) GetAllPendingSendPackets(
ctx context.Context,
req *types.GetAllPendingSendPacketsRequest,
) (*types.GetAllPendingSendPacketsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}
sdkCtx := sdk.UnwrapSDKContext(ctx)

store := prefix.NewStore(sdkCtx.KVStore(k.storeKey), []byte(types.PendingSendPacketPrefix))
pendingPackets := make([]types.PendingSendPacket, 0)
iterator := store.Iterator(nil, nil)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
channelId, sequence := types.SplitPendingSendPacketKey(iterator.Key())
pendingPackets = append(pendingPackets, types.PendingSendPacket{
ChannelId: channelId,
Sequence: sequence,
})
}
return &types.GetAllPendingSendPacketsResponse{
PendingSendPackets: pendingPackets,
}, nil
}
29 changes: 29 additions & 0 deletions protocol/x/ratelimit/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,32 @@ func TestCapacityByDenom(t *testing.T) {
})
}
}

func TestGetAllPendingSendPacket(t *testing.T) {
tApp := testapp.NewTestAppBuilder(t).Build()
ctx := tApp.InitChain()
k := tApp.App.RatelimitKeeper

channels := []string{"channel-0", "channel-1"}
sequences := []uint64{20, 22}

for i := range channels {
k.SetPendingSendPacket(ctx, channels[i], sequences[i])
}

req := &types.GetAllPendingSendPacketsRequest{}
res, err := k.GetAllPendingSendPackets(ctx, req)
require.NoError(t, err)
require.Equal(t, &types.GetAllPendingSendPacketsResponse{
PendingSendPackets: []types.PendingSendPacket{
{
ChannelId: channels[0],
Sequence: sequences[0],
},
{
ChannelId: channels[1],
Sequence: sequences[1],
},
},
}, res)
}
3 changes: 2 additions & 1 deletion protocol/x/ratelimit/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ func TestAppModuleBasic_GetQueryCmd(t *testing.T) {

cmd := am.GetQueryCmd()
require.Equal(t, "ratelimit", cmd.Use)
require.Equal(t, 2, len(cmd.Commands()))
require.Equal(t, 3, len(cmd.Commands()))
require.Equal(t, "capacity-by-denom", cmd.Commands()[0].Name())
require.Equal(t, "list-limit-params", cmd.Commands()[1].Name())
require.Equal(t, "pending-send-packets", cmd.Commands()[2].Name())
}
19 changes: 18 additions & 1 deletion protocol/x/ratelimit/types/keys.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package types

import fmt "fmt"
import (
"bytes"
"fmt"
"strconv"
)

// Module name and store keys
const (
Expand All @@ -27,3 +31,16 @@ const ()
func GetPendingSendPacketKey(channelId string, sequenceNumber uint64) []byte {
return []byte(fmt.Sprintf("%s_%d", channelId, sequenceNumber))
}

func SplitPendingSendPacketKey(key []byte) (channelId string, sequenceNumber uint64) {
affanv14 marked this conversation as resolved.
Show resolved Hide resolved
parts := bytes.Split(key, []byte("_"))
if len(parts) != 2 {
panic(fmt.Sprintf("unexpected key format: %s", key))
Copy link
Contributor

Choose a reason for hiding this comment

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

What does user see if we panic here? I assume nothing or some internal error?

Let's:

  • Log an error here so we could see this on server side
  • Also return this error so the user can see this error as well (easier for troubleshooting)

The error string could also be more helpful (e.g. "unexpected PendingSendPacket key format...")

}
channelId = string(parts[0])
// convert parts[1] to uint64 parts[1] is is a byte array with numeric characters of variable length

sequenceNumberInt, _ := strconv.Atoi(string(parts[1]))
sequenceNumber = uint64(sequenceNumberInt)
return
affanv14 marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading