Skip to content

Commit 304c4d7

Browse files
authored
feat: enable multiple confirmation count values in chain params (#3461)
* 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
1 parent 5cda985 commit 304c4d7

File tree

17 files changed

+1059
-82
lines changed

17 files changed

+1059
-82
lines changed

changelog.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Features
6+
7+
* [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`
8+
59
### Tests
610

711
* [3430](https://github.com/zeta-chain/node/pull/3430) - add simulation test for MsgWithDrawEmission

docs/openapi/openapi.swagger.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -59767,6 +59767,7 @@ definitions:
5976759767
confirmation_count:
5976859768
type: string
5976959769
format: uint64
59770+
title: 'Deprecated(v28): use confirmation_params instead'
5977059771
gas_price_ticker:
5977159772
type: string
5977259773
format: uint64
@@ -59799,6 +59800,9 @@ definitions:
5979959800
type: boolean
5980059801
gateway_address:
5980159802
type: string
59803+
confirmation_params:
59804+
$ref: '#/definitions/observerConfirmationParams'
59805+
title: Advanced confirmation parameters for chain to support fast observation
5980259806
observerChainParamsList:
5980359807
type: object
5980459808
properties:
@@ -59807,6 +59811,33 @@ definitions:
5980759811
items:
5980859812
type: object
5980959813
$ref: '#/definitions/observerChainParams'
59814+
observerConfirmationParams:
59815+
type: object
59816+
properties:
59817+
safe_inbound_count:
59818+
type: string
59819+
format: uint64
59820+
description: |-
59821+
This is the safe number of confirmations to wait before an inbound is
59822+
considered finalized.
59823+
fast_inbound_count:
59824+
type: string
59825+
format: uint64
59826+
description: |-
59827+
This is the number of confirmations for fast inbound observation, which is
59828+
shorter than safe_inbound_count.
59829+
safe_outbound_count:
59830+
type: string
59831+
format: uint64
59832+
description: |-
59833+
This is the safe number of confirmations to wait before an outbound is
59834+
considered finalized.
59835+
fast_outbound_count:
59836+
type: string
59837+
format: uint64
59838+
description: |-
59839+
This is the number of confirmations for fast outbound observation, which is
59840+
shorter than safe_outbound_count.
5981059841
observerCrosschainFlags:
5981159842
type: object
5981259843
properties:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
syntax = "proto3";
2+
package zetachain.zetacore.observer;
3+
4+
option go_package = "github.com/zeta-chain/node/x/observer/types";
5+
6+
message ConfirmationParams {
7+
// This is the safe number of confirmations to wait before an inbound is
8+
// considered finalized.
9+
uint64 safe_inbound_count = 1;
10+
11+
// This is the number of confirmations for fast inbound observation, which is
12+
// shorter than safe_inbound_count.
13+
uint64 fast_inbound_count = 2;
14+
15+
// This is the safe number of confirmations to wait before an outbound is
16+
// considered finalized.
17+
uint64 safe_outbound_count = 3;
18+
19+
// This is the number of confirmations for fast outbound observation, which is
20+
// shorter than safe_outbound_count.
21+
uint64 fast_outbound_count = 4;
22+
}

proto/zetachain/zetacore/observer/params.proto

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ syntax = "proto3";
22
package zetachain.zetacore.observer;
33

44
import "gogoproto/gogo.proto";
5-
import "zetachain/zetacore/observer/observer.proto";
5+
import "zetachain/zetacore/observer/confirmation_params.proto";
66

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

99
message ChainParamsList { repeated ChainParams chain_params = 1; }
1010

1111
message ChainParams {
1212
int64 chain_id = 11;
13-
uint64 confirmation_count = 1;
13+
// Deprecated(v28): use confirmation_params instead
14+
uint64 confirmation_count = 1 [ deprecated = true ];
1415
uint64 gas_price_ticker = 2;
1516
uint64 inbound_ticker = 3;
1617
uint64 outbound_ticker = 4;
@@ -30,6 +31,9 @@ message ChainParams {
3031
];
3132
bool is_supported = 16;
3233
string gateway_address = 17;
34+
35+
// Advanced confirmation parameters for chain to support fast observation
36+
ConfirmationParams confirmation_params = 18;
3337
}
3438

3539
// Deprecated(v17)

testutil/sample/observer.go

+16
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ func ChainParams(chainID int64) *types.ChainParams {
9797
return nil
9898
}
9999

100+
confirmationParams := ConfirmationParams(r)
101+
100102
return &types.ChainParams{
101103
ChainId: chainID,
102104
ConfirmationCount: r.Uint64(),
@@ -113,6 +115,8 @@ func ChainParams(chainID int64) *types.ChainParams {
113115
BallotThreshold: fiftyPercent,
114116
MinObserverDelegation: sdkmath.LegacyNewDec(r.Int63()),
115117
IsSupported: false,
118+
GatewayAddress: EthAddress().String(),
119+
ConfirmationParams: &confirmationParams,
116120
}
117121
}
118122

@@ -337,3 +341,15 @@ func OperationalFlags() types.OperationalFlags {
337341
SignerBlockTimeOffset: ptr.Ptr(time.Second),
338342
}
339343
}
344+
345+
func ConfirmationParams(r *rand.Rand) types.ConfirmationParams {
346+
randInboundCount := Uint64InRangeFromRand(r, 1, 200)
347+
randOutboundCount := Uint64InRangeFromRand(r, 1, 200)
348+
349+
return types.ConfirmationParams{
350+
SafeInboundCount: randInboundCount,
351+
FastInboundCount: Uint64InRange(1, randInboundCount),
352+
SafeOutboundCount: randOutboundCount,
353+
FastOutboundCount: Uint64InRange(1, randOutboundCount),
354+
}
355+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// @generated by protoc-gen-es v1.3.0 with parameter "target=dts"
2+
// @generated from file zetachain/zetacore/observer/confirmation_params.proto (package zetachain.zetacore.observer, syntax proto3)
3+
/* eslint-disable */
4+
// @ts-nocheck
5+
6+
import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
7+
import { Message, proto3 } from "@bufbuild/protobuf";
8+
9+
/**
10+
* @generated from message zetachain.zetacore.observer.ConfirmationParams
11+
*/
12+
export declare class ConfirmationParams extends Message<ConfirmationParams> {
13+
/**
14+
* This is the safe number of confirmations to wait before an inbound is
15+
* considered finalized.
16+
*
17+
* @generated from field: uint64 safe_inbound_count = 1;
18+
*/
19+
safeInboundCount: bigint;
20+
21+
/**
22+
* This is the number of confirmations for fast inbound observation, which is
23+
* shorter than safe_inbound_count.
24+
*
25+
* @generated from field: uint64 fast_inbound_count = 2;
26+
*/
27+
fastInboundCount: bigint;
28+
29+
/**
30+
* This is the safe number of confirmations to wait before an outbound is
31+
* considered finalized.
32+
*
33+
* @generated from field: uint64 safe_outbound_count = 3;
34+
*/
35+
safeOutboundCount: bigint;
36+
37+
/**
38+
* This is the number of confirmations for fast outbound observation, which is
39+
* shorter than safe_outbound_count.
40+
*
41+
* @generated from field: uint64 fast_outbound_count = 4;
42+
*/
43+
fastOutboundCount: bigint;
44+
45+
constructor(data?: PartialMessage<ConfirmationParams>);
46+
47+
static readonly runtime: typeof proto3;
48+
static readonly typeName = "zetachain.zetacore.observer.ConfirmationParams";
49+
static readonly fields: FieldList;
50+
51+
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ConfirmationParams;
52+
53+
static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): ConfirmationParams;
54+
55+
static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): ConfirmationParams;
56+
57+
static equals(a: ConfirmationParams | PlainMessage<ConfirmationParams> | undefined, b: ConfirmationParams | PlainMessage<ConfirmationParams> | undefined): boolean;
58+
}
59+

typescript/zetachain/zetacore/observer/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export * from "./ballot_pb";
22
export * from "./blame_pb";
33
export * from "./chain_nonces_pb";
4+
export * from "./confirmation_params_pb";
45
export * from "./crosschain_flags_pb";
56
export * from "./events_pb";
67
export * from "./genesis_pb";

typescript/zetachain/zetacore/observer/params_pb.d.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

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

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

4243
/**
43-
* @generated from field: uint64 confirmation_count = 1;
44+
* Deprecated(v28): use confirmation_params instead
45+
*
46+
* @generated from field: uint64 confirmation_count = 1 [deprecated = true];
47+
* @deprecated
4448
*/
4549
confirmationCount: bigint;
4650

@@ -109,6 +113,13 @@ export declare class ChainParams extends Message<ChainParams> {
109113
*/
110114
gatewayAddress: string;
111115

116+
/**
117+
* Advanced confirmation parameters for chain to support fast observation
118+
*
119+
* @generated from field: zetachain.zetacore.observer.ConfirmationParams confirmation_params = 18;
120+
*/
121+
confirmationParams?: ConfirmationParams;
122+
112123
constructor(data?: PartialMessage<ChainParams>);
113124

114125
static readonly runtime: typeof proto3;

x/observer/keeper/migrator.go

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package keeper
33
import (
44
sdk "github.com/cosmos/cosmos-sdk/types"
55

6+
v10 "github.com/zeta-chain/node/x/observer/migrations/v10"
67
v8 "github.com/zeta-chain/node/x/observer/migrations/v8"
78
v9 "github.com/zeta-chain/node/x/observer/migrations/v9"
89
)
@@ -55,3 +56,8 @@ func (m Migrator) Migrate7to8(ctx sdk.Context) error {
5556
func (m Migrator) Migrate8to9(ctx sdk.Context) error {
5657
return v9.MigrateStore(ctx, m.observerKeeper)
5758
}
59+
60+
// Migrate9to10 migrates the store from consensus version 9 to 10
61+
func (m Migrator) Migrate9to10(ctx sdk.Context) error {
62+
return v10.MigrateStore(ctx, m.observerKeeper)
63+
}

x/observer/migrations/v10/migrate.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package v10
2+
3+
import (
4+
errorsmod "cosmossdk.io/errors"
5+
sdk "github.com/cosmos/cosmos-sdk/types"
6+
7+
"github.com/zeta-chain/node/x/observer/types"
8+
)
9+
10+
type observerKeeper interface {
11+
GetChainParamsList(ctx sdk.Context) (val types.ChainParamsList, found bool)
12+
SetChainParamsList(ctx sdk.Context, chainParams types.ChainParamsList)
13+
}
14+
15+
// MigrateStore migrates the x/observer module state from the consensus version 9 to version 10.
16+
// The migration sets existing 'confirmation_count' as default value for newly added fields:
17+
// - 'safe_inbound_count'
18+
// - 'fast_inbound_count'
19+
// - 'safe_outbound_count'
20+
// - 'fast_outbound_count'
21+
func MigrateStore(ctx sdk.Context, observerKeeper observerKeeper) error {
22+
allChainParams, found := observerKeeper.GetChainParamsList(ctx)
23+
if !found {
24+
return errorsmod.Wrap(types.ErrChainParamsNotFound, "failed to get chain params")
25+
}
26+
27+
// set new fields to the same value as 'confirmation_count'
28+
for _, chainParams := range allChainParams.ChainParams {
29+
if chainParams != nil {
30+
chainParams.ConfirmationParams = &types.ConfirmationParams{
31+
SafeInboundCount: chainParams.ConfirmationCount,
32+
FastInboundCount: chainParams.ConfirmationCount,
33+
SafeOutboundCount: chainParams.ConfirmationCount,
34+
FastOutboundCount: chainParams.ConfirmationCount,
35+
}
36+
}
37+
}
38+
39+
// validate the updated chain params list
40+
if err := allChainParams.Validate(); err != nil {
41+
return errorsmod.Wrap(types.ErrInvalidChainParams, err.Error())
42+
}
43+
44+
// set the updated chain params list
45+
observerKeeper.SetChainParamsList(ctx, allChainParams)
46+
47+
return nil
48+
}

0 commit comments

Comments
 (0)