From 7e7cbfe846f0f9196f1a0635b9fbdfbb356ab921 Mon Sep 17 00:00:00 2001 From: Roy Li Date: Tue, 23 Jan 2024 17:34:25 -0500 Subject: [PATCH] Scaffolding x/govplus module --- .../src/codegen/dydxprotocol/bundle.ts | 341 +++---- .../codegen/dydxprotocol/govplus/genesis.ts | 42 + .../dydxprotocol/govplus/query.rpc.Query.ts | 18 + .../src/codegen/dydxprotocol/govplus/query.ts | 1 + .../src/codegen/dydxprotocol/govplus/tx.ts | 1 + .../src/codegen/dydxprotocol/rpc.query.ts | 1 + .../v4-protos/src/codegen/gogoproto/bundle.ts | 4 +- .../v4-protos/src/codegen/google/bundle.ts | 24 +- proto/dydxprotocol/govplus/genesis.proto | 7 + proto/dydxprotocol/govplus/query.proto | 7 + proto/dydxprotocol/govplus/tx.proto | 7 + protocol/app/app.go | 22 +- protocol/app/app_test.go | 2 + .../app/testdata/default_genesis_state.json | 1 + protocol/app/upgrades/v4.0.0/constants.go | 2 + .../scripts/genesis/sample_pregenesis.json | 1 + protocol/testutil/constants/genesis.go | 1 + protocol/x/govplus/client/cli/query.go | 24 + protocol/x/govplus/client/cli/tx.go | 28 + protocol/x/govplus/genesis.go | 15 + protocol/x/govplus/keeper/keeper.go | 44 + protocol/x/govplus/keeper/keeper_test.go | 848 ++++++++++++++++++ protocol/x/govplus/keeper/msg_server.go | 17 + protocol/x/govplus/keeper/msg_server_test.go | 26 + protocol/x/govplus/module.go | 150 ++++ protocol/x/govplus/types/codec.go | 19 + protocol/x/govplus/types/genesis.go | 12 + protocol/x/govplus/types/genesis.pb.go | 265 ++++++ protocol/x/govplus/types/keys.go | 10 + protocol/x/govplus/types/keys_test.go | 13 + protocol/x/govplus/types/query.pb.go | 81 ++ protocol/x/govplus/types/tx.pb.go | 81 ++ 32 files changed, 1934 insertions(+), 181 deletions(-) create mode 100644 indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/genesis.ts create mode 100644 indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.rpc.Query.ts create mode 100644 indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.ts create mode 100644 indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/tx.ts create mode 100644 proto/dydxprotocol/govplus/genesis.proto create mode 100644 proto/dydxprotocol/govplus/query.proto create mode 100644 proto/dydxprotocol/govplus/tx.proto create mode 100644 protocol/x/govplus/client/cli/query.go create mode 100644 protocol/x/govplus/client/cli/tx.go create mode 100644 protocol/x/govplus/genesis.go create mode 100644 protocol/x/govplus/keeper/keeper.go create mode 100644 protocol/x/govplus/keeper/keeper_test.go create mode 100644 protocol/x/govplus/keeper/msg_server.go create mode 100644 protocol/x/govplus/keeper/msg_server_test.go create mode 100644 protocol/x/govplus/module.go create mode 100644 protocol/x/govplus/types/codec.go create mode 100644 protocol/x/govplus/types/genesis.go create mode 100644 protocol/x/govplus/types/genesis.pb.go create mode 100644 protocol/x/govplus/types/keys.go create mode 100644 protocol/x/govplus/types/keys_test.go create mode 100644 protocol/x/govplus/types/query.pb.go create mode 100644 protocol/x/govplus/types/tx.pb.go diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/bundle.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/bundle.ts index 680ae1ba545..fcbccb4917d 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/bundle.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/bundle.ts @@ -42,112 +42,116 @@ import * as _45 from "./feetiers/genesis"; import * as _46 from "./feetiers/params"; import * as _47 from "./feetiers/query"; import * as _48 from "./feetiers/tx"; -import * as _49 from "./indexer/events/events"; -import * as _50 from "./indexer/indexer_manager/event"; -import * as _51 from "./indexer/off_chain_updates/off_chain_updates"; -import * as _52 from "./indexer/protocol/v1/clob"; -import * as _53 from "./indexer/protocol/v1/subaccount"; -import * as _54 from "./indexer/redis/redis_order"; -import * as _55 from "./indexer/shared/removal_reason"; -import * as _56 from "./indexer/socks/messages"; -import * as _57 from "./perpetuals/genesis"; -import * as _58 from "./perpetuals/params"; -import * as _59 from "./perpetuals/perpetual"; -import * as _60 from "./perpetuals/query"; -import * as _61 from "./perpetuals/tx"; -import * as _62 from "./prices/genesis"; -import * as _63 from "./prices/market_param"; -import * as _64 from "./prices/market_price"; -import * as _65 from "./prices/query"; -import * as _66 from "./prices/tx"; -import * as _67 from "./ratelimit/capacity"; -import * as _68 from "./ratelimit/genesis"; -import * as _69 from "./ratelimit/limit_params"; -import * as _70 from "./ratelimit/query"; -import * as _71 from "./ratelimit/tx"; -import * as _72 from "./rewards/genesis"; -import * as _73 from "./rewards/params"; -import * as _74 from "./rewards/query"; -import * as _75 from "./rewards/reward_share"; -import * as _76 from "./rewards/tx"; -import * as _77 from "./sending/genesis"; -import * as _78 from "./sending/query"; -import * as _79 from "./sending/transfer"; -import * as _80 from "./sending/tx"; -import * as _81 from "./stats/genesis"; -import * as _82 from "./stats/params"; -import * as _83 from "./stats/query"; -import * as _84 from "./stats/stats"; -import * as _85 from "./stats/tx"; -import * as _86 from "./subaccounts/asset_position"; -import * as _87 from "./subaccounts/genesis"; -import * as _88 from "./subaccounts/perpetual_position"; -import * as _89 from "./subaccounts/query"; -import * as _90 from "./subaccounts/subaccount"; -import * as _91 from "./vest/genesis"; -import * as _92 from "./vest/query"; -import * as _93 from "./vest/tx"; -import * as _94 from "./vest/vest_entry"; -import * as _102 from "./assets/query.lcd"; -import * as _103 from "./blocktime/query.lcd"; -import * as _104 from "./bridge/query.lcd"; -import * as _105 from "./clob/query.lcd"; -import * as _106 from "./delaymsg/query.lcd"; -import * as _107 from "./epochs/query.lcd"; -import * as _108 from "./feetiers/query.lcd"; -import * as _109 from "./perpetuals/query.lcd"; -import * as _110 from "./prices/query.lcd"; -import * as _111 from "./ratelimit/query.lcd"; -import * as _112 from "./rewards/query.lcd"; -import * as _113 from "./stats/query.lcd"; -import * as _114 from "./subaccounts/query.lcd"; -import * as _115 from "./vest/query.lcd"; -import * as _116 from "./assets/query.rpc.Query"; -import * as _117 from "./blocktime/query.rpc.Query"; -import * as _118 from "./bridge/query.rpc.Query"; -import * as _119 from "./clob/query.rpc.Query"; -import * as _120 from "./delaymsg/query.rpc.Query"; -import * as _121 from "./epochs/query.rpc.Query"; -import * as _122 from "./feetiers/query.rpc.Query"; -import * as _123 from "./perpetuals/query.rpc.Query"; -import * as _124 from "./prices/query.rpc.Query"; -import * as _125 from "./ratelimit/query.rpc.Query"; -import * as _126 from "./rewards/query.rpc.Query"; -import * as _127 from "./sending/query.rpc.Query"; -import * as _128 from "./stats/query.rpc.Query"; -import * as _129 from "./subaccounts/query.rpc.Query"; -import * as _130 from "./vest/query.rpc.Query"; -import * as _131 from "./blocktime/tx.rpc.msg"; -import * as _132 from "./bridge/tx.rpc.msg"; -import * as _133 from "./clob/tx.rpc.msg"; -import * as _134 from "./delaymsg/tx.rpc.msg"; -import * as _135 from "./feetiers/tx.rpc.msg"; -import * as _136 from "./perpetuals/tx.rpc.msg"; -import * as _137 from "./prices/tx.rpc.msg"; -import * as _138 from "./ratelimit/tx.rpc.msg"; -import * as _139 from "./rewards/tx.rpc.msg"; -import * as _140 from "./sending/tx.rpc.msg"; -import * as _141 from "./stats/tx.rpc.msg"; -import * as _142 from "./vest/tx.rpc.msg"; -import * as _143 from "./lcd"; -import * as _144 from "./rpc.query"; -import * as _145 from "./rpc.tx"; +import * as _49 from "./govplus/genesis"; +import * as _50 from "./govplus/query"; +import * as _51 from "./govplus/tx"; +import * as _52 from "./indexer/events/events"; +import * as _53 from "./indexer/indexer_manager/event"; +import * as _54 from "./indexer/off_chain_updates/off_chain_updates"; +import * as _55 from "./indexer/protocol/v1/clob"; +import * as _56 from "./indexer/protocol/v1/subaccount"; +import * as _57 from "./indexer/redis/redis_order"; +import * as _58 from "./indexer/shared/removal_reason"; +import * as _59 from "./indexer/socks/messages"; +import * as _60 from "./perpetuals/genesis"; +import * as _61 from "./perpetuals/params"; +import * as _62 from "./perpetuals/perpetual"; +import * as _63 from "./perpetuals/query"; +import * as _64 from "./perpetuals/tx"; +import * as _65 from "./prices/genesis"; +import * as _66 from "./prices/market_param"; +import * as _67 from "./prices/market_price"; +import * as _68 from "./prices/query"; +import * as _69 from "./prices/tx"; +import * as _70 from "./ratelimit/capacity"; +import * as _71 from "./ratelimit/genesis"; +import * as _72 from "./ratelimit/limit_params"; +import * as _73 from "./ratelimit/query"; +import * as _74 from "./ratelimit/tx"; +import * as _75 from "./rewards/genesis"; +import * as _76 from "./rewards/params"; +import * as _77 from "./rewards/query"; +import * as _78 from "./rewards/reward_share"; +import * as _79 from "./rewards/tx"; +import * as _80 from "./sending/genesis"; +import * as _81 from "./sending/query"; +import * as _82 from "./sending/transfer"; +import * as _83 from "./sending/tx"; +import * as _84 from "./stats/genesis"; +import * as _85 from "./stats/params"; +import * as _86 from "./stats/query"; +import * as _87 from "./stats/stats"; +import * as _88 from "./stats/tx"; +import * as _89 from "./subaccounts/asset_position"; +import * as _90 from "./subaccounts/genesis"; +import * as _91 from "./subaccounts/perpetual_position"; +import * as _92 from "./subaccounts/query"; +import * as _93 from "./subaccounts/subaccount"; +import * as _94 from "./vest/genesis"; +import * as _95 from "./vest/query"; +import * as _96 from "./vest/tx"; +import * as _97 from "./vest/vest_entry"; +import * as _105 from "./assets/query.lcd"; +import * as _106 from "./blocktime/query.lcd"; +import * as _107 from "./bridge/query.lcd"; +import * as _108 from "./clob/query.lcd"; +import * as _109 from "./delaymsg/query.lcd"; +import * as _110 from "./epochs/query.lcd"; +import * as _111 from "./feetiers/query.lcd"; +import * as _112 from "./perpetuals/query.lcd"; +import * as _113 from "./prices/query.lcd"; +import * as _114 from "./ratelimit/query.lcd"; +import * as _115 from "./rewards/query.lcd"; +import * as _116 from "./stats/query.lcd"; +import * as _117 from "./subaccounts/query.lcd"; +import * as _118 from "./vest/query.lcd"; +import * as _119 from "./assets/query.rpc.Query"; +import * as _120 from "./blocktime/query.rpc.Query"; +import * as _121 from "./bridge/query.rpc.Query"; +import * as _122 from "./clob/query.rpc.Query"; +import * as _123 from "./delaymsg/query.rpc.Query"; +import * as _124 from "./epochs/query.rpc.Query"; +import * as _125 from "./feetiers/query.rpc.Query"; +import * as _126 from "./govplus/query.rpc.Query"; +import * as _127 from "./perpetuals/query.rpc.Query"; +import * as _128 from "./prices/query.rpc.Query"; +import * as _129 from "./ratelimit/query.rpc.Query"; +import * as _130 from "./rewards/query.rpc.Query"; +import * as _131 from "./sending/query.rpc.Query"; +import * as _132 from "./stats/query.rpc.Query"; +import * as _133 from "./subaccounts/query.rpc.Query"; +import * as _134 from "./vest/query.rpc.Query"; +import * as _135 from "./blocktime/tx.rpc.msg"; +import * as _136 from "./bridge/tx.rpc.msg"; +import * as _137 from "./clob/tx.rpc.msg"; +import * as _138 from "./delaymsg/tx.rpc.msg"; +import * as _139 from "./feetiers/tx.rpc.msg"; +import * as _140 from "./perpetuals/tx.rpc.msg"; +import * as _141 from "./prices/tx.rpc.msg"; +import * as _142 from "./ratelimit/tx.rpc.msg"; +import * as _143 from "./rewards/tx.rpc.msg"; +import * as _144 from "./sending/tx.rpc.msg"; +import * as _145 from "./stats/tx.rpc.msg"; +import * as _146 from "./vest/tx.rpc.msg"; +import * as _147 from "./lcd"; +import * as _148 from "./rpc.query"; +import * as _149 from "./rpc.tx"; export namespace dydxprotocol { export const assets = { ..._5, ..._6, ..._7, ..._8, - ..._102, - ..._116 + ..._105, + ..._119 }; export const blocktime = { ..._9, ..._10, ..._11, ..._12, ..._13, - ..._103, - ..._117, - ..._131 + ..._106, + ..._120, + ..._135 }; export const bridge = { ..._14, ..._15, @@ -155,9 +159,9 @@ export namespace dydxprotocol { ..._17, ..._18, ..._19, - ..._104, - ..._118, - ..._132 + ..._107, + ..._121, + ..._136 }; export const clob = { ..._20, ..._21, @@ -173,9 +177,9 @@ export namespace dydxprotocol { ..._31, ..._32, ..._33, - ..._105, - ..._119, - ..._133 + ..._108, + ..._122, + ..._137 }; export namespace daemons { export const bridge = { ..._34 @@ -190,113 +194,118 @@ export namespace dydxprotocol { ..._39, ..._40, ..._41, - ..._106, - ..._120, - ..._134 + ..._109, + ..._123, + ..._138 }; export const epochs = { ..._42, ..._43, ..._44, - ..._107, - ..._121 + ..._110, + ..._124 }; export const feetiers = { ..._45, ..._46, ..._47, ..._48, - ..._108, - ..._122, - ..._135 + ..._111, + ..._125, + ..._139 + }; + export const govplus = { ..._49, + ..._50, + ..._51, + ..._126 }; export namespace indexer { - export const events = { ..._49 + export const events = { ..._52 }; - export const indexer_manager = { ..._50 + export const indexer_manager = { ..._53 }; - export const off_chain_updates = { ..._51 + export const off_chain_updates = { ..._54 }; export namespace protocol { - export const v1 = { ..._52, - ..._53 + export const v1 = { ..._55, + ..._56 }; } - export const redis = { ..._54 + export const redis = { ..._57 }; - export const shared = { ..._55 + export const shared = { ..._58 }; - export const socks = { ..._56 + export const socks = { ..._59 }; } - export const perpetuals = { ..._57, - ..._58, - ..._59, - ..._60, + export const perpetuals = { ..._60, ..._61, - ..._109, - ..._123, - ..._136 - }; - export const prices = { ..._62, + ..._62, ..._63, ..._64, - ..._65, - ..._66, - ..._110, - ..._124, - ..._137 + ..._112, + ..._127, + ..._140 }; - export const ratelimit = { ..._67, + export const prices = { ..._65, + ..._66, + ..._67, ..._68, ..._69, - ..._70, - ..._71, - ..._111, - ..._125, - ..._138 + ..._113, + ..._128, + ..._141 }; - export const rewards = { ..._72, + export const ratelimit = { ..._70, + ..._71, + ..._72, ..._73, ..._74, - ..._75, - ..._76, - ..._112, - ..._126, - ..._139 + ..._114, + ..._129, + ..._142 }; - export const sending = { ..._77, + export const rewards = { ..._75, + ..._76, + ..._77, ..._78, ..._79, - ..._80, - ..._127, - ..._140 + ..._115, + ..._130, + ..._143 }; - export const stats = { ..._81, + export const sending = { ..._80, + ..._81, ..._82, ..._83, - ..._84, - ..._85, - ..._113, - ..._128, - ..._141 + ..._131, + ..._144 }; - export const subaccounts = { ..._86, + export const stats = { ..._84, + ..._85, + ..._86, ..._87, ..._88, - ..._89, - ..._90, - ..._114, - ..._129 + ..._116, + ..._132, + ..._145 }; - export const vest = { ..._91, + export const subaccounts = { ..._89, + ..._90, + ..._91, ..._92, ..._93, - ..._94, - ..._115, - ..._130, - ..._142 + ..._117, + ..._133 }; - export const ClientFactory = { ..._143, - ..._144, - ..._145 + export const vest = { ..._94, + ..._95, + ..._96, + ..._97, + ..._118, + ..._134, + ..._146 + }; + export const ClientFactory = { ..._147, + ..._148, + ..._149 }; } \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/genesis.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/genesis.ts new file mode 100644 index 00000000000..54233c04a5a --- /dev/null +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/genesis.ts @@ -0,0 +1,42 @@ +import * as _m0 from "protobufjs/minimal"; +import { DeepPartial } from "../../helpers"; +/** GenesisState defines the govplus module's genesis state. */ + +export interface GenesisState {} +/** GenesisState defines the govplus module's genesis state. */ + +export interface GenesisStateSDKType {} + +function createBaseGenesisState(): GenesisState { + return {}; +} + +export const GenesisState = { + encode(_: GenesisState, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): GenesisState { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGenesisState(); + + while (reader.pos < end) { + const tag = reader.uint32(); + + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + + return message; + }, + + fromPartial(_: DeepPartial): GenesisState { + const message = createBaseGenesisState(); + return message; + } + +}; \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.rpc.Query.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.rpc.Query.ts new file mode 100644 index 00000000000..ab81adee85c --- /dev/null +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.rpc.Query.ts @@ -0,0 +1,18 @@ +import { Rpc } from "../../helpers"; +import { QueryClient, createProtobufRpcClient } from "@cosmjs/stargate"; +/** Query defines the gRPC querier service. */ + +export interface Query {} +export class QueryClientImpl implements Query { + private readonly rpc: Rpc; + + constructor(rpc: Rpc) { + this.rpc = rpc; + } + +} +export const createRpcQueryExtension = (base: QueryClient) => { + const rpc = createProtobufRpcClient(base); + const queryService = new QueryClientImpl(rpc); + return {}; +}; \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.ts new file mode 100644 index 00000000000..693da49fc40 --- /dev/null +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/query.ts @@ -0,0 +1 @@ +export {} \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/tx.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/tx.ts new file mode 100644 index 00000000000..693da49fc40 --- /dev/null +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/govplus/tx.ts @@ -0,0 +1 @@ +export {} \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/rpc.query.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/rpc.query.ts index 546196beebb..8660a20d09b 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/rpc.query.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/rpc.query.ts @@ -16,6 +16,7 @@ export const createRPCQueryClient = async ({ delaymsg: (await import("./delaymsg/query.rpc.Query")).createRpcQueryExtension(client), epochs: (await import("./epochs/query.rpc.Query")).createRpcQueryExtension(client), feetiers: (await import("./feetiers/query.rpc.Query")).createRpcQueryExtension(client), + govplus: (await import("./govplus/query.rpc.Query")).createRpcQueryExtension(client), perpetuals: (await import("./perpetuals/query.rpc.Query")).createRpcQueryExtension(client), prices: (await import("./prices/query.rpc.Query")).createRpcQueryExtension(client), ratelimit: (await import("./ratelimit/query.rpc.Query")).createRpcQueryExtension(client), diff --git a/indexer/packages/v4-protos/src/codegen/gogoproto/bundle.ts b/indexer/packages/v4-protos/src/codegen/gogoproto/bundle.ts index 545e2a809e0..00726066d76 100644 --- a/indexer/packages/v4-protos/src/codegen/gogoproto/bundle.ts +++ b/indexer/packages/v4-protos/src/codegen/gogoproto/bundle.ts @@ -1,3 +1,3 @@ -import * as _95 from "./gogo"; -export const gogoproto = { ..._95 +import * as _98 from "./gogo"; +export const gogoproto = { ..._98 }; \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/google/bundle.ts b/indexer/packages/v4-protos/src/codegen/google/bundle.ts index c920ab8cb51..dcfe2ea382b 100644 --- a/indexer/packages/v4-protos/src/codegen/google/bundle.ts +++ b/indexer/packages/v4-protos/src/codegen/google/bundle.ts @@ -1,16 +1,16 @@ -import * as _96 from "./api/annotations"; -import * as _97 from "./api/http"; -import * as _98 from "./protobuf/descriptor"; -import * as _99 from "./protobuf/duration"; -import * as _100 from "./protobuf/timestamp"; -import * as _101 from "./protobuf/any"; +import * as _99 from "./api/annotations"; +import * as _100 from "./api/http"; +import * as _101 from "./protobuf/descriptor"; +import * as _102 from "./protobuf/duration"; +import * as _103 from "./protobuf/timestamp"; +import * as _104 from "./protobuf/any"; export namespace google { - export const api = { ..._96, - ..._97 + export const api = { ..._99, + ..._100 }; - export const protobuf = { ..._98, - ..._99, - ..._100, - ..._101 + export const protobuf = { ..._101, + ..._102, + ..._103, + ..._104 }; } \ No newline at end of file diff --git a/proto/dydxprotocol/govplus/genesis.proto b/proto/dydxprotocol/govplus/genesis.proto new file mode 100644 index 00000000000..fd3ba92322c --- /dev/null +++ b/proto/dydxprotocol/govplus/genesis.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; +package dydxprotocol.govplus; + +option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types"; + +// GenesisState defines the govplus module's genesis state. +message GenesisState {} diff --git a/proto/dydxprotocol/govplus/query.proto b/proto/dydxprotocol/govplus/query.proto new file mode 100644 index 00000000000..434a45a3be6 --- /dev/null +++ b/proto/dydxprotocol/govplus/query.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; +package dydxprotocol.govplus; + +option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types"; + +// Query defines the gRPC querier service. +service Query {} diff --git a/proto/dydxprotocol/govplus/tx.proto b/proto/dydxprotocol/govplus/tx.proto new file mode 100644 index 00000000000..3c509230ce3 --- /dev/null +++ b/proto/dydxprotocol/govplus/tx.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; +package dydxprotocol.govplus; + +option go_package = "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types"; + +// Msg defines the Msg service. +service Msg {} diff --git a/protocol/app/app.go b/protocol/app/app.go index 7bdd5789418..afc47ca1f9c 100644 --- a/protocol/app/app.go +++ b/protocol/app/app.go @@ -3,7 +3,6 @@ package app import ( "context" "encoding/json" - custommodule "github.com/dydxprotocol/v4-chain/protocol/app/module" "io" "math/big" "net/http" @@ -13,6 +12,8 @@ import ( "sync" "time" + custommodule "github.com/dydxprotocol/v4-chain/protocol/app/module" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" "cosmossdk.io/log" @@ -144,6 +145,9 @@ import ( feetiersmodule "github.com/dydxprotocol/v4-chain/protocol/x/feetiers" feetiersmodulekeeper "github.com/dydxprotocol/v4-chain/protocol/x/feetiers/keeper" feetiersmoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/feetiers/types" + govplusmodule "github.com/dydxprotocol/v4-chain/protocol/x/govplus" + govplusmodulekeeper "github.com/dydxprotocol/v4-chain/protocol/x/govplus/keeper" + govplusmoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" perpetualsmodule "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals" perpetualsmodulekeeper "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/keeper" perpetualsmoduletypes "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals/types" @@ -251,6 +255,7 @@ type App struct { RatelimitKeeper ratelimitmodulekeeper.Keeper FeeGrantKeeper feegrantkeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper + GovPlusKeeper govplusmodulekeeper.Keeper PricesKeeper pricesmodulekeeper.Keeper @@ -975,6 +980,16 @@ func New( app.SubaccountsKeeper, ) + app.GovPlusKeeper = *govplusmodulekeeper.NewKeeper( + appCodec, + keys[govplusmoduletypes.StoreKey], + []string{ + lib.GovModuleAddress.String(), + delaymsgmoduletypes.ModuleAddress.String(), + }, + ) + govPlusModule := govplusmodule.NewAppModule(appCodec, app.GovPlusKeeper) + /**** Module Options ****/ // NOTE: we may consider parsing `appOpts` inside module constructors. For the moment @@ -1037,6 +1052,7 @@ func New( subaccountsModule, clobModule, sendingModule, + govPlusModule, delayMsgModule, epochsModule, ) @@ -1080,6 +1096,7 @@ func New( vestmoduletypes.ModuleName, rewardsmoduletypes.ModuleName, sendingmoduletypes.ModuleName, + govplusmoduletypes.ModuleName, delaymsgmoduletypes.ModuleName, ) @@ -1118,6 +1135,7 @@ func New( vestmoduletypes.ModuleName, rewardsmoduletypes.ModuleName, epochsmoduletypes.ModuleName, + govplusmoduletypes.ModuleName, delaymsgmoduletypes.ModuleName, blocktimemoduletypes.ModuleName, // Must be last ) @@ -1159,6 +1177,7 @@ func New( vestmoduletypes.ModuleName, rewardsmoduletypes.ModuleName, sendingmoduletypes.ModuleName, + govplusmoduletypes.ModuleName, delaymsgmoduletypes.ModuleName, ) @@ -1196,6 +1215,7 @@ func New( vestmoduletypes.ModuleName, rewardsmoduletypes.ModuleName, sendingmoduletypes.ModuleName, + govplusmoduletypes.ModuleName, delaymsgmoduletypes.ModuleName, // Auth must be migrated after staking. diff --git a/protocol/app/app_test.go b/protocol/app/app_test.go index 1f3f489e90d..0f0cf5685a1 100644 --- a/protocol/app/app_test.go +++ b/protocol/app/app_test.go @@ -38,6 +38,7 @@ import ( delaymsgmodule "github.com/dydxprotocol/v4-chain/protocol/x/delaymsg" epochsmodule "github.com/dydxprotocol/v4-chain/protocol/x/epochs" feetiersmodule "github.com/dydxprotocol/v4-chain/protocol/x/feetiers" + govplusmodule "github.com/dydxprotocol/v4-chain/protocol/x/govplus" perpetualsmodule "github.com/dydxprotocol/v4-chain/protocol/x/perpetuals" pricesmodule "github.com/dydxprotocol/v4-chain/protocol/x/prices" rewardsmodule "github.com/dydxprotocol/v4-chain/protocol/x/rewards" @@ -212,6 +213,7 @@ func TestModuleBasics(t *testing.T) { vestmodule.AppModuleBasic{}, rewardsmodule.AppModuleBasic{}, sendingmodule.AppModuleBasic{}, + govplusmodule.AppModuleBasic{}, delaymsgmodule.AppModuleBasic{}, epochsmodule.AppModuleBasic{}, ) diff --git a/protocol/app/testdata/default_genesis_state.json b/protocol/app/testdata/default_genesis_state.json index f26342d6283..31089a9995a 100644 --- a/protocol/app/testdata/default_genesis_state.json +++ b/protocol/app/testdata/default_genesis_state.json @@ -278,6 +278,7 @@ }, "constitution": "" }, + "govplus": {}, "ibc": { "client_genesis": { "clients": [], diff --git a/protocol/app/upgrades/v4.0.0/constants.go b/protocol/app/upgrades/v4.0.0/constants.go index a4d58c40d2d..2a2bfbdc198 100644 --- a/protocol/app/upgrades/v4.0.0/constants.go +++ b/protocol/app/upgrades/v4.0.0/constants.go @@ -5,6 +5,7 @@ import ( circuittypes "cosmossdk.io/x/circuit/types" icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" "github.com/dydxprotocol/v4-chain/protocol/app/upgrades" + govplustypes "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" ) const ( @@ -15,6 +16,7 @@ var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, StoreUpgrades: store.StoreUpgrades{ Added: []string{ + govplustypes.StoreKey, // Add circuittypes as per 0.47 to 0.50 upgrade handler // https://github.com/cosmos/cosmos-sdk/blob/b7d9d4c8a9b6b8b61716d2023982d29bdc9839a6/simapp/upgrades.go#L21 circuittypes.ModuleName, diff --git a/protocol/scripts/genesis/sample_pregenesis.json b/protocol/scripts/genesis/sample_pregenesis.json index 9a3c4fb8d65..cd5dbbeb1ec 100644 --- a/protocol/scripts/genesis/sample_pregenesis.json +++ b/protocol/scripts/genesis/sample_pregenesis.json @@ -788,6 +788,7 @@ "starting_proposal_id": "1", "votes": [] }, + "govplus": {}, "ibc": { "channel_genesis": { "ack_sequences": [], diff --git a/protocol/testutil/constants/genesis.go b/protocol/testutil/constants/genesis.go index 43bcc2a0d8f..26df9300a1c 100644 --- a/protocol/testutil/constants/genesis.go +++ b/protocol/testutil/constants/genesis.go @@ -844,6 +844,7 @@ const GenesisState = `{ "starting_proposal_id": "1", "votes": [] }, + "govplus": {}, "ibc": { "channel_genesis": { "ack_sequences": [], diff --git a/protocol/x/govplus/client/cli/query.go b/protocol/x/govplus/client/cli/query.go new file mode 100644 index 00000000000..8299ba0beb5 --- /dev/null +++ b/protocol/x/govplus/client/cli/query.go @@ -0,0 +1,24 @@ +package cli + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string) *cobra.Command { + // Group govplus queries under a subcommand + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + return cmd +} diff --git a/protocol/x/govplus/client/cli/tx.go b/protocol/x/govplus/client/cli/tx.go new file mode 100644 index 00000000000..e7c8f345804 --- /dev/null +++ b/protocol/x/govplus/client/cli/tx.go @@ -0,0 +1,28 @@ +package cli + +import ( + "fmt" + "time" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types" +) + +var ( + DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds()) +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + return cmd +} diff --git a/protocol/x/govplus/genesis.go b/protocol/x/govplus/genesis.go new file mode 100644 index 00000000000..2b749cecc2b --- /dev/null +++ b/protocol/x/govplus/genesis.go @@ -0,0 +1,15 @@ +package govplus + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/keeper" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" +) + +// InitGenesis initializes the govplus module's state from a provided genesis state. +func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) {} + +// ExportGenesis returns the govplus module's exported genesis. +func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { + return &types.GenesisState{} +} diff --git a/protocol/x/govplus/keeper/keeper.go b/protocol/x/govplus/keeper/keeper.go new file mode 100644 index 00000000000..558859fa89d --- /dev/null +++ b/protocol/x/govplus/keeper/keeper.go @@ -0,0 +1,44 @@ +package keeper + +import ( + "fmt" + + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/dydxprotocol/v4-chain/protocol/lib" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" +) + +type ( + Keeper struct { + cdc codec.BinaryCodec + storeKey storetypes.StoreKey + authorities map[string]struct{} + } +) + +func NewKeeper( + cdc codec.BinaryCodec, + storeKey storetypes.StoreKey, + authorities []string, +) *Keeper { + return &Keeper{ + cdc: cdc, + storeKey: storeKey, + authorities: lib.UniqueSliceToSet(authorities), + } +} + +func (k Keeper) HasAuthority(authority string) bool { + _, ok := k.authorities[authority] + return ok +} + +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With(log.ModuleKey, fmt.Sprintf("x/%s", types.ModuleName)) +} + +func (k Keeper) InitializeForGenesis(ctx sdk.Context) { +} diff --git a/protocol/x/govplus/keeper/keeper_test.go b/protocol/x/govplus/keeper/keeper_test.go new file mode 100644 index 00000000000..9b340de71d8 --- /dev/null +++ b/protocol/x/govplus/keeper/keeper_test.go @@ -0,0 +1,848 @@ +package keeper_test + +import ( + "math/big" + "testing" + "time" + + sdkmath "cosmossdk.io/math" + + cometbfttypes "github.com/cometbft/cometbft/types" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/dydxprotocol/v4-chain/protocol/dtypes" + testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" + big_testutil "github.com/dydxprotocol/v4-chain/protocol/testutil/big" + blocktimetypes "github.com/dydxprotocol/v4-chain/protocol/x/blocktime/types" + "github.com/dydxprotocol/v4-chain/protocol/x/ratelimit/types" + "github.com/stretchr/testify/require" +) + +const ( + testDenom = "ibc/xxx" + testDenom2 = "testdenom2" + testAddress1 = "dydx16h7p7f4dysrgtzptxx2gtpt5d8t834g9dj830z" + testAddress2 = "dydx168pjt8rkru35239fsqvz7rzgeclakp49zx3aum" + testAddress3 = "dydx1fjg6zp6vv8t9wvy4lps03r5l4g7tkjw9wvmh70" +) + +func TestSetGetDenomCapacity(t *testing.T) { + tApp := testapp.NewTestAppBuilder(t).Build() + ctx := tApp.InitChain() + k := tApp.App.RatelimitKeeper + + capacityList := []dtypes.SerializableInt{ + dtypes.NewInt(123_456_789), + dtypes.NewInt(500_000_000), + } + denomCapacity := types.DenomCapacity{ + Denom: testDenom, + CapacityList: capacityList, + } + + // Test SetDenomCapacity + k.SetDenomCapacity(ctx, denomCapacity) + + // Test GetDenomCapacity + gotDenomCapacity := k.GetDenomCapacity(ctx, testDenom) + require.Equal(t, denomCapacity, gotDenomCapacity, "retrieved DenomCapacity does not match the set value") + + k.SetDenomCapacity(ctx, types.DenomCapacity{ + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{}, // Empty list, results in deletion of the key. + }) + + // Check that the key is deleted under `DenomCapacity` storage. + require.Equal(t, + types.DenomCapacity{ + Denom: testDenom, + CapacityList: nil, + }, + k.GetDenomCapacity(ctx, testDenom), + "retrieved LimitParams do not match the set value", + ) +} + +func TestSetGetLimitParams_Success(t *testing.T) { + // Run tests. + tests := map[string]struct { + denom string + balances []banktypes.Balance + limiters []types.Limiter + expectedCapacityList []dtypes.SerializableInt + }{ + "0 TVL, capactiy correctly initialized as minimum baseline": { + denom: testDenom, + limiters: []types.Limiter{ + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1m tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + expectedCapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(100_000_000_000), + dtypes.NewInt(1_000_000_000_000), + }, + }, + "50m TVL, capactiy correctly initialized to 1% and 10%": { + denom: testDenom, + limiters: []types.Limiter{ + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1m tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token + }, + }, + }, + { + Address: testAddress2, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token + }, + }, + }, + }, + expectedCapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(500_000_000_000), // 500k tokens (1% of 50m) + dtypes.NewInt(5_000_000_000_000), // 5m tokens (10% of 50m) + }, + }, + "50m TVL, capactiy correctly initialized to 5% and 20% (rounds down)": { + denom: testDenom, + limiters: []types.Limiter{ + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 50_000, // 5% + }, + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1m tokens (assuming 6 decimals) + BaselineTvlPpm: 200_000, // 20% + }, + }, + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_123_450_000_000), // 25M token + }, + }, + }, + { + Address: testAddress2, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token + }, + }, + }, + }, + expectedCapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(2_506_172_500_000), // ~2.5M tokens (5% of ~50m) + dtypes.NewInt(10_024_690_000_000), // ~5m tokens (20% of 50m) + }, + }, + "50m TVL, capactiy correctly initialized to 10% and 100%": { + denom: testDenom, + limiters: []types.Limiter{ + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1m tokens (assuming 6 decimals) + BaselineTvlPpm: 1_000_000, // 100% + }, + }, + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token + }, + }, + }, + { + Address: testAddress2, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token + }, + }, + }, + }, + expectedCapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(5_000_000_000_000), // 5m tokens (10% of 50m) + dtypes.NewInt(50_000_000_000_000), // 50m tokens (100% of 50m) + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + tApp := testapp.NewTestAppBuilder(t).WithGenesisDocFn(func() (genesis cometbfttypes.GenesisDoc) { + genesis = testapp.DefaultGenesis() + // Set up treasury account balance in genesis state + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *banktypes.GenesisState) { + genesisState.Balances = append(genesisState.Balances, tc.balances...) + }, + ) + return genesis + }).Build() + ctx := tApp.InitChain() + k := tApp.App.RatelimitKeeper + + limitParams := types.LimitParams{ + Denom: tc.denom, + Limiters: tc.limiters, + } + + // Test SetLimitParams + k.SetLimitParams(ctx, limitParams) + + // Test GetLimitParams + gotLimitParams := k.GetLimitParams(ctx, tc.denom) + require.Equal(t, limitParams, gotLimitParams, "retrieved LimitParams do not match the set value") + + // Query for `DenomCapacity` of `testDenom`. + gotDenomCapacity := k.GetDenomCapacity(ctx, tc.denom) + // Expected `DenomCapacity` is initialized such that each capacity is equal to the baseline. + expectedDenomCapacity := types.DenomCapacity{ + Denom: tc.denom, + CapacityList: tc.expectedCapacityList, + } + require.Equal(t, expectedDenomCapacity, gotDenomCapacity, "retrieved DenomCapacity does not match the set value") + + // Set empty `LimitParams` for `testDenom`. + k.SetLimitParams(ctx, types.LimitParams{ + Denom: tc.denom, + Limiters: []types.Limiter{}, // Empty list, results in deletion of the key. + }) + + // Check that the key is deleted under `LimitParams` storage. + require.Equal(t, + types.LimitParams{ + Denom: tc.denom, + Limiters: nil, + }, + k.GetLimitParams(ctx, tc.denom), + "retrieved LimitParams do not match the set value") + + // Check that the key is deleted under `DenomCapacity` storage. + require.Equal(t, + types.DenomCapacity{ + Denom: tc.denom, + CapacityList: nil, + }, + k.GetDenomCapacity(ctx, tc.denom), + "retrieved LimitParams do not match the set value") + }) + } +} + +func TestUpdateAllCapacitiesEndBlocker(t *testing.T) { + tests := map[string]struct { + balances []banktypes.Balance // For initializing the current supply + limitParamsList []types.LimitParams + prevBlockTime time.Time + blockTime time.Time + initDenomCapacityList []types.DenomCapacity + expectedDenomCapacityList []types.DenomCapacity + }{ + "One denom, prev capacity equals baseline": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 25M * 1% = 250k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 25M * 10% = 2.5M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(250_000_000_000), // 250k tokens, which equals baseline + dtypes.NewInt(2_500_000_000_000), // 2.5M tokens, which equals baseline + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(250_000_000_000), // 250k tokens + dtypes.NewInt(2_500_000_000_000), // 2.5M tokens + }, + }, + }, + }, + "One denom, prev capacity < baseline": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 25M * 1% = 250k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 25M * 10% = 2.5M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_000_000_000), // 99k tokens, < baseline (250k) + dtypes.NewInt(990_000_000_000), // 0.99M tokens, < baseline (2.5M) + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_069_444_444), // recovered by 1/3600 * 250k = 69.4444 tokens + dtypes.NewInt(990_028_935_185), // recovered by 1/86400 * 2.5M = 28.9351 tokens + }, + }, + }, + }, + "One denom, prev capacity < baseline, 18 decimals": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewIntFromBigInt( + big_testutil.Int64MulPow10(25, 24), // 25M tokens (assuming 18 decimals) + ), + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 25M * 1% = 250k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewIntFromBigInt( + big_testutil.Int64MulPow10(100_000, 18), // 100k tokens(assuming 18 decimals) + ), + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 25M * 10% = 2.5M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewIntFromBigInt( + big_testutil.Int64MulPow10(1_000_000, 18), // 1M tokens(assuming 18 decimals) + ), + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewIntFromBigInt( + big_testutil.Int64MulPow10(99_000, 18), + ), // 99k tokens < baseline (250k) + dtypes.NewIntFromBigInt( + big_testutil.Int64MulPow10(990_000, 18), + ), // 0.99M tokens, < baseline (2.5M) + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewIntFromBigInt( + big_testutil.MustFirst(new(big.Int).SetString("99069444444444444444444", 10)), + ), // recovered by 1/3600 * 250k ~= 69.4444 tokens + dtypes.NewIntFromBigInt( + big_testutil.MustFirst(new(big.Int).SetString("990028935185185185185185", 10)), + ), // recovered by 1/86400 * 2.5M ~= 28.9351 tokens + }, + }, + }, + }, + "One denom, prev capacity = 0": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(1_000_000_000_000), // 1M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = baseline minimum = 100k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = baseline minimum = 1M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(0), // 0 Capacity + dtypes.NewInt(0), // 0 Capacity + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(27_777_777), // recovered by 1/3600 * 100k ~= 27.7778 tokens + dtypes.NewInt(11_574_074), // recovered by 1/86400 * 1M ~= 11.5741 tokens + }, + }, + }, + }, + "One denom, baseline < prev capacity < 2 * baseline": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(20_000_000_000_000), // 20M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 20M * 1% = 200k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 20M * 10% = 2M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(329_000_000_000), + dtypes.NewInt(3_500_000_000_000), + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(328_944_444_445), // recovered by 1/3600 * 200k ~= 55.5555555556 + dtypes.NewInt(3_499_976_851_852), // recovered by 1/86400 * 2M ~= 23.1481481482 + }, + }, + }, + }, + "One denom, prev capacity > 2 * baseline": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(20_000_000_000_000), // 20M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 20M * 1% = 200k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 20M * 10% = 2M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(529_000_000_000), // 529k tokens > 2 * baseline (200k) + dtypes.NewInt(4_500_000_000_000), // 4.5M tokens > 2 * baseline (2) + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(528_908_611_112), // recovered by 1/3600 * (529k - 200k) ~= 91.389 + dtypes.NewInt(4_499_971_064_815), // recovered by 1/86400 * (4.5M - 2M) ~= 28.935 + }, + }, + }, + }, + "Two denoms, mix of values from above cases": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(20_000_000_000_000), // 20M token (assuming 6 decimals) + }, + { + Denom: testDenom2, + Amount: sdkmath.NewInt(25_000_000_000_000), // 20M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 20M * 1% = 200k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 20M * 10% = 2M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + { + Denom: testDenom2, + Limiters: []types.Limiter{ + // baseline = 25M * 1% = 250k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 25M * 10% = 2.5M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(529_000_000_000), // 529k tokens > 2 * baseline (200k) + dtypes.NewInt(4_500_000_000_000), // 4.5M tokens > 2 * baseline (2) + }, + }, + { + Denom: testDenom2, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_000_000_000), // 99k tokens, < baseline (250k) + dtypes.NewInt(990_000_000_000), // 0.99M tokens, < baseline (2.5M) + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(528_908_611_112), // recovered by 1/3600 * (529k - 200k) ~= 91.389 + dtypes.NewInt(4_499_971_064_815), // recovered by 1/86400 * (4.5M - 2M) ~= 28.935 + }, + }, + { + Denom: testDenom2, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_069_444_444), // recovered by 1/3600 * 250k = 69.4444 tokens + dtypes.NewInt(990_028_935_185), // recovered by 1/86400 * 2.5M = 28.9351 tokens + }, + }, + }, + }, + "(Error) one denom, current block time = prev block time, no changes applied": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 25M * 1% = 250k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + // baseline = 25M * 10% = 2.5M tokens + { + Period: 86_400 * time.Second, + BaselineMinimum: dtypes.NewInt(1_000_000_000_000), // 1M tokens (assuming 6 decimals) + BaselineTvlPpm: 100_000, // 10% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1000, 0).In(time.UTC), // same as prev block time (should not happen in practice) + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_000_000_000), // 99k tokens, < baseline (250k) + dtypes.NewInt(990_000_000_000), // 0.99M tokens, < baseline (2.5M) + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_000_000_000), // 99k tokens (unchanged) + dtypes.NewInt(990_000_000_000), // 0.99M tokens (unchanged) + }, + }, + }, + }, + "(Error) one denom, len(limiters) != len(capacityList)": { + balances: []banktypes.Balance{ + { + Address: testAddress1, + Coins: sdk.Coins{ + { + Denom: testDenom, + Amount: sdkmath.NewInt(25_000_000_000_000), // 25M token (assuming 6 decimals) + }, + }, + }, + }, + limitParamsList: []types.LimitParams{ + { + Denom: testDenom, + Limiters: []types.Limiter{ + // baseline = 25M * 1% = 250k tokens + { + Period: 3_600 * time.Second, + BaselineMinimum: dtypes.NewInt(100_000_000_000), // 100k tokens (assuming 6 decimals) + BaselineTvlPpm: 10_000, // 1% + }, + }, + }, + }, + prevBlockTime: time.Unix(1000, 0).In(time.UTC), + blockTime: time.Unix(1001, 0).In(time.UTC), // same as prev block time (should not happen in practice) + initDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_000_000_000), // 99k tokens, < baseline (250k) + dtypes.NewInt(990_000_000_000), // 0.99M tokens, < baseline (2.5M) + }, + }, + }, + expectedDenomCapacityList: []types.DenomCapacity{ + { + Denom: testDenom, + CapacityList: []dtypes.SerializableInt{ + dtypes.NewInt(99_000_000_000), // 99k tokens (unchanged) + dtypes.NewInt(990_000_000_000), // 0.99M tokens (unchanged) + }, + }, + }, + }, + } + + // Run tests. + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + tApp := testapp.NewTestAppBuilder(t).WithGenesisDocFn(func() (genesis cometbfttypes.GenesisDoc) { + genesis = testapp.DefaultGenesis() + // Set up treasury account balance in genesis state + testapp.UpdateGenesisDocWithAppStateForModule( + &genesis, + func(genesisState *banktypes.GenesisState) { + genesisState.Balances = append(genesisState.Balances, tc.balances...) + }, + ) + return genesis + }).Build() + + ctx := tApp.InitChain() + + // Set previous block time + tApp.App.BlockTimeKeeper.SetPreviousBlockInfo(ctx, &blocktimetypes.BlockInfo{ + Timestamp: tc.prevBlockTime, + }) + + k := tApp.App.RatelimitKeeper + + // Initialize limit params + for _, limitParams := range tc.limitParamsList { + k.SetLimitParams(ctx, limitParams) + } + + // Initialize denom capacity + for _, denomCapacity := range tc.initDenomCapacityList { + k.SetDenomCapacity(ctx, denomCapacity) + } + + // Run the function being tested + k.UpdateAllCapacitiesEndBlocker(ctx.WithBlockTime(tc.blockTime)) + + // Check results + for _, expectedDenomCapacity := range tc.expectedDenomCapacityList { + gotDenomCapacity := k.GetDenomCapacity(ctx, expectedDenomCapacity.Denom) + require.Equal(t, + expectedDenomCapacity, + gotDenomCapacity, + "expected denom capacity: %+v, got: %+v", + expectedDenomCapacity, + gotDenomCapacity, + ) + } + }) + } +} diff --git a/protocol/x/govplus/keeper/msg_server.go b/protocol/x/govplus/keeper/msg_server.go new file mode 100644 index 00000000000..7c01192b85b --- /dev/null +++ b/protocol/x/govplus/keeper/msg_server.go @@ -0,0 +1,17 @@ +package keeper + +import ( + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = msgServer{} diff --git a/protocol/x/govplus/keeper/msg_server_test.go b/protocol/x/govplus/keeper/msg_server_test.go new file mode 100644 index 00000000000..c5997406e35 --- /dev/null +++ b/protocol/x/govplus/keeper/msg_server_test.go @@ -0,0 +1,26 @@ +package keeper_test + +import ( + "context" + "testing" + + testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/keeper" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" + "github.com/stretchr/testify/require" +) + +func setupMsgServer(t *testing.T) (keeper.Keeper, types.MsgServer, context.Context) { + tApp := testapp.NewTestAppBuilder(t).Build() + ctx := tApp.InitChain() + k := tApp.App.GovPlusKeeper + + return k, keeper.NewMsgServerImpl(k), ctx +} + +func TestMsgServer(t *testing.T) { + k, ms, ctx := setupMsgServer(t) + require.NotNil(t, k) + require.NotNil(t, ms) + require.NotNil(t, ctx) +} diff --git a/protocol/x/govplus/module.go b/protocol/x/govplus/module.go new file mode 100644 index 00000000000..1e33f1be5a6 --- /dev/null +++ b/protocol/x/govplus/module.go @@ -0,0 +1,150 @@ +package govplus + +import ( + "context" + "encoding/json" + "fmt" + + "cosmossdk.io/core/appmodule" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/client/cli" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/keeper" + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" +) + +var ( + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasGenesisBasics = AppModuleBasic{} + + _ appmodule.AppModule = AppModule{} + _ appmodule.HasEndBlocker = AppModule{} + _ module.HasConsensusVersion = AppModule{} + _ module.HasGenesis = AppModule{} + _ module.HasServices = AppModule{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface that defines the independent methodsa Cosmos SDK module +// needs to implement. +type AppModuleBasic struct { + cdc codec.BinaryCodec +} + +func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the name of the module as a string +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the amino codec for the module, which is used to marshal and unmarshal structs +// to/from []byte in order to persist them in the module's KVStore +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers a module's interface types and their concrete implementations as proto.Message +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} + +// GetTxCmd returns the root Tx command for the module. The subcommands of this root command are used by end-users +// to generate new transactions containing messages defined in the module +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the root query command for the module. The subcommands of this root command are used by +// end-users to generate new queries to the subset of the state defined by the module +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd(types.StoreKey) +} + +// DefaultGenesis returns a default GenesisState for the module, marshalled to json.RawMessage. The default +// GenesisState need to be defined by the module developer and is primarily used for testing +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis used to validate the GenesisState, given in its json.RawMessage form +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface that defines the inter-dependent methods that modules need to implement +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper +} + +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, +) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: keeper, + } +} + +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} + +// IsOnePerModuleType is a marker function just indicates that this is a one-per-module type. +func (am AppModule) IsOnePerModuleType() {} + +// RegisterServices registers a gRPC query service to respond to the module-specific gRPC queries +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// InitGenesis performs the module's genesis initialization. It returns no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + + InitGenesis(ctx, am.keeper, genState) +} + +// ExportGenesis returns the module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(genState) +} + +// ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each +// consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should +// be set to 1 +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// EndBlock contains the logic that is automatically triggered at the end of each block +func (am AppModule) EndBlock(ctx context.Context) error { + return nil +} diff --git a/protocol/x/govplus/types/codec.go b/protocol/x/govplus/types/codec.go new file mode 100644 index 00000000000..545e15101cd --- /dev/null +++ b/protocol/x/govplus/types/codec.go @@ -0,0 +1,19 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterCodec(cdc *codec.LegacyAmino) {} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) diff --git a/protocol/x/govplus/types/genesis.go b/protocol/x/govplus/types/genesis.go new file mode 100644 index 00000000000..315d5df0ae2 --- /dev/null +++ b/protocol/x/govplus/types/genesis.go @@ -0,0 +1,12 @@ +package types + +// DefaultGenesis returns the default genesis state +func DefaultGenesis() *GenesisState { + return &GenesisState{} +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + return nil +} diff --git a/protocol/x/govplus/types/genesis.pb.go b/protocol/x/govplus/types/genesis.pb.go new file mode 100644 index 00000000000..e8bfb32d2d2 --- /dev/null +++ b/protocol/x/govplus/types/genesis.pb.go @@ -0,0 +1,265 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dydxprotocol/govplus/genesis.proto + +package types + +import ( + fmt "fmt" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the govplus module's genesis state. +type GenesisState struct { +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_70b54f4ffc433898, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func init() { + proto.RegisterType((*GenesisState)(nil), "dydxprotocol.govplus.GenesisState") +} + +func init() { + proto.RegisterFile("dydxprotocol/govplus/genesis.proto", fileDescriptor_70b54f4ffc433898) +} + +var fileDescriptor_70b54f4ffc433898 = []byte{ + // 143 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4a, 0xa9, 0x4c, 0xa9, + 0x28, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0xd1, 0x4f, 0xcf, 0x2f, 0x2b, 0xc8, 0x29, 0x2d, + 0xd6, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x03, 0x4b, 0x08, 0x89, 0x20, 0xab, 0xd1, + 0x83, 0xaa, 0x51, 0xe2, 0xe3, 0xe2, 0x71, 0x87, 0x28, 0x0b, 0x2e, 0x49, 0x2c, 0x49, 0x75, 0x0a, + 0x3e, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, + 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xcb, 0xf4, 0xcc, 0x92, 0x8c, + 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0x14, 0xeb, 0xca, 0x4c, 0x74, 0x93, 0x33, 0x12, 0x33, + 0xf3, 0xf4, 0xe1, 0x22, 0x15, 0x70, 0x27, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x65, + 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xd6, 0x53, 0xf7, 0xa7, 0x00, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/protocol/x/govplus/types/keys.go b/protocol/x/govplus/types/keys.go new file mode 100644 index 00000000000..1ca0eff668b --- /dev/null +++ b/protocol/x/govplus/types/keys.go @@ -0,0 +1,10 @@ +package types + +// Module name and store keys +const ( + // ModuleName defines the module name + ModuleName = "govplus" + + // StoreKey defines the primary module store key + StoreKey = ModuleName +) diff --git a/protocol/x/govplus/types/keys_test.go b/protocol/x/govplus/types/keys_test.go new file mode 100644 index 00000000000..22527901f86 --- /dev/null +++ b/protocol/x/govplus/types/keys_test.go @@ -0,0 +1,13 @@ +package types_test + +import ( + "testing" + + "github.com/dydxprotocol/v4-chain/protocol/x/govplus/types" + "github.com/stretchr/testify/require" +) + +func TestModuleKeys(t *testing.T) { + require.Equal(t, "govplus", types.ModuleName) + require.Equal(t, "govplus", types.StoreKey) +} diff --git a/protocol/x/govplus/types/query.pb.go b/protocol/x/govplus/types/query.pb.go new file mode 100644 index 00000000000..17205166561 --- /dev/null +++ b/protocol/x/govplus/types/query.pb.go @@ -0,0 +1,81 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dydxprotocol/govplus/query.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("dydxprotocol/govplus/query.proto", fileDescriptor_b04547eded25b028) } + +var fileDescriptor_b04547eded25b028 = []byte{ + // 136 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0xa9, 0x4c, 0xa9, + 0x28, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0xd1, 0x4f, 0xcf, 0x2f, 0x2b, 0xc8, 0x29, 0x2d, + 0xd6, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x03, 0x0b, 0x0b, 0x89, 0x20, 0xab, 0xd0, 0x83, 0xaa, + 0x30, 0x62, 0xe7, 0x62, 0x0d, 0x04, 0x29, 0x72, 0x0a, 0x3e, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, + 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, + 0x63, 0x39, 0x86, 0x28, 0xcb, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, + 0x14, 0x5b, 0xca, 0x4c, 0x74, 0x93, 0x33, 0x12, 0x33, 0xf3, 0xf4, 0xe1, 0x22, 0x15, 0x70, 0x9b, + 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x32, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x86, 0x4f, 0xc8, 0xd5, 0x9e, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +// QueryServer is the server API for Query service. +type QueryServer interface { +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "dydxprotocol.govplus.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "dydxprotocol/govplus/query.proto", +} diff --git a/protocol/x/govplus/types/tx.pb.go b/protocol/x/govplus/types/tx.pb.go new file mode 100644 index 00000000000..6ba74ba284a --- /dev/null +++ b/protocol/x/govplus/types/tx.pb.go @@ -0,0 +1,81 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dydxprotocol/govplus/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +func init() { proto.RegisterFile("dydxprotocol/govplus/tx.proto", fileDescriptor_9394a0d94676770f) } + +var fileDescriptor_9394a0d94676770f = []byte{ + // 131 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4d, 0xa9, 0x4c, 0xa9, + 0x28, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0xd1, 0x4f, 0xcf, 0x2f, 0x2b, 0xc8, 0x29, 0x2d, + 0xd6, 0x2f, 0xa9, 0xd0, 0x03, 0x8b, 0x09, 0x89, 0x20, 0x4b, 0xeb, 0x41, 0xa5, 0x8d, 0x58, 0xb9, + 0x98, 0x7d, 0x8b, 0xd3, 0x9d, 0x82, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, + 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, + 0xca, 0x32, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xc5, 0x82, 0x32, + 0x13, 0xdd, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, 0x7d, 0xb8, 0x48, 0x05, 0xc2, 0xd2, 0xca, 0x82, 0xd4, + 0xe2, 0x24, 0x36, 0xb0, 0x8c, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xf7, 0x6b, 0x7e, 0x99, + 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "dydxprotocol.govplus.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "dydxprotocol/govplus/tx.proto", +}