Skip to content

Commit

Permalink
feat: enable multiple confirmation count values in chain params (#3461)
Browse files Browse the repository at this point in the history
* add fine-grained confirmation to chain params; add migration script

* add changelog entry

* fix unit test

* rename Confirmation as ConfirmationParams; remove 0 check on safe inbound, outbound count

* leave ConfirmationParams as empty in mock chain params, we don't check 0 count any more

* mark chain params ConfirmationCount as deprecated

* make changelog entry explicit; add proto message comment; improve migrate script and unit test

* validate all chain params during migration; return error if validation fails

* make ConfirmationParams nullable to avoid upgrade test failure; adjust checks and tests accordingly
  • Loading branch information
ws4charlie authored Feb 5, 2025
1 parent 5cda985 commit 304c4d7
Show file tree
Hide file tree
Showing 17 changed files with 1,059 additions and 82 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Features

* [3461](https://github.com/zeta-chain/node/pull/3461) - add new 'ConfirmationParams' field to chain params to enable multiple confirmation count values, deprecating `confirmation_count`

### Tests

* [3430](https://github.com/zeta-chain/node/pull/3430) - add simulation test for MsgWithDrawEmission
Expand Down
31 changes: 31 additions & 0 deletions docs/openapi/openapi.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59767,6 +59767,7 @@ definitions:
confirmation_count:
type: string
format: uint64
title: 'Deprecated(v28): use confirmation_params instead'
gas_price_ticker:
type: string
format: uint64
Expand Down Expand Up @@ -59799,6 +59800,9 @@ definitions:
type: boolean
gateway_address:
type: string
confirmation_params:
$ref: '#/definitions/observerConfirmationParams'
title: Advanced confirmation parameters for chain to support fast observation
observerChainParamsList:
type: object
properties:
Expand All @@ -59807,6 +59811,33 @@ definitions:
items:
type: object
$ref: '#/definitions/observerChainParams'
observerConfirmationParams:
type: object
properties:
safe_inbound_count:
type: string
format: uint64
description: |-
This is the safe number of confirmations to wait before an inbound is
considered finalized.
fast_inbound_count:
type: string
format: uint64
description: |-
This is the number of confirmations for fast inbound observation, which is
shorter than safe_inbound_count.
safe_outbound_count:
type: string
format: uint64
description: |-
This is the safe number of confirmations to wait before an outbound is
considered finalized.
fast_outbound_count:
type: string
format: uint64
description: |-
This is the number of confirmations for fast outbound observation, which is
shorter than safe_outbound_count.
observerCrosschainFlags:
type: object
properties:
Expand Down
22 changes: 22 additions & 0 deletions proto/zetachain/zetacore/observer/confirmation_params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
syntax = "proto3";
package zetachain.zetacore.observer;

option go_package = "github.com/zeta-chain/node/x/observer/types";

message ConfirmationParams {
// This is the safe number of confirmations to wait before an inbound is
// considered finalized.
uint64 safe_inbound_count = 1;

// This is the number of confirmations for fast inbound observation, which is
// shorter than safe_inbound_count.
uint64 fast_inbound_count = 2;

// This is the safe number of confirmations to wait before an outbound is
// considered finalized.
uint64 safe_outbound_count = 3;

// This is the number of confirmations for fast outbound observation, which is
// shorter than safe_outbound_count.
uint64 fast_outbound_count = 4;
}
8 changes: 6 additions & 2 deletions proto/zetachain/zetacore/observer/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ syntax = "proto3";
package zetachain.zetacore.observer;

import "gogoproto/gogo.proto";
import "zetachain/zetacore/observer/observer.proto";
import "zetachain/zetacore/observer/confirmation_params.proto";

option go_package = "github.com/zeta-chain/node/x/observer/types";

message ChainParamsList { repeated ChainParams chain_params = 1; }

message ChainParams {
int64 chain_id = 11;
uint64 confirmation_count = 1;
// Deprecated(v28): use confirmation_params instead
uint64 confirmation_count = 1 [ deprecated = true ];
uint64 gas_price_ticker = 2;
uint64 inbound_ticker = 3;
uint64 outbound_ticker = 4;
Expand All @@ -30,6 +31,9 @@ message ChainParams {
];
bool is_supported = 16;
string gateway_address = 17;

// Advanced confirmation parameters for chain to support fast observation
ConfirmationParams confirmation_params = 18;
}

// Deprecated(v17)
Expand Down
16 changes: 16 additions & 0 deletions testutil/sample/observer.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ func ChainParams(chainID int64) *types.ChainParams {
return nil
}

confirmationParams := ConfirmationParams(r)

return &types.ChainParams{
ChainId: chainID,
ConfirmationCount: r.Uint64(),
Expand All @@ -113,6 +115,8 @@ func ChainParams(chainID int64) *types.ChainParams {
BallotThreshold: fiftyPercent,
MinObserverDelegation: sdkmath.LegacyNewDec(r.Int63()),
IsSupported: false,
GatewayAddress: EthAddress().String(),
ConfirmationParams: &confirmationParams,
}
}

Expand Down Expand Up @@ -337,3 +341,15 @@ func OperationalFlags() types.OperationalFlags {
SignerBlockTimeOffset: ptr.Ptr(time.Second),
}
}

func ConfirmationParams(r *rand.Rand) types.ConfirmationParams {
randInboundCount := Uint64InRangeFromRand(r, 1, 200)
randOutboundCount := Uint64InRangeFromRand(r, 1, 200)

return types.ConfirmationParams{
SafeInboundCount: randInboundCount,
FastInboundCount: Uint64InRange(1, randInboundCount),
SafeOutboundCount: randOutboundCount,
FastOutboundCount: Uint64InRange(1, randOutboundCount),
}
}
59 changes: 59 additions & 0 deletions typescript/zetachain/zetacore/observer/confirmation_params_pb.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// @generated by protoc-gen-es v1.3.0 with parameter "target=dts"
// @generated from file zetachain/zetacore/observer/confirmation_params.proto (package zetachain.zetacore.observer, syntax proto3)
/* eslint-disable */
// @ts-nocheck

import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3 } from "@bufbuild/protobuf";

/**
* @generated from message zetachain.zetacore.observer.ConfirmationParams
*/
export declare class ConfirmationParams extends Message<ConfirmationParams> {
/**
* This is the safe number of confirmations to wait before an inbound is
* considered finalized.
*
* @generated from field: uint64 safe_inbound_count = 1;
*/
safeInboundCount: bigint;

/**
* This is the number of confirmations for fast inbound observation, which is
* shorter than safe_inbound_count.
*
* @generated from field: uint64 fast_inbound_count = 2;
*/
fastInboundCount: bigint;

/**
* This is the safe number of confirmations to wait before an outbound is
* considered finalized.
*
* @generated from field: uint64 safe_outbound_count = 3;
*/
safeOutboundCount: bigint;

/**
* This is the number of confirmations for fast outbound observation, which is
* shorter than safe_outbound_count.
*
* @generated from field: uint64 fast_outbound_count = 4;
*/
fastOutboundCount: bigint;

constructor(data?: PartialMessage<ConfirmationParams>);

static readonly runtime: typeof proto3;
static readonly typeName = "zetachain.zetacore.observer.ConfirmationParams";
static readonly fields: FieldList;

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ConfirmationParams;

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ConfirmationParams;

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ConfirmationParams;

static equals(a: ConfirmationParams | PlainMessage<ConfirmationParams> | undefined, b: ConfirmationParams | PlainMessage<ConfirmationParams> | undefined): boolean;
}

1 change: 1 addition & 0 deletions typescript/zetachain/zetacore/observer/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from "./ballot_pb";
export * from "./blame_pb";
export * from "./chain_nonces_pb";
export * from "./confirmation_params_pb";
export * from "./crosschain_flags_pb";
export * from "./events_pb";
export * from "./genesis_pb";
Expand Down
13 changes: 12 additions & 1 deletion typescript/zetachain/zetacore/observer/params_pb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
import { Message, proto3 } from "@bufbuild/protobuf";
import type { ConfirmationParams } from "./confirmation_params_pb.js";

/**
* @generated from message zetachain.zetacore.observer.ChainParamsList
Expand Down Expand Up @@ -40,7 +41,10 @@ export declare class ChainParams extends Message<ChainParams> {
chainId: bigint;

/**
* @generated from field: uint64 confirmation_count = 1;
* Deprecated(v28): use confirmation_params instead
*
* @generated from field: uint64 confirmation_count = 1 [deprecated = true];
* @deprecated
*/
confirmationCount: bigint;

Expand Down Expand Up @@ -109,6 +113,13 @@ export declare class ChainParams extends Message<ChainParams> {
*/
gatewayAddress: string;

/**
* Advanced confirmation parameters for chain to support fast observation
*
* @generated from field: zetachain.zetacore.observer.ConfirmationParams confirmation_params = 18;
*/
confirmationParams?: ConfirmationParams;

constructor(data?: PartialMessage<ChainParams>);

static readonly runtime: typeof proto3;
Expand Down
6 changes: 6 additions & 0 deletions x/observer/keeper/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"

v10 "github.com/zeta-chain/node/x/observer/migrations/v10"
v8 "github.com/zeta-chain/node/x/observer/migrations/v8"
v9 "github.com/zeta-chain/node/x/observer/migrations/v9"
)
Expand Down Expand Up @@ -55,3 +56,8 @@ func (m Migrator) Migrate7to8(ctx sdk.Context) error {
func (m Migrator) Migrate8to9(ctx sdk.Context) error {
return v9.MigrateStore(ctx, m.observerKeeper)
}

// Migrate9to10 migrates the store from consensus version 9 to 10
func (m Migrator) Migrate9to10(ctx sdk.Context) error {
return v10.MigrateStore(ctx, m.observerKeeper)
}
48 changes: 48 additions & 0 deletions x/observer/migrations/v10/migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package v10

import (
errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/zeta-chain/node/x/observer/types"
)

type observerKeeper interface {
GetChainParamsList(ctx sdk.Context) (val types.ChainParamsList, found bool)
SetChainParamsList(ctx sdk.Context, chainParams types.ChainParamsList)
}

// MigrateStore migrates the x/observer module state from the consensus version 9 to version 10.
// The migration sets existing 'confirmation_count' as default value for newly added fields:
// - 'safe_inbound_count'
// - 'fast_inbound_count'
// - 'safe_outbound_count'
// - 'fast_outbound_count'
func MigrateStore(ctx sdk.Context, observerKeeper observerKeeper) error {
allChainParams, found := observerKeeper.GetChainParamsList(ctx)
if !found {
return errorsmod.Wrap(types.ErrChainParamsNotFound, "failed to get chain params")
}

// set new fields to the same value as 'confirmation_count'
for _, chainParams := range allChainParams.ChainParams {
if chainParams != nil {
chainParams.ConfirmationParams = &types.ConfirmationParams{
SafeInboundCount: chainParams.ConfirmationCount,
FastInboundCount: chainParams.ConfirmationCount,
SafeOutboundCount: chainParams.ConfirmationCount,
FastOutboundCount: chainParams.ConfirmationCount,
}
}
}

// validate the updated chain params list
if err := allChainParams.Validate(); err != nil {
return errorsmod.Wrap(types.ErrInvalidChainParams, err.Error())
}

// set the updated chain params list
observerKeeper.SetChainParamsList(ctx, allChainParams)

return nil
}
Loading

0 comments on commit 304c4d7

Please sign in to comment.