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-839] add query for unconditional revshare #2380

Merged
merged 2 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LCDClient } from "@osmonauts/lcd";
import { QueryMarketMapperRevenueShareParams, QueryMarketMapperRevenueShareParamsResponseSDKType, QueryMarketMapperRevShareDetails, QueryMarketMapperRevShareDetailsResponseSDKType } from "./query";
import { QueryMarketMapperRevenueShareParams, QueryMarketMapperRevenueShareParamsResponseSDKType, QueryMarketMapperRevShareDetails, QueryMarketMapperRevShareDetailsResponseSDKType, QueryUnconditionalRevShareConfig, QueryUnconditionalRevShareConfigResponseSDKType } from "./query";
export class LCDQueryClient {
req: LCDClient;

Expand All @@ -11,6 +11,7 @@ export class LCDQueryClient {
this.req = requestClient;
this.marketMapperRevenueShareParams = this.marketMapperRevenueShareParams.bind(this);
this.marketMapperRevShareDetails = this.marketMapperRevShareDetails.bind(this);
this.unconditionalRevShareConfig = this.unconditionalRevShareConfig.bind(this);
}
/* MarketMapperRevenueShareParams queries the revenue share params for the
market mapper */
Expand All @@ -27,5 +28,12 @@ export class LCDQueryClient {
const endpoint = `dydxprotocol/revshare/market_mapper_rev_share_details/${params.marketId}`;
return await this.req.get<QueryMarketMapperRevShareDetailsResponseSDKType>(endpoint);
}
/* Queries unconditional revenue share config */


async unconditionalRevShareConfig(_params: QueryUnconditionalRevShareConfig = {}): Promise<QueryUnconditionalRevShareConfigResponseSDKType> {
const endpoint = `dydxprotocol/revshare/unconditional_rev_share`;
return await this.req.get<QueryUnconditionalRevShareConfigResponseSDKType>(endpoint);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Rpc } from "../../helpers";
import * as _m0 from "protobufjs/minimal";
import { QueryClient, createProtobufRpcClient } from "@cosmjs/stargate";
import { QueryMarketMapperRevenueShareParams, QueryMarketMapperRevenueShareParamsResponse, QueryMarketMapperRevShareDetails, QueryMarketMapperRevShareDetailsResponse } from "./query";
import { QueryMarketMapperRevenueShareParams, QueryMarketMapperRevenueShareParamsResponse, QueryMarketMapperRevShareDetails, QueryMarketMapperRevShareDetailsResponse, QueryUnconditionalRevShareConfig, QueryUnconditionalRevShareConfigResponse } from "./query";
/** Query defines the gRPC querier service. */

export interface Query {
Expand All @@ -13,6 +13,9 @@ export interface Query {
/** Queries market mapper revenue share details for a specific market */

marketMapperRevShareDetails(request: QueryMarketMapperRevShareDetails): Promise<QueryMarketMapperRevShareDetailsResponse>;
/** Queries unconditional revenue share config */

unconditionalRevShareConfig(request?: QueryUnconditionalRevShareConfig): Promise<QueryUnconditionalRevShareConfigResponse>;
}
export class QueryClientImpl implements Query {
private readonly rpc: Rpc;
Expand All @@ -21,6 +24,7 @@ export class QueryClientImpl implements Query {
this.rpc = rpc;
this.marketMapperRevenueShareParams = this.marketMapperRevenueShareParams.bind(this);
this.marketMapperRevShareDetails = this.marketMapperRevShareDetails.bind(this);
this.unconditionalRevShareConfig = this.unconditionalRevShareConfig.bind(this);
}

marketMapperRevenueShareParams(request: QueryMarketMapperRevenueShareParams = {}): Promise<QueryMarketMapperRevenueShareParamsResponse> {
Expand All @@ -35,6 +39,12 @@ export class QueryClientImpl implements Query {
return promise.then(data => QueryMarketMapperRevShareDetailsResponse.decode(new _m0.Reader(data)));
}

unconditionalRevShareConfig(request: QueryUnconditionalRevShareConfig = {}): Promise<QueryUnconditionalRevShareConfigResponse> {
const data = QueryUnconditionalRevShareConfig.encode(request).finish();
const promise = this.rpc.request("dydxprotocol.revshare.Query", "UnconditionalRevShareConfig", data);
return promise.then(data => QueryUnconditionalRevShareConfigResponse.decode(new _m0.Reader(data)));
}

}
export const createRpcQueryExtension = (base: QueryClient) => {
const rpc = createProtobufRpcClient(base);
Expand All @@ -46,6 +56,10 @@ export const createRpcQueryExtension = (base: QueryClient) => {

marketMapperRevShareDetails(request: QueryMarketMapperRevShareDetails): Promise<QueryMarketMapperRevShareDetailsResponse> {
return queryService.marketMapperRevShareDetails(request);
},

unconditionalRevShareConfig(request?: QueryUnconditionalRevShareConfig): Promise<QueryUnconditionalRevShareConfigResponse> {
return queryService.unconditionalRevShareConfig(request);
}

};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MarketMapperRevenueShareParams, MarketMapperRevenueShareParamsSDKType } from "./params";
import { MarketMapperRevShareDetails, MarketMapperRevShareDetailsSDKType } from "./revshare";
import { MarketMapperRevShareDetails, MarketMapperRevShareDetailsSDKType, UnconditionalRevShareConfig, UnconditionalRevShareConfigSDKType } from "./revshare";
import * as _m0 from "protobufjs/minimal";
import { DeepPartial } from "../../helpers";
/** Queries for the default market mapper revenue share params */
Expand Down Expand Up @@ -40,6 +40,22 @@ export interface QueryMarketMapperRevShareDetailsResponse {
export interface QueryMarketMapperRevShareDetailsResponseSDKType {
details?: MarketMapperRevShareDetailsSDKType;
}
/** Queries unconditional revenue share details */

export interface QueryUnconditionalRevShareConfig {}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace empty interfaces with type aliases

The interfaces QueryUnconditionalRevShareConfig and QueryUnconditionalRevShareConfigSDKType are empty. Since empty interfaces are equivalent to {}, consider using type aliases instead for clarity.

Apply this diff to fix the issue:

-export interface QueryUnconditionalRevShareConfig {}
+type QueryUnconditionalRevShareConfig = {};

-export interface QueryUnconditionalRevShareConfigSDKType {}
+type QueryUnconditionalRevShareConfigSDKType = {};

Also applies to: 48-48

🧰 Tools
🪛 Biome

[error] 45-45: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

/** Queries unconditional revenue share details */

export interface QueryUnconditionalRevShareConfigSDKType {}
/** Response type for QueryUnconditionalRevShareConfig */

export interface QueryUnconditionalRevShareConfigResponse {
config?: UnconditionalRevShareConfig;
}
/** Response type for QueryUnconditionalRevShareConfig */

export interface QueryUnconditionalRevShareConfigResponseSDKType {
config?: UnconditionalRevShareConfigSDKType;
}

function createBaseQueryMarketMapperRevenueShareParams(): QueryMarketMapperRevenueShareParams {
return {};
Expand Down Expand Up @@ -208,4 +224,83 @@ export const QueryMarketMapperRevShareDetailsResponse = {
return message;
}

};

function createBaseQueryUnconditionalRevShareConfig(): QueryUnconditionalRevShareConfig {
return {};
}

export const QueryUnconditionalRevShareConfig = {
encode(_: QueryUnconditionalRevShareConfig, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
return writer;
},

decode(input: _m0.Reader | Uint8Array, length?: number): QueryUnconditionalRevShareConfig {
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseQueryUnconditionalRevShareConfig();

while (reader.pos < end) {
const tag = reader.uint32();

switch (tag >>> 3) {
default:
reader.skipType(tag & 7);
break;
}
}

return message;
},

fromPartial(_: DeepPartial<QueryUnconditionalRevShareConfig>): QueryUnconditionalRevShareConfig {
const message = createBaseQueryUnconditionalRevShareConfig();
return message;
}

};

function createBaseQueryUnconditionalRevShareConfigResponse(): QueryUnconditionalRevShareConfigResponse {
return {
config: undefined
};
}

export const QueryUnconditionalRevShareConfigResponse = {
encode(message: QueryUnconditionalRevShareConfigResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.config !== undefined) {
UnconditionalRevShareConfig.encode(message.config, writer.uint32(10).fork()).ldelim();
}

return writer;
},

decode(input: _m0.Reader | Uint8Array, length?: number): QueryUnconditionalRevShareConfigResponse {
const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseQueryUnconditionalRevShareConfigResponse();

while (reader.pos < end) {
const tag = reader.uint32();

switch (tag >>> 3) {
case 1:
message.config = UnconditionalRevShareConfig.decode(reader, reader.uint32());
break;

default:
reader.skipType(tag & 7);
break;
}
}

return message;
},

fromPartial(object: DeepPartial<QueryUnconditionalRevShareConfigResponse>): QueryUnconditionalRevShareConfigResponse {
const message = createBaseQueryUnconditionalRevShareConfigResponse();
message.config = object.config !== undefined && object.config !== null ? UnconditionalRevShareConfig.fromPartial(object.config) : undefined;
return message;
}

};
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface Msg {
*/

setMarketMapperRevShareDetailsForMarket(request: MsgSetMarketMapperRevShareDetailsForMarket): Promise<MsgSetMarketMapperRevShareDetailsForMarketResponse>;
/** SetUnconditionalRevShareConfig sets the unconditional revshare config */
/** UpdateUnconditionalRevShareConfig sets the unconditional revshare config */

updateUnconditionalRevShareConfig(request: MsgUpdateUnconditionalRevShareConfig): Promise<MsgUpdateUnconditionalRevShareConfigResponse>;
}
Expand Down
17 changes: 16 additions & 1 deletion proto/dydxprotocol/revshare/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ service Query {
option (google.api.http).get =
"/dydxprotocol/revshare/market_mapper_rev_share_details/{market_id}";
}

// Queries unconditional revenue share config
rpc UnconditionalRevShareConfig(QueryUnconditionalRevShareConfig)
returns (QueryUnconditionalRevShareConfigResponse) {
option (google.api.http).get =
"/dydxprotocol/revshare/unconditional_rev_share";
}
}

// Queries for the default market mapper revenue share params
Expand All @@ -41,4 +48,12 @@ message QueryMarketMapperRevShareDetails { uint32 market_id = 1; }
// Response type for QueryMarketMapperRevShareDetails
message QueryMarketMapperRevShareDetailsResponse {
MarketMapperRevShareDetails details = 1 [ (gogoproto.nullable) = false ];
}
}

// Queries unconditional revenue share details
message QueryUnconditionalRevShareConfig {}

// Response type for QueryUnconditionalRevShareConfig
message QueryUnconditionalRevShareConfigResponse {
UnconditionalRevShareConfig config = 1 [ (gogoproto.nullable) = false ];
}
2 changes: 1 addition & 1 deletion proto/dydxprotocol/revshare/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ service Msg {
rpc SetMarketMapperRevShareDetailsForMarket(
MsgSetMarketMapperRevShareDetailsForMarket)
returns (MsgSetMarketMapperRevShareDetailsForMarketResponse);
// SetUnconditionalRevShareConfig sets the unconditional revshare config
// UpdateUnconditionalRevShareConfig sets the unconditional revshare config
rpc UpdateUnconditionalRevShareConfig(MsgUpdateUnconditionalRevShareConfig)
returns (MsgUpdateUnconditionalRevShareConfigResponse);
}
Expand Down
1 change: 1 addition & 0 deletions protocol/x/revshare/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(CmdQueryRevShareParams())
cmd.AddCommand(CmdQueryRevShareDetailsForMarket())
cmd.AddCommand(CmdQueryUnconditionalRevShareConfig())

return cmd
}
23 changes: 23 additions & 0 deletions protocol/x/revshare/client/cli/query_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,26 @@ func CmdQueryRevShareDetailsForMarket() *cobra.Command {

return cmd
}

func CmdQueryUnconditionalRevShareConfig() *cobra.Command {
cmd := &cobra.Command{
Use: "unconditional-revshare-config",
Short: "unconditional revshare config",
RunE: func(cmd *cobra.Command, args []string) (err error) {
clientCtx := client.GetClientContextFromCmd(cmd)
queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.UnconditionalRevShareConfig(
context.Background(),
&types.QueryUnconditionalRevShareConfig{},
)
if err != nil {
return err
}
return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
21 changes: 21 additions & 0 deletions protocol/x/revshare/keeper/grpc_query_unconditional_revshare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package keeper

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/dydxprotocol/v4-chain/protocol/x/revshare/types"
)

func (k Keeper) UnconditionalRevShareConfig(
ctx context.Context,
req *types.QueryUnconditionalRevShareConfig,
) (*types.QueryUnconditionalRevShareConfigResponse, error) {
config, err := k.GetUnconditionalRevShareConfigParams(sdk.UnwrapSDKContext(ctx))
if err != nil {
return nil, err
}
return &types.QueryUnconditionalRevShareConfigResponse{
Config: config,
}, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package keeper_test

import (
"testing"

testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app"
"github.com/dydxprotocol/v4-chain/protocol/testutil/constants"
"github.com/dydxprotocol/v4-chain/protocol/x/revshare/types"
"github.com/stretchr/testify/require"
)

func TestQueryUnconditionalRevShare(t *testing.T) {
testCases := map[string]struct {
config types.UnconditionalRevShareConfig
}{
"Single recipient": {
config: types.UnconditionalRevShareConfig{
Configs: []types.UnconditionalRevShareConfig_RecipientConfig{
{
Address: constants.AliceAccAddress.String(),
SharePpm: 100_000,
},
},
},
},
"Multiple recipients": {
config: types.UnconditionalRevShareConfig{
Configs: []types.UnconditionalRevShareConfig_RecipientConfig{
{
Address: constants.AliceAccAddress.String(),
SharePpm: 50_000,
},
{
Address: constants.BobAccAddress.String(),
SharePpm: 30_000,
},
},
},
},
"Empty config": {
config: types.UnconditionalRevShareConfig{},
},
}
Comment on lines +13 to +43
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding edge cases and invalid configurations.

The current test cases cover the main scenarios well. To enhance the robustness of the tests, consider adding the following cases:

  1. A configuration with the maximum allowed number of recipients.
  2. A configuration where the total SharePpm exceeds 1,000,000 (100%).
  3. A configuration with an invalid address.
  4. A configuration with a negative SharePpm.

These additional cases would help ensure proper error handling and validation in the UnconditionalRevShareConfig method.


for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
tApp := testapp.NewTestAppBuilder(t).Build()
ctx := tApp.InitChain()
k := tApp.App.RevShareKeeper

k.SetUnconditionalRevShareConfigParams(ctx, tc.config)

resp, err := k.UnconditionalRevShareConfig(ctx, &types.QueryUnconditionalRevShareConfig{})
require.NoError(t, err)
require.Equal(t, tc.config, resp.Config)
})
}
Comment on lines +45 to +57
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance error checking and add more assertions.

The test execution logic is generally correct, but consider the following improvements:

  1. Add an assertion to check that SetUnconditionalRevShareConfigParams succeeds:

    err := k.SetUnconditionalRevShareConfigParams(ctx, tc.config)
    require.NoError(t, err)
  2. For the query result, add more specific assertions:

    require.Equal(t, len(tc.config.Configs), len(resp.Config.Configs))
    for i, config := range tc.config.Configs {
        require.Equal(t, config.Address, resp.Config.Configs[i].Address)
        require.Equal(t, config.SharePpm, resp.Config.Configs[i].SharePpm)
    }

These changes will provide more detailed error messages if a test fails, making it easier to identify the exact point of failure.

}
Loading
Loading