From 369a0c139987220b9bf486564726c0f533b29b36 Mon Sep 17 00:00:00 2001 From: Teddy Ding Date: Fri, 29 Nov 2024 18:41:37 -0500 Subject: [PATCH] feat(blocktime): Use gov-controlled`next_block_delay` to replace `timeout_commit` (#2609) --- .../codegen/dydxprotocol/blocktime/params.ts | 71 +++ .../dydxprotocol/blocktime/tx.rpc.msg.ts | 12 +- .../src/codegen/dydxprotocol/blocktime/tx.ts | 119 ++++- proto/dydxprotocol/blocktime/params.proto | 12 + proto/dydxprotocol/blocktime/tx.proto | 17 + protocol/app/app.go | 2 + protocol/app/msgs/all_msgs.go | 6 +- protocol/app/msgs/internal_msgs.go | 6 +- protocol/app/msgs/internal_msgs_test.go | 2 + protocol/go.mod | 4 +- protocol/go.sum | 8 +- protocol/lib/ante/internal_msg.go | 2 +- protocol/x/blocktime/keeper/block_delay.go | 31 ++ .../x/blocktime/keeper/block_delay_test.go | 49 +++ protocol/x/blocktime/keeper/msg_server.go | 18 + protocol/x/blocktime/types/errors.go | 5 + protocol/x/blocktime/types/keys.go | 3 + protocol/x/blocktime/types/params.go | 17 + protocol/x/blocktime/types/params.pb.go | 194 ++++++++- protocol/x/blocktime/types/tx.go | 14 + protocol/x/blocktime/types/tx.pb.go | 405 +++++++++++++++++- protocol/x/blocktime/types/tx_test.go | 47 ++ 22 files changed, 1015 insertions(+), 29 deletions(-) create mode 100644 protocol/x/blocktime/keeper/block_delay.go create mode 100644 protocol/x/blocktime/keeper/block_delay_test.go diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/params.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/params.ts index 7f327d2f3c..05483e5024 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/params.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/params.ts @@ -19,6 +19,32 @@ export interface DowntimeParamsSDKType { */ durations: DurationSDKType[]; } +/** SynchronyParams defines the parameters for block synchrony. */ + +export interface SynchronyParams { + /** + * next_block_delay replaces the locally configured timeout_commit in + * CometBFT. It determines the amount of time the CometBFT waits after the + * `CommitTime` (subjective time when +2/3 precommits were received), before + * moving to next height. + * If the application sends next_block_delay = 0 to the consensus engine, the + * latter defaults back to using timeout_commit. + */ + nextBlockDelay?: Duration; +} +/** SynchronyParams defines the parameters for block synchrony. */ + +export interface SynchronyParamsSDKType { + /** + * next_block_delay replaces the locally configured timeout_commit in + * CometBFT. It determines the amount of time the CometBFT waits after the + * `CommitTime` (subjective time when +2/3 precommits were received), before + * moving to next height. + * If the application sends next_block_delay = 0 to the consensus engine, the + * latter defaults back to using timeout_commit. + */ + next_block_delay?: DurationSDKType; +} function createBaseDowntimeParams(): DowntimeParams { return { @@ -63,4 +89,49 @@ export const DowntimeParams = { return message; } +}; + +function createBaseSynchronyParams(): SynchronyParams { + return { + nextBlockDelay: undefined + }; +} + +export const SynchronyParams = { + encode(message: SynchronyParams, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.nextBlockDelay !== undefined) { + Duration.encode(message.nextBlockDelay, writer.uint32(10).fork()).ldelim(); + } + + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): SynchronyParams { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSynchronyParams(); + + while (reader.pos < end) { + const tag = reader.uint32(); + + switch (tag >>> 3) { + case 1: + message.nextBlockDelay = Duration.decode(reader, reader.uint32()); + break; + + default: + reader.skipType(tag & 7); + break; + } + } + + return message; + }, + + fromPartial(object: DeepPartial): SynchronyParams { + const message = createBaseSynchronyParams(); + message.nextBlockDelay = object.nextBlockDelay !== undefined && object.nextBlockDelay !== null ? Duration.fromPartial(object.nextBlockDelay) : undefined; + return message; + } + }; \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.rpc.msg.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.rpc.msg.ts index c878a926c0..d0db3c98ff 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.rpc.msg.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.rpc.msg.ts @@ -1,11 +1,14 @@ import { Rpc } from "../../helpers"; import * as _m0 from "protobufjs/minimal"; -import { MsgUpdateDowntimeParams, MsgUpdateDowntimeParamsResponse } from "./tx"; +import { MsgUpdateDowntimeParams, MsgUpdateDowntimeParamsResponse, MsgUpdateSynchronyParams, MsgUpdateSynchronyParamsResponse } from "./tx"; /** Msg defines the Msg service. */ export interface Msg { /** UpdateDowntimeParams updates the DowntimeParams in state. */ updateDowntimeParams(request: MsgUpdateDowntimeParams): Promise; + /** UpdateSynchronyParams updates the SynchronyParams in state. */ + + updateSynchronyParams(request: MsgUpdateSynchronyParams): Promise; } export class MsgClientImpl implements Msg { private readonly rpc: Rpc; @@ -13,6 +16,7 @@ export class MsgClientImpl implements Msg { constructor(rpc: Rpc) { this.rpc = rpc; this.updateDowntimeParams = this.updateDowntimeParams.bind(this); + this.updateSynchronyParams = this.updateSynchronyParams.bind(this); } updateDowntimeParams(request: MsgUpdateDowntimeParams): Promise { @@ -21,4 +25,10 @@ export class MsgClientImpl implements Msg { return promise.then(data => MsgUpdateDowntimeParamsResponse.decode(new _m0.Reader(data))); } + updateSynchronyParams(request: MsgUpdateSynchronyParams): Promise { + const data = MsgUpdateSynchronyParams.encode(request).finish(); + const promise = this.rpc.request("dydxprotocol.blocktime.Msg", "UpdateSynchronyParams", data); + return promise.then(data => MsgUpdateSynchronyParamsResponse.decode(new _m0.Reader(data))); + } + } \ No newline at end of file diff --git a/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.ts b/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.ts index 33655a7732..9d56e35968 100644 --- a/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.ts +++ b/indexer/packages/v4-protos/src/codegen/dydxprotocol/blocktime/tx.ts @@ -1,4 +1,4 @@ -import { DowntimeParams, DowntimeParamsSDKType } from "./params"; +import { DowntimeParams, DowntimeParamsSDKType, SynchronyParams, SynchronyParamsSDKType } from "./params"; import * as _m0 from "protobufjs/minimal"; import { DeepPartial } from "../../helpers"; /** MsgUpdateDowntimeParams is the Msg/UpdateDowntimeParams request type. */ @@ -29,6 +29,34 @@ export interface MsgUpdateDowntimeParamsResponse {} */ export interface MsgUpdateDowntimeParamsResponseSDKType {} +/** MsgUpdateSynchronyParams is the Msg/UpdateSynchronyParams request type. */ + +export interface MsgUpdateSynchronyParams { + authority: string; + /** Defines the parameters to update. All parameters must be supplied. */ + + params?: SynchronyParams; +} +/** MsgUpdateSynchronyParams is the Msg/UpdateSynchronyParams request type. */ + +export interface MsgUpdateSynchronyParamsSDKType { + authority: string; + /** Defines the parameters to update. All parameters must be supplied. */ + + params?: SynchronyParamsSDKType; +} +/** + * MsgUpdateSynchronyParamsResponse is the Msg/UpdateSynchronyParams response + * type. + */ + +export interface MsgUpdateSynchronyParamsResponse {} +/** + * MsgUpdateSynchronyParamsResponse is the Msg/UpdateSynchronyParams response + * type. + */ + +export interface MsgUpdateSynchronyParamsResponseSDKType {} function createBaseMsgUpdateDowntimeParams(): MsgUpdateDowntimeParams { return { @@ -117,4 +145,93 @@ export const MsgUpdateDowntimeParamsResponse = { return message; } +}; + +function createBaseMsgUpdateSynchronyParams(): MsgUpdateSynchronyParams { + return { + authority: "", + params: undefined + }; +} + +export const MsgUpdateSynchronyParams = { + encode(message: MsgUpdateSynchronyParams, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.authority !== "") { + writer.uint32(10).string(message.authority); + } + + if (message.params !== undefined) { + SynchronyParams.encode(message.params, writer.uint32(18).fork()).ldelim(); + } + + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): MsgUpdateSynchronyParams { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgUpdateSynchronyParams(); + + while (reader.pos < end) { + const tag = reader.uint32(); + + switch (tag >>> 3) { + case 1: + message.authority = reader.string(); + break; + + case 2: + message.params = SynchronyParams.decode(reader, reader.uint32()); + break; + + default: + reader.skipType(tag & 7); + break; + } + } + + return message; + }, + + fromPartial(object: DeepPartial): MsgUpdateSynchronyParams { + const message = createBaseMsgUpdateSynchronyParams(); + message.authority = object.authority ?? ""; + message.params = object.params !== undefined && object.params !== null ? SynchronyParams.fromPartial(object.params) : undefined; + return message; + } + +}; + +function createBaseMsgUpdateSynchronyParamsResponse(): MsgUpdateSynchronyParamsResponse { + return {}; +} + +export const MsgUpdateSynchronyParamsResponse = { + encode(_: MsgUpdateSynchronyParamsResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): MsgUpdateSynchronyParamsResponse { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMsgUpdateSynchronyParamsResponse(); + + while (reader.pos < end) { + const tag = reader.uint32(); + + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + + return message; + }, + + fromPartial(_: DeepPartial): MsgUpdateSynchronyParamsResponse { + const message = createBaseMsgUpdateSynchronyParamsResponse(); + return message; + } + }; \ No newline at end of file diff --git a/proto/dydxprotocol/blocktime/params.proto b/proto/dydxprotocol/blocktime/params.proto index 72b63e3e68..a7a5c44b2c 100644 --- a/proto/dydxprotocol/blocktime/params.proto +++ b/proto/dydxprotocol/blocktime/params.proto @@ -13,3 +13,15 @@ message DowntimeParams { repeated google.protobuf.Duration durations = 1 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; } + +// SynchronyParams defines the parameters for block synchrony. +message SynchronyParams { + // next_block_delay replaces the locally configured timeout_commit in + // CometBFT. It determines the amount of time the CometBFT waits after the + // `CommitTime` (subjective time when +2/3 precommits were received), before + // moving to next height. + // If the application sends next_block_delay = 0 to the consensus engine, the + // latter defaults back to using timeout_commit. + google.protobuf.Duration next_block_delay = 1 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; +} diff --git a/proto/dydxprotocol/blocktime/tx.proto b/proto/dydxprotocol/blocktime/tx.proto index 80779c1dcb..ffd9be8edb 100644 --- a/proto/dydxprotocol/blocktime/tx.proto +++ b/proto/dydxprotocol/blocktime/tx.proto @@ -13,6 +13,9 @@ service Msg { // UpdateDowntimeParams updates the DowntimeParams in state. rpc UpdateDowntimeParams(MsgUpdateDowntimeParams) returns (MsgUpdateDowntimeParamsResponse); + // UpdateSynchronyParams updates the SynchronyParams in state. + rpc UpdateSynchronyParams(MsgUpdateSynchronyParams) + returns (MsgUpdateSynchronyParamsResponse); } // MsgUpdateDowntimeParams is the Msg/UpdateDowntimeParams request type. @@ -28,3 +31,17 @@ message MsgUpdateDowntimeParams { // MsgUpdateDowntimeParamsResponse is the Msg/UpdateDowntimeParams response // type. message MsgUpdateDowntimeParamsResponse {} + +// MsgUpdateSynchronyParams is the Msg/UpdateSynchronyParams request type. +message MsgUpdateSynchronyParams { + // The address that controls the module. + option (cosmos.msg.v1.signer) = "authority"; + string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // Defines the parameters to update. All parameters must be supplied. + SynchronyParams params = 2 [ (gogoproto.nullable) = false ]; +} + +// MsgUpdateSynchronyParamsResponse is the Msg/UpdateSynchronyParams response +// type. +message MsgUpdateSynchronyParamsResponse {} diff --git a/protocol/app/app.go b/protocol/app/app.go index 9b16079e88..f23d5a13ad 100644 --- a/protocol/app/app.go +++ b/protocol/app/app.go @@ -1571,6 +1571,8 @@ func New( app.SetPrepareProposal(prepareProposalHandler) app.SetProcessProposal(processProposalHandler) + app.SetBlockDelayGetter(app.BlockTimeKeeper.GetBlockDelay) + // Note that panics from out of gas errors won't get logged, since the `OutOfGasMiddleware` is added in front of this, // so error will get handled by that middleware and subsequent middlewares won't get executed. // Also note that `AddRunTxRecoveryHandler` adds the handler in reverse order, meaning that handlers that appear diff --git a/protocol/app/msgs/all_msgs.go b/protocol/app/msgs/all_msgs.go index 9a6e072df0..357d9c0218 100644 --- a/protocol/app/msgs/all_msgs.go +++ b/protocol/app/msgs/all_msgs.go @@ -180,8 +180,10 @@ var ( "/dydxprotocol.accountplus.TxExtension": {}, // blocktime - "/dydxprotocol.blocktime.MsgUpdateDowntimeParams": {}, - "/dydxprotocol.blocktime.MsgUpdateDowntimeParamsResponse": {}, + "/dydxprotocol.blocktime.MsgUpdateDowntimeParams": {}, + "/dydxprotocol.blocktime.MsgUpdateDowntimeParamsResponse": {}, + "/dydxprotocol.blocktime.MsgUpdateSynchronyParams": {}, + "/dydxprotocol.blocktime.MsgUpdateSynchronyParamsResponse": {}, // bridge "/dydxprotocol.bridge.MsgAcknowledgeBridges": {}, diff --git a/protocol/app/msgs/internal_msgs.go b/protocol/app/msgs/internal_msgs.go index 8587ff5e4c..44725202ba 100644 --- a/protocol/app/msgs/internal_msgs.go +++ b/protocol/app/msgs/internal_msgs.go @@ -118,8 +118,10 @@ var ( "/dydxprotocol.accountplus.MsgSetActiveStateResponse": nil, // blocktime - "/dydxprotocol.blocktime.MsgUpdateDowntimeParams": &blocktime.MsgUpdateDowntimeParams{}, - "/dydxprotocol.blocktime.MsgUpdateDowntimeParamsResponse": nil, + "/dydxprotocol.blocktime.MsgUpdateDowntimeParams": &blocktime.MsgUpdateDowntimeParams{}, + "/dydxprotocol.blocktime.MsgUpdateDowntimeParamsResponse": nil, + "/dydxprotocol.blocktime.MsgUpdateSynchronyParams": &blocktime.MsgUpdateSynchronyParams{}, + "/dydxprotocol.blocktime.MsgUpdateSynchronyParamsResponse": nil, // bridge "/dydxprotocol.bridge.MsgCompleteBridge": &bridge.MsgCompleteBridge{}, diff --git a/protocol/app/msgs/internal_msgs_test.go b/protocol/app/msgs/internal_msgs_test.go index 00bcbdc912..652c2f202e 100644 --- a/protocol/app/msgs/internal_msgs_test.go +++ b/protocol/app/msgs/internal_msgs_test.go @@ -76,6 +76,8 @@ func TestInternalMsgSamples_Gov_Key(t *testing.T) { // blocktime "/dydxprotocol.blocktime.MsgUpdateDowntimeParams", "/dydxprotocol.blocktime.MsgUpdateDowntimeParamsResponse", + "/dydxprotocol.blocktime.MsgUpdateSynchronyParams", + "/dydxprotocol.blocktime.MsgUpdateSynchronyParamsResponse", // bridge "/dydxprotocol.bridge.MsgCompleteBridge", diff --git a/protocol/go.mod b/protocol/go.mod index d51d6134f0..4a6e2458b4 100644 --- a/protocol/go.mod +++ b/protocol/go.mod @@ -470,9 +470,9 @@ replace ( // Use dYdX fork of Cosmos SDK/store cosmossdk.io/store => github.com/dydxprotocol/cosmos-sdk/store v1.0.3-0.20240326192503-dd116391188d // Use dYdX fork of CometBFT - github.com/cometbft/cometbft => github.com/dydxprotocol/cometbft v0.38.6-0.20241120221529-56316dc17261 + github.com/cometbft/cometbft => github.com/dydxprotocol/cometbft v0.38.6-0.20241126215519-69cdde955fd0 // Use dYdX fork of Cosmos SDK - github.com/cosmos/cosmos-sdk => github.com/dydxprotocol/cosmos-sdk v0.50.6-0.20241120185835-38650041ec4d + github.com/cosmos/cosmos-sdk => github.com/dydxprotocol/cosmos-sdk v0.50.6-0.20241127172510-4ee58434cdea github.com/cosmos/iavl => github.com/dydxprotocol/iavl v1.1.1-0.20240509161911-1c8b8e787e85 ) diff --git a/protocol/go.sum b/protocol/go.sum index 0d415bcc36..8f8192bfa7 100644 --- a/protocol/go.sum +++ b/protocol/go.sum @@ -958,10 +958,10 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/dydxprotocol/cometbft v0.38.6-0.20241120221529-56316dc17261 h1:uspjqDKBvC5I98gKBdZxqX3q0M2UOE/UlGgg+1CLNyI= -github.com/dydxprotocol/cometbft v0.38.6-0.20241120221529-56316dc17261/go.mod h1:XSQX1hQbr54qaJb4/5YNNZGXkAQHHa6bi/KMcN1SQ7w= -github.com/dydxprotocol/cosmos-sdk v0.50.6-0.20241120185835-38650041ec4d h1:6Qzg4IuX6LNdciU55jzpGuKxEVgD09rbU2cQaoJFo9Q= -github.com/dydxprotocol/cosmos-sdk v0.50.6-0.20241120185835-38650041ec4d/go.mod h1:8EZnLstapHjZ2iGa9nGIhctJ3gU1yCqmRUPN8WI7jD0= +github.com/dydxprotocol/cometbft v0.38.6-0.20241126215519-69cdde955fd0 h1:KBMuBNAE91SVeULnq2XBnmSDGeimI6aM1+YxlLb0yOI= +github.com/dydxprotocol/cometbft v0.38.6-0.20241126215519-69cdde955fd0/go.mod h1:XSQX1hQbr54qaJb4/5YNNZGXkAQHHa6bi/KMcN1SQ7w= +github.com/dydxprotocol/cosmos-sdk v0.50.6-0.20241127172510-4ee58434cdea h1:5jsj2e6zqnx7Q7SiNTYC7UGEW0ymgKFTbLxzp27/2Fg= +github.com/dydxprotocol/cosmos-sdk v0.50.6-0.20241127172510-4ee58434cdea/go.mod h1:z/5+LD4MJzLqbe+fBCWI2pZLnQbOlzSM82snAw2zceg= github.com/dydxprotocol/cosmos-sdk/store v1.0.3-0.20240326192503-dd116391188d h1:HgLu1FD2oDFzlKW6/+SFXlH5Os8cwNTbplQIrQOWx8w= github.com/dydxprotocol/cosmos-sdk/store v1.0.3-0.20240326192503-dd116391188d/go.mod h1:zMcD3hfNwd0WMTpdRUhS3QxoCoEtBXWeoKsu3iaLBbQ= github.com/dydxprotocol/iavl v1.1.1-0.20240509161911-1c8b8e787e85 h1:5B/yGZyTBX/OZASQQMnk6Ms/TZja56MYd8OBaVc0Mho= diff --git a/protocol/lib/ante/internal_msg.go b/protocol/lib/ante/internal_msg.go index 3e1b44a917..e9257555e3 100644 --- a/protocol/lib/ante/internal_msg.go +++ b/protocol/lib/ante/internal_msg.go @@ -77,7 +77,7 @@ func IsInternalMsg(msg sdk.Msg) bool { // blocktime *blocktime.MsgUpdateDowntimeParams, - + *blocktime.MsgUpdateSynchronyParams, // bridge *bridge.MsgCompleteBridge, *bridge.MsgUpdateEventParams, diff --git a/protocol/x/blocktime/keeper/block_delay.go b/protocol/x/blocktime/keeper/block_delay.go new file mode 100644 index 0000000000..7b0ef0b429 --- /dev/null +++ b/protocol/x/blocktime/keeper/block_delay.go @@ -0,0 +1,31 @@ +package keeper + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/dydxprotocol/v4-chain/protocol/x/blocktime/types" +) + +func (k Keeper) GetSynchronyParams(ctx sdk.Context) types.SynchronyParams { + store := ctx.KVStore(k.storeKey) + bytes := store.Get([]byte(types.SynchronyParamsKey)) + + if bytes == nil { + return types.DefaultSynchronyParams() + } + + var params types.SynchronyParams + k.cdc.MustUnmarshal(bytes, ¶ms) + return params +} + +func (k Keeper) SetSynchronyParams(ctx sdk.Context, params types.SynchronyParams) { + store := ctx.KVStore(k.storeKey) + store.Set([]byte(types.SynchronyParamsKey), k.cdc.MustMarshal(¶ms)) +} + +func (k Keeper) GetBlockDelay(ctx sdk.Context) time.Duration { + return k.GetSynchronyParams(ctx).NextBlockDelay +} diff --git a/protocol/x/blocktime/keeper/block_delay_test.go b/protocol/x/blocktime/keeper/block_delay_test.go new file mode 100644 index 0000000000..8fe89cb97a --- /dev/null +++ b/protocol/x/blocktime/keeper/block_delay_test.go @@ -0,0 +1,49 @@ +package keeper_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" + "github.com/dydxprotocol/v4-chain/protocol/x/blocktime/keeper" + "github.com/dydxprotocol/v4-chain/protocol/x/blocktime/types" + "github.com/stretchr/testify/require" +) + +func Test_Set_GetSynchronyParams_GetBlockDelay(t *testing.T) { + tests := map[string]struct { + setUp func(keeper.Keeper, sdk.Context) + expectedSynchronyParams types.SynchronyParams + expectedBlockDelay time.Duration + }{ + "No set-up, empty synchrony params, block_delay = 0": { + setUp: func(k keeper.Keeper, ctx sdk.Context) { + }, + expectedSynchronyParams: types.DefaultSynchronyParams(), + expectedBlockDelay: 0, + }, + "Non-nil synchrony param": { + setUp: func(k keeper.Keeper, ctx sdk.Context) { + k.SetSynchronyParams(ctx, types.SynchronyParams{ + NextBlockDelay: 300 * time.Millisecond, + }) + }, + expectedSynchronyParams: types.SynchronyParams{ + NextBlockDelay: 300 * time.Millisecond, + }, + expectedBlockDelay: 300 * time.Millisecond, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + tApp := testapp.NewTestAppBuilder(t).Build() + ctx := tApp.InitChain() + k := tApp.App.BlockTimeKeeper + tc.setUp(k, ctx) + require.Equal(t, tc.expectedSynchronyParams, k.GetSynchronyParams(ctx)) + require.Equal(t, tc.expectedBlockDelay, k.GetBlockDelay(ctx)) + }) + } +} diff --git a/protocol/x/blocktime/keeper/msg_server.go b/protocol/x/blocktime/keeper/msg_server.go index e4cac712c7..397bfb7f4b 100644 --- a/protocol/x/blocktime/keeper/msg_server.go +++ b/protocol/x/blocktime/keeper/msg_server.go @@ -41,3 +41,21 @@ func (k msgServer) UpdateDowntimeParams( return &types.MsgUpdateDowntimeParamsResponse{}, nil } + +func (k msgServer) UpdateSynchronyParams( + goCtx context.Context, + msg *types.MsgUpdateSynchronyParams, +) (*types.MsgUpdateSynchronyParamsResponse, error) { + if !k.HasAuthority(msg.Authority) { + return nil, errorsmod.Wrapf( + govtypes.ErrInvalidSigner, + "invalid authority %s", + msg.Authority, + ) + } + + ctx := lib.UnwrapSDKContext(goCtx, types.ModuleName) + k.SetSynchronyParams(ctx, msg.Params) + + return &types.MsgUpdateSynchronyParamsResponse{}, nil +} diff --git a/protocol/x/blocktime/types/errors.go b/protocol/x/blocktime/types/errors.go index 250e78305c..02b5761dfd 100644 --- a/protocol/x/blocktime/types/errors.go +++ b/protocol/x/blocktime/types/errors.go @@ -20,4 +20,9 @@ var ( 402, "Authority is invalid", ) + ErrNegativeNextBlockDelay = errorsmod.Register( + ModuleName, + 403, + "next_block_delay must be non-negative", + ) ) diff --git a/protocol/x/blocktime/types/keys.go b/protocol/x/blocktime/types/keys.go index 48344dc6b1..670a7689c2 100644 --- a/protocol/x/blocktime/types/keys.go +++ b/protocol/x/blocktime/types/keys.go @@ -19,4 +19,7 @@ const ( // PreviousBlockInfoKey defines the key for PreviousBlockInfo PreviousBlockInfoKey = "PreviousBlockInfo" + + // SynchronyParamsKey defines the key for the SynchronyParams + SynchronyParamsKey = "SP:" ) diff --git a/protocol/x/blocktime/types/params.go b/protocol/x/blocktime/types/params.go index c86f29769d..1ec22673be 100644 --- a/protocol/x/blocktime/types/params.go +++ b/protocol/x/blocktime/types/params.go @@ -1,5 +1,7 @@ package types +import time "time" + func (m *DowntimeParams) Validate() error { if m.Durations != nil { for i := 0; i < len(m.Durations); i++ { @@ -16,3 +18,18 @@ func (m *DowntimeParams) Validate() error { } return nil } + +func (s SynchronyParams) Validate() error { + if s.NextBlockDelay < 0 { + return ErrNegativeNextBlockDelay + } + return nil +} + +func DefaultSynchronyParams() SynchronyParams { + return SynchronyParams{ + // CometBFT defaults back to `timeout_commit` if application sends over + // `NextBlockDelay` of 0. + NextBlockDelay: 0 * time.Second, + } +} diff --git a/protocol/x/blocktime/types/params.pb.go b/protocol/x/blocktime/types/params.pb.go index 1f55a12d30..a20fafe278 100644 --- a/protocol/x/blocktime/types/params.pb.go +++ b/protocol/x/blocktime/types/params.pb.go @@ -74,8 +74,60 @@ func (m *DowntimeParams) GetDurations() []time.Duration { return nil } +// SynchronyParams defines the parameters for block synchrony. +type SynchronyParams struct { + // next_block_delay replaces the locally configured timeout_commit in + // CometBFT. It determines the amount of time the CometBFT waits after the + // `CommitTime` (subjective time when +2/3 precommits were received), before + // moving to next height. + // If the application sends next_block_delay = 0 to the consensus engine, the + // latter defaults back to using timeout_commit. + NextBlockDelay time.Duration `protobuf:"bytes,1,opt,name=next_block_delay,json=nextBlockDelay,proto3,stdduration" json:"next_block_delay"` +} + +func (m *SynchronyParams) Reset() { *m = SynchronyParams{} } +func (m *SynchronyParams) String() string { return proto.CompactTextString(m) } +func (*SynchronyParams) ProtoMessage() {} +func (*SynchronyParams) Descriptor() ([]byte, []int) { + return fileDescriptor_d036653b2617e4cf, []int{1} +} +func (m *SynchronyParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SynchronyParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SynchronyParams.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 *SynchronyParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_SynchronyParams.Merge(m, src) +} +func (m *SynchronyParams) XXX_Size() int { + return m.Size() +} +func (m *SynchronyParams) XXX_DiscardUnknown() { + xxx_messageInfo_SynchronyParams.DiscardUnknown(m) +} + +var xxx_messageInfo_SynchronyParams proto.InternalMessageInfo + +func (m *SynchronyParams) GetNextBlockDelay() time.Duration { + if m != nil { + return m.NextBlockDelay + } + return 0 +} + func init() { proto.RegisterType((*DowntimeParams)(nil), "dydxprotocol.blocktime.DowntimeParams") + proto.RegisterType((*SynchronyParams)(nil), "dydxprotocol.blocktime.SynchronyParams") } func init() { @@ -83,7 +135,7 @@ func init() { } var fileDescriptor_d036653b2617e4cf = []byte{ - // 221 bytes of a gzipped FileDescriptorProto + // 268 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4e, 0xa9, 0x4c, 0xa9, 0x28, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0xd1, 0x4f, 0xca, 0xc9, 0x4f, 0xce, 0x2e, 0xc9, 0xcc, 0x4d, 0xd5, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x03, 0xcb, 0x08, 0x89, 0x21, 0x2b, @@ -92,12 +144,15 @@ var fileDescriptor_d036653b2617e4cf = []byte{ 0x69, 0x51, 0x62, 0x49, 0x66, 0x7e, 0x1e, 0x44, 0x5e, 0x29, 0x98, 0x8b, 0xcf, 0x25, 0xbf, 0x3c, 0x0f, 0x64, 0x42, 0x00, 0xd8, 0x16, 0x21, 0x47, 0x2e, 0x4e, 0x98, 0x9a, 0x62, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x6e, 0x23, 0x49, 0x3d, 0x88, 0x29, 0x7a, 0x30, 0x53, 0xf4, 0x5c, 0xa0, 0x2a, 0x9c, - 0x38, 0x4e, 0xdc, 0x93, 0x67, 0x98, 0x71, 0x5f, 0x9e, 0x31, 0x08, 0xa1, 0xcb, 0x29, 0xf4, 0xc4, - 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, - 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xac, 0xd3, 0x33, 0x4b, 0x32, 0x4a, 0x93, - 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x51, 0x3c, 0x5b, 0x66, 0xa2, 0x9b, 0x9c, 0x91, 0x98, 0x99, 0xa7, - 0x0f, 0x17, 0xa9, 0x40, 0x0a, 0x80, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x9c, 0x31, - 0x20, 0x00, 0x00, 0xff, 0xff, 0x1e, 0xa4, 0x26, 0x2b, 0x27, 0x01, 0x00, 0x00, + 0x38, 0x4e, 0xdc, 0x93, 0x67, 0x98, 0x71, 0x5f, 0x9e, 0x31, 0x08, 0xa1, 0x4b, 0x29, 0x81, 0x8b, + 0x3f, 0xb8, 0x32, 0x2f, 0x39, 0xa3, 0x28, 0x3f, 0xaf, 0x12, 0x6a, 0xaa, 0x2f, 0x97, 0x40, 0x5e, + 0x6a, 0x45, 0x49, 0x3c, 0xd8, 0xbd, 0xf1, 0x29, 0xa9, 0x39, 0x89, 0x95, 0x12, 0x8c, 0x0a, 0x8c, + 0xc4, 0x1a, 0xce, 0x07, 0xd2, 0xec, 0x04, 0xd2, 0xeb, 0x02, 0xd2, 0xea, 0x14, 0x7a, 0xe2, 0x91, + 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, + 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xd6, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, + 0xc9, 0xf9, 0xb9, 0xfa, 0x28, 0xc1, 0x59, 0x66, 0xa2, 0x9b, 0x9c, 0x91, 0x98, 0x99, 0xa7, 0x0f, + 0x17, 0xa9, 0x40, 0x0a, 0xe2, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x9c, 0x31, 0x20, + 0x00, 0x00, 0xff, 0xff, 0x09, 0x2a, 0x13, 0xab, 0x89, 0x01, 0x00, 0x00, } func (m *DowntimeParams) Marshal() (dAtA []byte, err error) { @@ -135,6 +190,37 @@ func (m *DowntimeParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SynchronyParams) 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 *SynchronyParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SynchronyParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.NextBlockDelay, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.NextBlockDelay):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintParams(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func encodeVarintParams(dAtA []byte, offset int, v uint64) int { offset -= sovParams(v) base := offset @@ -161,6 +247,17 @@ func (m *DowntimeParams) Size() (n int) { return n } +func (m *SynchronyParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.NextBlockDelay) + n += 1 + l + sovParams(uint64(l)) + return n +} + func sovParams(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -251,6 +348,89 @@ func (m *DowntimeParams) Unmarshal(dAtA []byte) error { } return nil } +func (m *SynchronyParams) 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 ErrIntOverflowParams + } + 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: SynchronyParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SynchronyParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NextBlockDelay", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.NextBlockDelay, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipParams(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/protocol/x/blocktime/types/tx.go b/protocol/x/blocktime/types/tx.go index 1dbe2dcc2f..bd54c2bb4e 100644 --- a/protocol/x/blocktime/types/tx.go +++ b/protocol/x/blocktime/types/tx.go @@ -20,3 +20,17 @@ func (msg *MsgUpdateDowntimeParams) ValidateBasic() error { } return msg.Params.Validate() } + +func (msg *MsgUpdateSynchronyParams) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil { + return errorsmod.Wrap( + ErrInvalidAuthority, + fmt.Sprintf( + "authority '%s' must be a valid bech32 address, but got error '%v'", + msg.Authority, + err.Error(), + ), + ) + } + return msg.Params.Validate() +} diff --git a/protocol/x/blocktime/types/tx.pb.go b/protocol/x/blocktime/types/tx.pb.go index 5fd591ab26..017b9d1871 100644 --- a/protocol/x/blocktime/types/tx.pb.go +++ b/protocol/x/blocktime/types/tx.pb.go @@ -122,15 +122,109 @@ func (m *MsgUpdateDowntimeParamsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateDowntimeParamsResponse proto.InternalMessageInfo +// MsgUpdateSynchronyParams is the Msg/UpdateSynchronyParams request type. +type MsgUpdateSynchronyParams struct { + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // Defines the parameters to update. All parameters must be supplied. + Params SynchronyParams `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateSynchronyParams) Reset() { *m = MsgUpdateSynchronyParams{} } +func (m *MsgUpdateSynchronyParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateSynchronyParams) ProtoMessage() {} +func (*MsgUpdateSynchronyParams) Descriptor() ([]byte, []int) { + return fileDescriptor_4b4afda7c355c8b6, []int{2} +} +func (m *MsgUpdateSynchronyParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateSynchronyParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateSynchronyParams.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 *MsgUpdateSynchronyParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateSynchronyParams.Merge(m, src) +} +func (m *MsgUpdateSynchronyParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateSynchronyParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateSynchronyParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateSynchronyParams proto.InternalMessageInfo + +func (m *MsgUpdateSynchronyParams) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgUpdateSynchronyParams) GetParams() SynchronyParams { + if m != nil { + return m.Params + } + return SynchronyParams{} +} + +// MsgUpdateSynchronyParamsResponse is the Msg/UpdateSynchronyParams response +// type. +type MsgUpdateSynchronyParamsResponse struct { +} + +func (m *MsgUpdateSynchronyParamsResponse) Reset() { *m = MsgUpdateSynchronyParamsResponse{} } +func (m *MsgUpdateSynchronyParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateSynchronyParamsResponse) ProtoMessage() {} +func (*MsgUpdateSynchronyParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_4b4afda7c355c8b6, []int{3} +} +func (m *MsgUpdateSynchronyParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateSynchronyParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateSynchronyParamsResponse.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 *MsgUpdateSynchronyParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateSynchronyParamsResponse.Merge(m, src) +} +func (m *MsgUpdateSynchronyParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateSynchronyParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateSynchronyParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateSynchronyParamsResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgUpdateDowntimeParams)(nil), "dydxprotocol.blocktime.MsgUpdateDowntimeParams") proto.RegisterType((*MsgUpdateDowntimeParamsResponse)(nil), "dydxprotocol.blocktime.MsgUpdateDowntimeParamsResponse") + proto.RegisterType((*MsgUpdateSynchronyParams)(nil), "dydxprotocol.blocktime.MsgUpdateSynchronyParams") + proto.RegisterType((*MsgUpdateSynchronyParamsResponse)(nil), "dydxprotocol.blocktime.MsgUpdateSynchronyParamsResponse") } func init() { proto.RegisterFile("dydxprotocol/blocktime/tx.proto", fileDescriptor_4b4afda7c355c8b6) } var fileDescriptor_4b4afda7c355c8b6 = []byte{ - // 326 bytes of a gzipped FileDescriptorProto + // 384 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xa9, 0x4c, 0xa9, 0x28, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0xce, 0xcf, 0xd1, 0x4f, 0xca, 0xc9, 0x4f, 0xce, 0x2e, 0xc9, 0xcc, 0x4d, 0xd5, 0x2f, 0xa9, 0xd0, 0x03, 0x8b, 0x0a, 0x89, 0x21, 0x2b, 0xd0, 0x83, 0x2b, 0x90, @@ -144,14 +238,17 @@ var fileDescriptor_4b4afda7c355c8b6 = []byte{ 0x79, 0xe9, 0x41, 0x08, 0xa5, 0x42, 0x2e, 0x5c, 0x6c, 0x10, 0x9b, 0x25, 0x98, 0x14, 0x18, 0x35, 0xb8, 0x8d, 0xd4, 0xf4, 0xb0, 0xfb, 0x55, 0x0f, 0xd5, 0x3e, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x7a, 0xad, 0xf8, 0x9a, 0x9e, 0x6f, 0xd0, 0x42, 0x98, 0xaa, 0xa4, 0xc8, 0x25, 0x8f, - 0xc3, 0xa1, 0x41, 0xa9, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x46, 0x1d, 0x8c, 0x5c, 0xcc, 0xbe, - 0xc5, 0xe9, 0x42, 0x0d, 0x8c, 0x5c, 0x22, 0x58, 0x7d, 0xa4, 0x8f, 0xcb, 0x25, 0x38, 0x4c, 0x96, - 0x32, 0x27, 0x51, 0x03, 0xcc, 0x29, 0x4e, 0xa1, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, - 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, - 0xc7, 0x10, 0x65, 0x9d, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x8f, 0x12, - 0x6f, 0x65, 0x26, 0xba, 0xc9, 0x19, 0x89, 0x99, 0x79, 0xfa, 0x70, 0x91, 0x0a, 0xe4, 0x84, 0x53, - 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x96, 0x33, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x67, 0x88, - 0x2a, 0x78, 0x5f, 0x02, 0x00, 0x00, + 0xc3, 0xa1, 0x41, 0xa9, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x4a, 0x2b, 0x19, 0xb9, 0x24, 0xe0, + 0x6a, 0x82, 0x2b, 0xf3, 0x92, 0x33, 0x8a, 0xf2, 0xf3, 0x2a, 0x29, 0xf4, 0x8d, 0x2b, 0x9a, 0x6f, + 0xd4, 0x71, 0xf9, 0x06, 0xcd, 0x42, 0x02, 0xde, 0x51, 0xe2, 0x52, 0xc0, 0xe5, 0x54, 0x98, 0x7f, + 0x8c, 0xfa, 0x98, 0xb8, 0x98, 0x7d, 0x8b, 0xd3, 0x85, 0x1a, 0x18, 0xb9, 0x44, 0xb0, 0xc6, 0x90, + 0x3e, 0x2e, 0xb7, 0xe0, 0x08, 0x29, 0x29, 0x73, 0x12, 0x35, 0xc0, 0x9c, 0x22, 0xd4, 0xcc, 0xc8, + 0x25, 0x8a, 0x3d, 0x5c, 0x0d, 0x08, 0x1a, 0x89, 0xa6, 0x43, 0xca, 0x82, 0x54, 0x1d, 0x30, 0x57, + 0x38, 0x85, 0x9e, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, + 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x75, 0x7a, 0x66, + 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0x4a, 0x6e, 0x28, 0x33, 0xd1, 0x4d, 0xce, + 0x48, 0xcc, 0xcc, 0xd3, 0x87, 0x8b, 0x54, 0x20, 0x67, 0xc7, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, + 0xb0, 0x9c, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc2, 0x8d, 0xcd, 0xb5, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -168,6 +265,8 @@ const _ = grpc.SupportPackageIsVersion4 type MsgClient interface { // UpdateDowntimeParams updates the DowntimeParams in state. UpdateDowntimeParams(ctx context.Context, in *MsgUpdateDowntimeParams, opts ...grpc.CallOption) (*MsgUpdateDowntimeParamsResponse, error) + // UpdateSynchronyParams updates the SynchronyParams in state. + UpdateSynchronyParams(ctx context.Context, in *MsgUpdateSynchronyParams, opts ...grpc.CallOption) (*MsgUpdateSynchronyParamsResponse, error) } type msgClient struct { @@ -187,10 +286,21 @@ func (c *msgClient) UpdateDowntimeParams(ctx context.Context, in *MsgUpdateDownt return out, nil } +func (c *msgClient) UpdateSynchronyParams(ctx context.Context, in *MsgUpdateSynchronyParams, opts ...grpc.CallOption) (*MsgUpdateSynchronyParamsResponse, error) { + out := new(MsgUpdateSynchronyParamsResponse) + err := c.cc.Invoke(ctx, "/dydxprotocol.blocktime.Msg/UpdateSynchronyParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // UpdateDowntimeParams updates the DowntimeParams in state. UpdateDowntimeParams(context.Context, *MsgUpdateDowntimeParams) (*MsgUpdateDowntimeParamsResponse, error) + // UpdateSynchronyParams updates the SynchronyParams in state. + UpdateSynchronyParams(context.Context, *MsgUpdateSynchronyParams) (*MsgUpdateSynchronyParamsResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -200,6 +310,9 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) UpdateDowntimeParams(ctx context.Context, req *MsgUpdateDowntimeParams) (*MsgUpdateDowntimeParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateDowntimeParams not implemented") } +func (*UnimplementedMsgServer) UpdateSynchronyParams(ctx context.Context, req *MsgUpdateSynchronyParams) (*MsgUpdateSynchronyParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateSynchronyParams not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -223,6 +336,24 @@ func _Msg_UpdateDowntimeParams_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Msg_UpdateSynchronyParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateSynchronyParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateSynchronyParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/dydxprotocol.blocktime.Msg/UpdateSynchronyParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateSynchronyParams(ctx, req.(*MsgUpdateSynchronyParams)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "dydxprotocol.blocktime.Msg", HandlerType: (*MsgServer)(nil), @@ -231,6 +362,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateDowntimeParams", Handler: _Msg_UpdateDowntimeParams_Handler, }, + { + MethodName: "UpdateSynchronyParams", + Handler: _Msg_UpdateSynchronyParams_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "dydxprotocol/blocktime/tx.proto", @@ -299,6 +434,69 @@ func (m *MsgUpdateDowntimeParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *MsgUpdateSynchronyParams) 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 *MsgUpdateSynchronyParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateSynchronyParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateSynchronyParamsResponse) 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 *MsgUpdateSynchronyParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateSynchronyParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -334,6 +532,30 @@ func (m *MsgUpdateDowntimeParamsResponse) Size() (n int) { return n } +func (m *MsgUpdateSynchronyParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateSynchronyParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -505,6 +727,171 @@ func (m *MsgUpdateDowntimeParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgUpdateSynchronyParams) 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 ErrIntOverflowTx + } + 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: MsgUpdateSynchronyParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateSynchronyParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateSynchronyParamsResponse) 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 ErrIntOverflowTx + } + 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: MsgUpdateSynchronyParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateSynchronyParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/protocol/x/blocktime/types/tx_test.go b/protocol/x/blocktime/types/tx_test.go index c125b6f6f3..0915f52b02 100644 --- a/protocol/x/blocktime/types/tx_test.go +++ b/protocol/x/blocktime/types/tx_test.go @@ -54,3 +54,50 @@ func TestMsgUpdateDowntimeParams_ValidateBasic(t *testing.T) { }) } } + +func TestMsgUpdateSynchronyParams_ValidateBasic(t *testing.T) { + tests := map[string]struct { + msg types.MsgUpdateSynchronyParams + expectedErr error + }{ + "Success - empty params": { + msg: types.MsgUpdateSynchronyParams{ + Authority: validAuthority, + Params: types.SynchronyParams{}, + }, + }, + "Success": { + msg: types.MsgUpdateSynchronyParams{ + Authority: validAuthority, + Params: types.SynchronyParams{ + NextBlockDelay: 300 * time.Millisecond, + }, + }, + }, + "Failure: Invalid authority": { + msg: types.MsgUpdateSynchronyParams{ + Authority: "", // invalid + }, + expectedErr: types.ErrInvalidAuthority, + }, + "Failure: Invalid params": { + msg: types.MsgUpdateSynchronyParams{ + Authority: validAuthority, + Params: types.SynchronyParams{ + NextBlockDelay: -1 * time.Second, + }, + }, + expectedErr: types.ErrNegativeNextBlockDelay, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.expectedErr == nil { + require.NoError(t, err) + } else { + require.ErrorIs(t, err, tc.expectedErr) + } + }) + } +}