diff --git a/changelog.md b/changelog.md index 434d69161e..439e33b100 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,7 @@ * [3170](https://github.com/zeta-chain/node/pull/3170) - revamp TSS package in zetaclient * [3291](https://github.com/zeta-chain/node/pull/3291) - revamp zetaclient initialization (+ graceful shutdown) +* [2863](https://github.com/zeta-chain/node/pull/2863) - refactor zetacore to delete matured ballots and add a migration script to remove all old ballots. ### Fixes diff --git a/docs/cli/zetacored/cli.md b/docs/cli/zetacored/cli.md index 56e293efe4..c5c6401918 100644 --- a/docs/cli/zetacored/cli.md +++ b/docs/cli/zetacored/cli.md @@ -5376,6 +5376,7 @@ zetacored query observer [flags] * [zetacored query](#zetacored-query) - Querying subcommands * [zetacored query observer get-historical-tss-address](#zetacored-query-observer-get-historical-tss-address) - Query tss address by finalized zeta height (for historical tss addresses) * [zetacored query observer get-tss-address](#zetacored-query-observer-get-tss-address) - Query current tss address +* [zetacored query observer list-ballots](#zetacored-query-observer-list-ballots) - Query all ballots * [zetacored query observer list-blame](#zetacored-query-observer-list-blame) - Query AllBlameRecords * [zetacored query observer list-blame-by-msg](#zetacored-query-observer-list-blame-by-msg) - Query AllBlameRecords * [zetacored query observer list-chain-nonces](#zetacored-query-observer-list-chain-nonces) - list all chainNonces @@ -5466,6 +5467,40 @@ zetacored query observer get-tss-address [bitcoinChainId]] [flags] * [zetacored query observer](#zetacored-query-observer) - Querying commands for the observer module +## zetacored query observer list-ballots + +Query all ballots + +``` +zetacored query observer list-ballots [flags] +``` + +### Options + +``` + --grpc-addr string the gRPC endpoint to use for this chain + --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS + --height int Use a specific height to query state at (this can error if the node is pruning state) + -h, --help help for list-ballots + --node string [host]:[port] to Tendermint RPC interface for this chain + -o, --output string Output format (text|json) +``` + +### Options inherited from parent commands + +``` + --chain-id string The network chain ID + --home string directory for config and data + --log_format string The logging format (json|plain) + --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) + --log_no_color Disable colored logs + --trace print out full stack trace on errors +``` + +### SEE ALSO + +* [zetacored query observer](#zetacored-query-observer) - Querying commands for the observer module + ## zetacored query observer list-blame Query AllBlameRecords diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 65f305da0f..63b56b395e 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -29981,6 +29981,65 @@ paths: type: string tags: - Query + /zeta-chain/observer/ballots: + get: + summary: Query all ballots + operationId: Query_Ballots + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/observerQueryBallotsResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: pagination.key + description: |- + key is a value returned in PageResponse.next_key to begin + querying the next page most efficiently. Only one of offset or key + should be set. + in: query + required: false + type: string + format: byte + - name: pagination.offset + description: |- + offset is a numeric offset that can be used when key is unavailable. + It is less efficient than using key. Only one of offset or key should + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: |- + limit is the total number of results to be returned in the result page. + If left empty it will default to a value to be set by each app. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: |- + count_total is set to true to indicate that the result set should include + a count of the total number of items available for pagination in UIs. + count_total is only respected when offset is used. It is ignored when key + is set. + in: query + required: false + type: boolean + - name: pagination.reverse + description: |- + reverse is set to true if results are to be returned in the descending order. + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean + tags: + - Query /zeta-chain/observer/blame_by_chain_and_nonce/{chain_id}/{nonce}: get: summary: Queries a list of VoterByIdentifier items. @@ -57864,6 +57923,31 @@ definitions: properties: valid: type: boolean + observerBallot: + type: object + properties: + index: + type: string + ballot_identifier: + type: string + voter_list: + type: array + items: + type: string + votes: + type: array + items: + $ref: '#/definitions/observerVoteType' + observation_type: + $ref: '#/definitions/observerObservationType' + ballot_threshold: + type: string + ballot_status: + $ref: '#/definitions/observerBallotStatus' + ballot_creation_height: + type: string + format: int64 + title: https://github.com/zeta-chain/node/issues/939 observerBallotStatus: type: string enum: @@ -58180,6 +58264,16 @@ definitions: $ref: '#/definitions/observerObservationType' ballot_status: $ref: '#/definitions/observerBallotStatus' + observerQueryBallotsResponse: + type: object + properties: + ballots: + type: array + items: + type: object + $ref: '#/definitions/observerBallot' + pagination: + $ref: '#/definitions/v1beta1PageResponse' observerQueryBlameByChainAndNonceResponse: type: object properties: diff --git a/proto/zetachain/zetacore/observer/query.proto b/proto/zetachain/zetacore/observer/query.proto index f58e3f9118..82f7359340 100644 --- a/proto/zetachain/zetacore/observer/query.proto +++ b/proto/zetachain/zetacore/observer/query.proto @@ -171,6 +171,20 @@ service Query { returns (QueryOperationalFlagsResponse) { option (google.api.http).get = "/zeta-chain/observer/operationalFlags"; } + + // Query all ballots + rpc Ballots(QueryBallotsRequest) returns (QueryBallotsResponse) { + option (google.api.http).get = "/zeta-chain/observer/ballots"; + } +} + +message QueryBallotsRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +message QueryBallotsResponse { + repeated Ballot ballots = 1 [ (gogoproto.nullable) = false ]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; } message QueryOperationalFlagsRequest {} @@ -259,6 +273,7 @@ message QueryHasVotedRequest { message QueryHasVotedResponse { bool has_voted = 1; } message QueryBallotByIdentifierRequest { string ballot_identifier = 1; } + message VoterList { string voter_address = 1; VoteType vote_type = 2; diff --git a/testutil/keeper/mocks/emissions/observer.go b/testutil/keeper/mocks/emissions/observer.go index 501cc68d43..18c95ae92c 100644 --- a/testutil/keeper/mocks/emissions/observer.go +++ b/testutil/keeper/mocks/emissions/observer.go @@ -15,6 +15,11 @@ type EmissionObserverKeeper struct { mock.Mock } +// ClearMaturedBallotsAndBallotList provides a mock function with given fields: ctx, maturityBlocks +func (_m *EmissionObserverKeeper) ClearMaturedBallotsAndBallotList(ctx types.Context, maturityBlocks int64) { + _m.Called(ctx, maturityBlocks) +} + // GetBallot provides a mock function with given fields: ctx, index func (_m *EmissionObserverKeeper) GetBallot(ctx types.Context, index string) (observertypes.Ballot, bool) { ret := _m.Called(ctx, index) diff --git a/testutil/sample/logger.go b/testutil/sample/logger.go new file mode 100644 index 0000000000..684e2d6f50 --- /dev/null +++ b/testutil/sample/logger.go @@ -0,0 +1,26 @@ +package sample + +import ( + "bytes" + + "github.com/cometbft/cometbft/libs/log" +) + +type TestLogger struct { + buf bytes.Buffer + log.Logger +} + +func NewTestLogger() *TestLogger { + tl := &TestLogger{} + tl.Logger = log.NewTMLogger(log.NewSyncWriter(&tl.buf)) + return tl +} + +func (t *TestLogger) Write(p []byte) (n int, err error) { + return t.buf.Write(p) +} + +func (t *TestLogger) String() string { + return t.buf.String() +} diff --git a/typescript/zetachain/zetacore/observer/query_pb.d.ts b/typescript/zetachain/zetacore/observer/query_pb.d.ts index 2fbfdc9e8a..5294d80105 100644 --- a/typescript/zetachain/zetacore/observer/query_pb.d.ts +++ b/typescript/zetachain/zetacore/observer/query_pb.d.ts @@ -5,13 +5,13 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; +import type { PageRequest, PageResponse } from "../../../cosmos/base/query/v1beta1/pagination_pb.js"; +import type { Ballot, BallotStatus, VoteType } from "./ballot_pb.js"; import type { OperationalFlags } from "./operational_pb.js"; import type { TssFundMigratorInfo } from "./tss_funds_migrator_pb.js"; import type { ChainNonces } from "./chain_nonces_pb.js"; -import type { PageRequest, PageResponse } from "../../../cosmos/base/query/v1beta1/pagination_pb.js"; import type { PendingNonces } from "./pending_nonces_pb.js"; import type { TSS } from "./tss_pb.js"; -import type { BallotStatus, VoteType } from "./ballot_pb.js"; import type { LastObserverCount, ObservationType } from "./observer_pb.js"; import type { Chain } from "../pkg/chains/chains_pb.js"; import type { ChainParams, ChainParamsList } from "./params_pb.js"; @@ -20,6 +20,59 @@ import type { CrosschainFlags } from "./crosschain_flags_pb.js"; import type { Keygen } from "./keygen_pb.js"; import type { Blame } from "./blame_pb.js"; +/** + * @generated from message zetachain.zetacore.observer.QueryBallotsRequest + */ +export declare class QueryBallotsRequest extends Message { + /** + * @generated from field: cosmos.base.query.v1beta1.PageRequest pagination = 1; + */ + pagination?: PageRequest; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.QueryBallotsRequest"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryBallotsRequest; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryBallotsRequest; + + static fromJsonString(jsonString: string, options?: Partial): QueryBallotsRequest; + + static equals(a: QueryBallotsRequest | PlainMessage | undefined, b: QueryBallotsRequest | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.observer.QueryBallotsResponse + */ +export declare class QueryBallotsResponse extends Message { + /** + * @generated from field: repeated zetachain.zetacore.observer.Ballot ballots = 1; + */ + ballots: Ballot[]; + + /** + * @generated from field: cosmos.base.query.v1beta1.PageResponse pagination = 2; + */ + pagination?: PageResponse; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.QueryBallotsResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryBallotsResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryBallotsResponse; + + static fromJsonString(jsonString: string, options?: Partial): QueryBallotsResponse; + + static equals(a: QueryBallotsResponse | PlainMessage | undefined, b: QueryBallotsResponse | PlainMessage | undefined): boolean; +} + /** * @generated from message zetachain.zetacore.observer.QueryOperationalFlagsRequest */ diff --git a/x/emissions/abci.go b/x/emissions/abci.go index c1924ff2e2..1cb1ccdc22 100644 --- a/x/emissions/abci.go +++ b/x/emissions/abci.go @@ -4,16 +4,18 @@ import ( "fmt" "sort" + sdkerrors "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/node/cmd/zetacored/config" "github.com/zeta-chain/node/x/emissions/keeper" "github.com/zeta-chain/node/x/emissions/types" + observertypes "github.com/zeta-chain/node/x/observer/types" ) -func BeginBlocker(ctx sdk.Context, keeper keeper.Keeper) { - emissionPoolBalance := keeper.GetReservesFactor(ctx) +func BeginBlocker(ctx sdk.Context, emissionsKeeper keeper.Keeper) { + emissionPoolBalance := emissionsKeeper.GetReservesFactor(ctx) // reduce frequency of log messages logEach10Blocks := func(message string) { @@ -25,7 +27,7 @@ func BeginBlocker(ctx sdk.Context, keeper keeper.Keeper) { } // Get the block rewards from the params - params, found := keeper.GetParams(ctx) + params, found := emissionsKeeper.GetParams(ctx) if !found { ctx.Logger().Error("Params not found") return @@ -51,24 +53,29 @@ func BeginBlocker(ctx sdk.Context, keeper keeper.Keeper) { // Use a tmpCtx, which is a cache-wrapped context to avoid writing to the store // We commit only if all three distributions are successful, if not the funds stay in the emission pool tmpCtx, commit := ctx.CacheContext() - err := DistributeValidatorRewards(tmpCtx, validatorRewards, keeper.GetBankKeeper(), keeper.GetFeeCollector()) + err := DistributeValidatorRewards( + tmpCtx, + validatorRewards, + emissionsKeeper.GetBankKeeper(), + emissionsKeeper.GetFeeCollector(), + ) if err != nil { ctx.Logger().Error(fmt.Sprintf("Error while distributing validator rewards %s", err)) return } - err = DistributeObserverRewards(tmpCtx, observerRewards, keeper, params) + err = DistributeObserverRewards(tmpCtx, observerRewards, emissionsKeeper, params) if err != nil { ctx.Logger().Error(fmt.Sprintf("Error while distributing observer rewards %s", err)) return } - err = DistributeTSSRewards(tmpCtx, tssSignerRewards, keeper.GetBankKeeper()) + err = DistributeTSSRewards(tmpCtx, tssSignerRewards, emissionsKeeper.GetBankKeeper()) if err != nil { ctx.Logger().Error(fmt.Sprintf("Error while distributing tss signer rewards %s", err)) return } commit() - types.EmitValidatorEmissions(ctx, "", "", + keeper.EmitValidatorEmissions(ctx, "", "", "", validatorRewards.String(), observerRewards.String(), @@ -97,45 +104,88 @@ func DistributeValidatorRewards( func DistributeObserverRewards( ctx sdk.Context, amount sdkmath.Int, - keeper keeper.Keeper, + emissionsKeeper keeper.Keeper, params types.Params, ) error { - slashAmount := params.ObserverSlashAmount - rewardsDistributer := map[string]int64{} - totalRewardsUnits := int64(0) - err := keeper.GetBankKeeper(). + var ( + slashAmount = params.ObserverSlashAmount + maturityBlocks = params.BallotMaturityBlocks + maturedBallots []string + ) + + err := emissionsKeeper.GetBankKeeper(). SendCoinsFromModuleToModule(ctx, types.ModuleName, types.UndistributedObserverRewardsPool, sdk.NewCoins(sdk.NewCoin(config.BaseDenom, amount))) if err != nil { - return err + return sdkerrors.Wrap(err, "error while transferring funds to the undistributed pool") } - list, found := keeper.GetObserverKeeper().GetMaturedBallots(ctx, params.BallotMaturityBlocks) - ballotIdentifiers := []string{} + // Fetch the matured ballots for this block + list, found := emissionsKeeper.GetObserverKeeper().GetMaturedBallots(ctx, maturityBlocks) if found { - ballotIdentifiers = list.BallotsIndexList + maturedBallots = list.BallotsIndexList } - // do not distribute rewards if no ballots are matured, the rewards can accumulate in the undistributed pool - if len(ballotIdentifiers) == 0 { + if len(maturedBallots) == 0 { return nil } - for _, ballotIdentifier := range ballotIdentifiers { + + // We have some matured ballots, we now need to process them + // Processing Step 1: Distribute the rewards + // Final distribution list is the list of ObserverEmissions, which will be emitted as events + finalDistributionList := distributeRewardsForMaturedBallots( + ctx, + emissionsKeeper, + maturedBallots, + amount, + slashAmount, + ) + + // Processing Step 2: Emit the observer emissions + keeper.EmitObserverEmissions(ctx, finalDistributionList) + + // Processing Step 3: Delete all matured ballots and the ballot list + emissionsKeeper.GetObserverKeeper().ClearMaturedBallotsAndBallotList(ctx, params.BallotMaturityBlocks) + return nil +} + +// DistributeTSSRewards trasferes the allocated rewards to the Undistributed Tss Rewards Pool. +// This is done so that the reserves factor is properly calculated in the next block +func DistributeTSSRewards(ctx sdk.Context, amount sdk.Int, bankKeeper types.BankKeeper) error { + coin := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, amount)) + return bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.UndistributedTSSRewardsPool, coin) +} + +func distributeRewardsForMaturedBallots( + ctx sdk.Context, + keeper keeper.Keeper, + maturedBallots []string, + amount sdkmath.Int, + slashAmount sdkmath.Int, +) []*types.ObserverEmission { + var ( + rewardsDistributeMap = map[string]int64{} + totalRewardsUnits = int64(0) + ) + ballots := make([]observertypes.Ballot, 0, len(maturedBallots)) + for _, ballotIdentifier := range maturedBallots { ballot, found := keeper.GetObserverKeeper().GetBallot(ctx, ballotIdentifier) if !found { continue } - totalRewardsUnits += ballot.BuildRewardsDistribution(rewardsDistributer) + ballots = append(ballots, ballot) + totalRewardsUnits += ballot.BuildRewardsDistribution(rewardsDistributeMap) } rewardPerUnit := sdkmath.ZeroInt() if totalRewardsUnits > 0 && amount.IsPositive() { rewardPerUnit = amount.Quo(sdk.NewInt(totalRewardsUnits)) } ctx.Logger(). - Debug(fmt.Sprintf("Total Rewards Units : %d , rewards per Unit %s ,number of ballots :%d", totalRewardsUnits, rewardPerUnit.String(), len(ballotIdentifiers))) - sortedKeys := make([]string, 0, len(rewardsDistributer)) - for k := range rewardsDistributer { + Debug(fmt.Sprintf("Total Rewards Units : %d , rewards per Unit %s ,number of ballots :%d", totalRewardsUnits, rewardPerUnit.String(), len(maturedBallots))) + sortedKeys := make([]string, 0, len(rewardsDistributeMap)) + for k := range rewardsDistributeMap { sortedKeys = append(sortedKeys, k) } + sort.Strings(sortedKeys) var finalDistributionList []*types.ObserverEmission for _, key := range sortedKeys { @@ -146,7 +196,7 @@ func DistributeObserverRewards( } // observerRewardUnits can be negative if the observer has been slashed // an observers earn 1 unit for a correct vote, and -1 unit for an incorrect vote - observerRewardUnits := rewardsDistributer[key] + observerRewardUnits := rewardsDistributeMap[key] if observerRewardUnits == 0 { finalDistributionList = append(finalDistributionList, &types.ObserverEmission{ @@ -177,15 +227,5 @@ func DistributeObserverRewards( }) } } - types.EmitObserverEmissions(ctx, finalDistributionList) - // TODO : Delete Ballots after distribution - // https://github.com/zeta-chain/node/issues/942 - return nil -} - -// DistributeTSSRewards trasferes the allocated rewards to the Undistributed Tss Rewards Pool. -// This is done so that the reserves factor is properly calculated in the next block -func DistributeTSSRewards(ctx sdk.Context, amount sdk.Int, bankKeeper types.BankKeeper) error { - coin := sdk.NewCoins(sdk.NewCoin(config.BaseDenom, amount)) - return bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.UndistributedTSSRewardsPool, coin) + return finalDistributionList } diff --git a/x/emissions/abci_test.go b/x/emissions/abci_test.go index b29698c398..7905480e35 100644 --- a/x/emissions/abci_test.go +++ b/x/emissions/abci_test.go @@ -204,7 +204,8 @@ func TestBeginBlocker(t *testing.T) { }) t.Run("successfully distribute rewards", func(t *testing.T) { - numberOfTestBlocks := 100 + //Arrange + numberOfTestBlocks := 10 k, ctx, sk, zk := keepertest.EmissionsKeeper(t) observerSet := sample.ObserverSet(10) zk.ObserverKeeper.SetObserverSet(ctx, observerSet) @@ -239,6 +240,9 @@ func TestBeginBlocker(t *testing.T) { params, found := k.GetParams(ctx) require.True(t, found) + // Set the ballot maturity blocks to numberOfTestBlocks so that the ballot mature at the end of the for loop which produces blocks + params.BallotMaturityBlocks = int64(numberOfTestBlocks) + err = k.SetParams(ctx, params) // Get the rewards distribution, this is a fixed amount based on total block rewards and distribution percentages validatorRewardsForABlock, observerRewardsForABlock, tssSignerRewardsForABlock := emissionstypes.GetRewardsDistributions( @@ -248,6 +252,11 @@ func TestBeginBlocker(t *testing.T) { distributedRewards := observerRewardsForABlock.Add(validatorRewardsForABlock).Add(tssSignerRewardsForABlock) require.True(t, blockRewards.TruncateInt().GT(distributedRewards)) + require.Len(t, zk.ObserverKeeper.GetAllBallots(ctx), len(ballotList)) + _, found = zk.ObserverKeeper.GetBallotListForHeight(ctx, 0) + require.True(t, found) + + // Act for i := 0; i < numberOfTestBlocks; i++ { emissionPoolBeforeBlockDistribution := sk.BankKeeper.GetBalance(ctx, emissionPool, config.BaseDenom).Amount // produce a block @@ -278,12 +287,23 @@ func TestBeginBlocker(t *testing.T) { ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) } + // Assert + + // 1. Assert Observer rewards, these are distributed at the block in which the ballots mature. + // numberOfTestBlocks is the same maturity blocks for the ballots + // We can simplify the calculation as the rewards are distributed equally among all the observers rewardPerUnit := observerRewardsForABlock.Quo( sdk.NewInt(int64(len(ballotList) * len(observerSet.ObserverList))), ) emissionAmount := rewardPerUnit.Mul(sdk.NewInt(int64(len(ballotList)))) + // 2 . Assert ballots and ballot list are deleted on maturity + require.Len(t, zk.ObserverKeeper.GetAllBallots(ctx), 0) + _, found = zk.ObserverKeeper.GetBallotListForHeight(ctx, 0) + require.False(t, found) + + //3. Assert amounts in undistributed pools // Check if the rewards are distributed equally among all the observers for _, observer := range observerSet.ObserverList { observerEmission, found := k.GetWithdrawableEmission(ctx, observer) diff --git a/x/emissions/types/events.go b/x/emissions/keeper/events.go similarity index 74% rename from x/emissions/types/events.go rename to x/emissions/keeper/events.go index 224212fc5a..97e4c54072 100644 --- a/x/emissions/types/events.go +++ b/x/emissions/keeper/events.go @@ -1,14 +1,16 @@ -package types +package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/zeta-chain/node/x/emissions/types" ) func EmitValidatorEmissions( ctx sdk.Context, bondFactor, reservesFactor, durationsFactor, validatorRewards, observerRewards, tssRewards string, ) { - err := ctx.EventManager().EmitTypedEvents(&EventBlockEmissions{ + err := ctx.EventManager().EmitTypedEvents(&types.EventBlockEmissions{ MsgTypeUrl: "/zetachain.zetacore.emissions.internal.BlockEmissions", BondFactor: bondFactor, DurationFactor: durationsFactor, @@ -22,8 +24,8 @@ func EmitValidatorEmissions( } } -func EmitObserverEmissions(ctx sdk.Context, em []*ObserverEmission) { - err := ctx.EventManager().EmitTypedEvents(&EventObserverEmissions{ +func EmitObserverEmissions(ctx sdk.Context, em []*types.ObserverEmission) { + err := ctx.EventManager().EmitTypedEvents(&types.EventObserverEmissions{ MsgTypeUrl: "/zetachain.zetacore.emissions.internal.ObserverEmissions", Emissions: em, }) diff --git a/x/emissions/types/expected_keepers.go b/x/emissions/types/expected_keepers.go index bf67b183be..a0754a8870 100644 --- a/x/emissions/types/expected_keepers.go +++ b/x/emissions/types/expected_keepers.go @@ -16,6 +16,7 @@ type AccountKeeper interface { type ObserverKeeper interface { GetBallot(ctx sdk.Context, index string) (val observertypes.Ballot, found bool) GetMaturedBallots(ctx sdk.Context, maturityBlocks int64) (val observertypes.BallotListForHeight, found bool) + ClearMaturedBallotsAndBallotList(ctx sdk.Context, maturityBlocks int64) } // BankKeeper defines the expected interface needed to retrieve account balances. diff --git a/x/observer/client/cli/query.go b/x/observer/client/cli/query.go index 04c773063b..5276430453 100644 --- a/x/observer/client/cli/query.go +++ b/x/observer/client/cli/query.go @@ -44,6 +44,7 @@ func GetQueryCmd(_ string) *cobra.Command { CmdGetAllTssFundsMigrator(), CmdGetTssFundsMigrator(), CmdShowOperationalFlags(), + CmdAllBallots(), ) return cmd diff --git a/x/observer/client/cli/query_ballot.go b/x/observer/client/cli/query_ballot.go index 6d724a3571..4e4ce65f6b 100644 --- a/x/observer/client/cli/query_ballot.go +++ b/x/observer/client/cli/query_ballot.go @@ -8,6 +8,7 @@ import ( "github.com/zeta-chain/node/x/observer/types" ) +// CmdBallotByIdentifier returns a command which queries a ballot by its identifier func CmdBallotByIdentifier() *cobra.Command { cmd := &cobra.Command{ Use: "show-ballot [ballot-identifier]", @@ -37,6 +38,39 @@ func CmdBallotByIdentifier() *cobra.Command { } flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +// CmdAllBallots returns a command which queries all ballots +func CmdAllBallots() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-ballots", + Short: "Query all ballots", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, _ []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryBallotsRequest{ + Pagination: pageReq, + } + + res, err := queryClient.Ballots(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) return cmd } diff --git a/x/observer/keeper/ballot.go b/x/observer/keeper/ballot.go index 799f5c8281..3465e18709 100644 --- a/x/observer/keeper/ballot.go +++ b/x/observer/keeper/ballot.go @@ -1,6 +1,8 @@ package keeper import ( + "fmt" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -20,6 +22,16 @@ func (k Keeper) SetBallotList(ctx sdk.Context, ballotlist *types.BallotListForHe store.Set(types.BallotListKeyPrefix(ballotlist.Height), b) } +func (k Keeper) DeleteBallot(ctx sdk.Context, index string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.VoterKey)) + store.Delete([]byte(index)) +} + +func (k Keeper) DeleteBallotListForHeight(ctx sdk.Context, height int64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BallotListKey)) + store.Delete(types.BallotListKeyPrefix(height)) +} + func (k Keeper) GetBallot(ctx sdk.Context, index string) (val types.Ballot, found bool) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.VoterKey)) b := store.Get(types.KeyPrefix(index)) @@ -30,18 +42,21 @@ func (k Keeper) GetBallot(ctx sdk.Context, index string) (val types.Ballot, foun return val, true } -func (k Keeper) GetBallotList(ctx sdk.Context, height int64) (val types.BallotListForHeight, found bool) { +func (k Keeper) GetBallotListForHeight(ctx sdk.Context, height int64) (val types.BallotListForHeight, found bool) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.BallotListKey)) b := store.Get(types.BallotListKeyPrefix(height)) if b == nil { - return val, false + return types.BallotListForHeight{ + Height: height, + BallotsIndexList: nil, + }, false } k.cdc.MustUnmarshal(b, &val) return val, true } func (k Keeper) GetMaturedBallots(ctx sdk.Context, maturityBlocks int64) (val types.BallotListForHeight, found bool) { - return k.GetBallotList(ctx, ctx.BlockHeight()-maturityBlocks) + return k.GetBallotListForHeight(ctx, getMaturedBallotHeight(ctx, maturityBlocks)) } func (k Keeper) GetAllBallots(ctx sdk.Context) (voters []*types.Ballot) { @@ -58,10 +73,57 @@ func (k Keeper) GetAllBallots(ctx sdk.Context) (voters []*types.Ballot) { // AddBallotToList adds a ballot to the list of ballots for a given height. func (k Keeper) AddBallotToList(ctx sdk.Context, ballot types.Ballot) { - list, found := k.GetBallotList(ctx, ballot.BallotCreationHeight) + list, found := k.GetBallotListForHeight(ctx, ballot.BallotCreationHeight) if !found { list = types.BallotListForHeight{Height: ballot.BallotCreationHeight, BallotsIndexList: []string{}} } list.BallotsIndexList = append(list.BallotsIndexList, ballot.BallotIdentifier) k.SetBallotList(ctx, &list) } + +// ClearMaturedBallotsAndBallotList deletes all matured ballots and the list of ballots for a given height. +// It also emits an event for each ballot deleted. +func (k Keeper) ClearMaturedBallotsAndBallotList(ctx sdk.Context, maturityBlocksParam int64) { + maturedBallotsHeight := getMaturedBallotHeight(ctx, maturityBlocksParam) + + // Fetch all the matured ballots, return if no matured ballots are found + // For the current implementation, this should never happen as ClearMaturedBallotsAndBallotList is only called after the Distribution of the rewards, + // which means that there are matured ballots to be deleted + maturedBallots, found := k.GetBallotListForHeight(ctx, maturedBallotsHeight) + if !found { + return + } + // Delete all the matured ballots and emit an event for each ballot deleted + for _, ballotIndex := range maturedBallots.BallotsIndexList { + ballot, found := k.GetBallot(ctx, ballotIndex) + if !found { + continue + } + k.DeleteBallot(ctx, ballotIndex) + logBallotDeletion(ctx, ballot) + } + // Delete the list of matured ballots + k.DeleteBallotListForHeight(ctx, maturedBallotsHeight) + return +} + +// getMaturedBallotHeight returns the height at which a ballot is considered matured. +func getMaturedBallotHeight(ctx sdk.Context, maturityBlocks int64) int64 { + return ctx.BlockHeight() - maturityBlocks +} + +func logBallotDeletion(ctx sdk.Context, ballot types.Ballot) { + if len(ballot.VoterList) != len(ballot.Votes) { + ctx.Logger(). + Error(fmt.Sprintf("voter list and votes list length mismatch for deleted ballot %s", ballot.BallotIdentifier)) + return + } + + votersList := "" + for i := range ballot.VoterList { + votersList += fmt.Sprintf("Voter : %s | Vote : %s\n", ballot.VoterList[i], ballot.Votes[i]) + } + + ctx.Logger(). + Debug(fmt.Sprintf("ballotIdentifier: %s,ballotType: %s,voterList: %s", ballot.BallotIdentifier, ballot.ObservationType.String(), votersList)) +} diff --git a/x/observer/keeper/ballot_test.go b/x/observer/keeper/ballot_test.go index 2f88571558..c686f02bed 100644 --- a/x/observer/keeper/ballot_test.go +++ b/x/observer/keeper/ballot_test.go @@ -5,6 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + "github.com/zeta-chain/node/x/observer/keeper" keepertest "github.com/zeta-chain/node/testutil/keeper" "github.com/zeta-chain/node/testutil/sample" @@ -54,25 +55,49 @@ func TestKeeper_GetBallot(t *testing.T) { } func TestKeeper_GetBallotList(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - identifier := sample.ZetaIndex(t) - b := &types.Ballot{ - Index: "", - BallotIdentifier: identifier, - VoterList: nil, - ObservationType: 0, - BallotThreshold: sdk.ZeroDec(), - BallotStatus: 0, - BallotCreationHeight: 1, - } - _, found := k.GetBallotList(ctx, 1) - require.False(t, found) + t.Run("get existing ballot list", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.ZeroDec(), + BallotStatus: 0, + BallotCreationHeight: 1, + } + _, found := k.GetBallotListForHeight(ctx, 1) + require.False(t, found) + + k.AddBallotToList(ctx, *b) + list, found := k.GetBallotListForHeight(ctx, 1) + require.True(t, found) + require.Equal(t, 1, len(list.BallotsIndexList)) + require.Equal(t, identifier, list.BallotsIndexList[0]) + }) + + t.Run("get non-existing ballot list", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + Index: "", + BallotIdentifier: identifier, + VoterList: nil, + ObservationType: 0, + BallotThreshold: sdk.ZeroDec(), + BallotStatus: 0, + BallotCreationHeight: 1, + } + _, found := k.GetBallotListForHeight(ctx, 1) + require.False(t, found) + + k.AddBallotToList(ctx, *b) + list, found := k.GetBallotListForHeight(ctx, -10) + require.False(t, found) + require.Nil(t, list.BallotsIndexList) + }) - k.AddBallotToList(ctx, *b) - list, found := k.GetBallotList(ctx, 1) - require.True(t, found) - require.Equal(t, 1, len(list.BallotsIndexList)) - require.Equal(t, identifier, list.BallotsIndexList[0]) } func TestKeeper_GetMaturedBallots(t *testing.T) { @@ -118,3 +143,322 @@ func TestKeeper_GetAllBallots(t *testing.T) { require.Equal(t, 1, len(ballots)) require.Equal(t, b, ballots[0]) } + +func TestKeeper_DeleteBallot(t *testing.T) { + t.Run("delete existing ballot", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := &types.Ballot{ + BallotIdentifier: identifier, + } + k.SetBallot(ctx, b) + _, found := k.GetBallot(ctx, identifier) + require.True(t, found) + + //Act + k.DeleteBallot(ctx, identifier) + + //Assert + _, found = k.GetBallot(ctx, identifier) + require.False(t, found) + }) + + t.Run("delete non-existing ballot,nothing happens", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + numberOfBallots := 10 + for i := 0; i < numberOfBallots; i++ { + k.SetBallot(ctx, &types.Ballot{ + BallotIdentifier: sample.ZetaIndex(t), + }) + } + + require.Len(t, k.GetAllBallots(ctx), numberOfBallots) + + //Act + k.DeleteBallot(ctx, identifier) + + //Assert + _, found := k.GetBallot(ctx, identifier) + require.False(t, found) + require.Len(t, k.GetAllBallots(ctx), numberOfBallots) + }) +} + +func TestKeeper_DeleteBallotList(t *testing.T) { + t.Run("delete existing ballot list", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + numberOfBallotLists := 10 + for i := 0; i < numberOfBallotLists; i++ { + k.AddBallotToList(ctx, types.Ballot{ + Index: sample.ZetaIndex(t), + BallotCreationHeight: 1, + }) + } + + _, found := k.GetBallotListForHeight(ctx, 1) + require.True(t, found) + + //Act + k.DeleteBallotListForHeight(ctx, 1) + + //Assert + _, found = k.GetBallotListForHeight(ctx, 1) + require.False(t, found) + }) + + t.Run("delete non-existing ballot list, nothing happens", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + numberOfBallotLists := 10 + for i := 0; i < numberOfBallotLists; i++ { + k.AddBallotToList(ctx, types.Ballot{ + Index: sample.ZetaIndex(t), + BallotCreationHeight: 1, + }) + } + + _, found := k.GetBallotListForHeight(ctx, 1) + require.True(t, found) + + //Act + k.DeleteBallotListForHeight(ctx, 2) + + //Assert + _, found = k.GetBallotListForHeight(ctx, 1) + require.True(t, found) + }) +} + +func TestKeeper_ClearMaturedBallots(t *testing.T) { + t.Run("clear matured ballots successfully", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + numberOfBallots := 10 + ballots := make([]types.Ballot, numberOfBallots) + for i := 0; i < numberOfBallots; i++ { + b := types.Ballot{ + BallotIdentifier: sample.ZetaIndex(t), + BallotCreationHeight: 1, + } + k.AddBallotToList(ctx, b) + k.SetBallot(ctx, &b) + ballots[i] = b + } + _, found := k.GetBallotListForHeight(ctx, 1) + require.True(t, found) + require.Equal(t, numberOfBallots, len(k.GetAllBallots(ctx))) + + //Act + k.ClearMaturedBallotsAndBallotList(ctx, 0) + + //Assert + for _, b := range ballots { + _, found = k.GetBallot(ctx, b.BallotIdentifier) + require.False(t, found) + } + _, found = k.GetBallotListForHeight(ctx, 0) + require.False(t, found) + }) + + t.Run("clear only ballotList if no ballots are found", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + numberOfBallots := 10 + ballots := make([]types.Ballot, numberOfBallots) + for i := 0; i < numberOfBallots; i++ { + b := types.Ballot{ + BallotIdentifier: sample.ZetaIndex(t), + BallotCreationHeight: 1, + } + k.AddBallotToList(ctx, b) + ballots[i] = b + } + _, found := k.GetBallotListForHeight(ctx, 1) + require.True(t, found) + require.Equal(t, 0, len(k.GetAllBallots(ctx))) + + //Act + k.ClearMaturedBallotsAndBallotList(ctx, 0) + + //Assert + _, found = k.GetBallotListForHeight(ctx, 1) + require.False(t, found) + require.Equal(t, 0, len(k.GetAllBallots(ctx))) + }) + + t.Run("do nothing if ballot list for height is not found", func(t *testing.T) { + // Note this condition should never happen in production as the ballot list for height should always be set when saving a ballot to state + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + numberOfBallots := 10 + ballots := make([]types.Ballot, numberOfBallots) + for i := 0; i < numberOfBallots; i++ { + b := types.Ballot{ + BallotIdentifier: sample.ZetaIndex(t), + BallotCreationHeight: 1, + } + k.SetBallot(ctx, &b) + ballots[i] = b + } + _, found := k.GetBallotListForHeight(ctx, 1) + require.False(t, found) + require.Equal(t, numberOfBallots, len(k.GetAllBallots(ctx))) + + //Act + k.ClearMaturedBallotsAndBallotList(ctx, 0) + + //Assert + for _, b := range ballots { + _, found = k.GetBallot(ctx, b.BallotIdentifier) + require.True(t, found) + } + }) + +} + +func TestGetMaturedBallotHeight(t *testing.T) { + tt := []struct { + name string + currentHeight int64 + maturityBlocks int64 + expectedHeight int64 + }{ + { + name: "maturity blocks is 0", + currentHeight: 10, + maturityBlocks: 0, + expectedHeight: 10, + }, + { + name: "maturity blocks is same as current height", + currentHeight: 10, + maturityBlocks: 10, + expectedHeight: 0, + }, + { + name: "maturity blocks is less than current height", + currentHeight: 10, + maturityBlocks: 5, + expectedHeight: 5, + }, + { + name: "maturity blocks is greater than current height", + currentHeight: 5, + maturityBlocks: 10, + expectedHeight: -5, + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + _, ctx, _, _ := keepertest.ObserverKeeper(t) + ctx = ctx.WithBlockHeight(tc.currentHeight) + require.Equal(t, tc.expectedHeight, keeper.GetMaturedBallotHeightFunc(ctx, tc.maturityBlocks)) + }) + } +} + +func TestLogBallotDeletion(t *testing.T) { + t.Run("log ballot deletion", func(t *testing.T) { + //Arrange + _, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := types.Ballot{ + BallotIdentifier: identifier, + ObservationType: types.ObservationType_InboundTx, + VoterList: []string{"voter1", "voter2"}, + Votes: []types.VoteType{types.VoteType_SuccessObservation, types.VoteType_SuccessObservation}, + } + + testLogger := sample.NewTestLogger() + ctx = ctx.WithLogger(testLogger) + + //Act + keeper.LogBallotDeletionFunc(ctx, b) + + //Assert + logOutput := testLogger.String() + require.Contains(t, logOutput, "ballotIdentifier: "+identifier) + require.Contains(t, logOutput, "Voter : voter1 | Vote : SuccessObservation") + require.Contains(t, logOutput, "Voter : voter2 | Vote : SuccessObservation") + require.Contains(t, logOutput, "ballotType: InboundTx") + }) + + t.Run("log error if voter list and votes list length mismatch", func(t *testing.T) { + //Arrange + _, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := types.Ballot{ + BallotIdentifier: identifier, + ObservationType: types.ObservationType_InboundTx, + VoterList: []string{"voter1", "voter2"}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + } + + testLogger := sample.NewTestLogger() + ctx = ctx.WithLogger(testLogger) + + //Act + keeper.LogBallotDeletionFunc(ctx, b) + + //Assert + logOutput := testLogger.String() + require.Contains(t, logOutput, "voter list and votes list length mismatch for deleted ballot "+identifier) + }) + + t.Run("does not panic if ballot identifier is empty", func(t *testing.T) { + //Arrange + _, ctx, _, _ := keepertest.ObserverKeeper(t) + b := types.Ballot{ + BallotIdentifier: "", + ObservationType: types.ObservationType_InboundTx, + VoterList: []string{"voter1", "voter2"}, + Votes: []types.VoteType{types.VoteType_SuccessObservation, types.VoteType_SuccessObservation}, + } + + testLogger := sample.NewTestLogger() + ctx = ctx.WithLogger(testLogger) + + //Act + require.NotPanics(t, func() { + keeper.LogBallotDeletionFunc(ctx, b) + }) + + //Assert + logOutput := testLogger.String() + require.Contains(t, logOutput, "ballotIdentifier: ") + require.Contains(t, logOutput, "Voter : voter1 | Vote : SuccessObservation") + require.Contains(t, logOutput, "Voter : voter2 | Vote : SuccessObservation") + require.Contains(t, logOutput, "ballotType: InboundTx") + }) + + t.Run("does not panic if observation type is empty", func(t *testing.T) { + //Arrange + _, ctx, _, _ := keepertest.ObserverKeeper(t) + identifier := sample.ZetaIndex(t) + b := types.Ballot{ + BallotIdentifier: identifier, + ObservationType: 0, + VoterList: []string{"voter1", "voter2"}, + Votes: []types.VoteType{types.VoteType_SuccessObservation, types.VoteType_SuccessObservation}, + } + + testLogger := sample.NewTestLogger() + ctx = ctx.WithLogger(testLogger) + + //Act + require.NotPanics(t, func() { + keeper.LogBallotDeletionFunc(ctx, b) + }) + + //Assert + logOutput := testLogger.String() + require.Contains(t, logOutput, "ballotIdentifier: "+identifier) + require.Contains(t, logOutput, "Voter : voter1 | Vote : SuccessObservation") + require.Contains(t, logOutput, "Voter : voter2 | Vote : SuccessObservation") + require.Contains(t, logOutput, "ballotType: ") + }) +} diff --git a/x/observer/keeper/export_private_functions_test.go b/x/observer/keeper/export_private_functions_test.go new file mode 100644 index 0000000000..0fa2c4780f --- /dev/null +++ b/x/observer/keeper/export_private_functions_test.go @@ -0,0 +1,6 @@ +package keeper + +// These functions are exported for testing purposes + +var GetMaturedBallotHeightFunc = getMaturedBallotHeight +var LogBallotDeletionFunc = logBallotDeletion diff --git a/x/observer/keeper/grpc_query_ballot.go b/x/observer/keeper/grpc_query_ballot.go index 75ffd6ff07..a3472317f8 100644 --- a/x/observer/keeper/grpc_query_ballot.go +++ b/x/observer/keeper/grpc_query_ballot.go @@ -3,7 +3,9 @@ package keeper import ( "context" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -57,3 +59,32 @@ func (k Keeper) BallotByIdentifier( BallotStatus: ballot.BallotStatus, }, nil } + +// Ballots queries all the ballots. It is a paginated query +func (k Keeper) Ballots(goCtx context.Context, req *types.QueryBallotsRequest) (*types.QueryBallotsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ballots := make([]types.Ballot, 0) + ctx := sdk.UnwrapSDKContext(goCtx) + + ballotStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.VoterKey)) + + if req.Pagination == nil { + req.Pagination = &query.PageRequest{} + } + + pageRes, err := query.Paginate(ballotStore, req.Pagination, func(_ []byte, value []byte) error { + var ballot types.Ballot + if err := k.cdc.Unmarshal(value, &ballot); err != nil { + return err + } + ballots = append(ballots, ballot) + return nil + }) + + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + return &types.QueryBallotsResponse{Ballots: ballots, Pagination: pageRes}, nil +} diff --git a/x/observer/keeper/grpc_query_ballot_test.go b/x/observer/keeper/grpc_query_ballot_test.go index fe34971a64..aa5d6f48b8 100644 --- a/x/observer/keeper/grpc_query_ballot_test.go +++ b/x/observer/keeper/grpc_query_ballot_test.go @@ -1,9 +1,11 @@ package keeper_test import ( + "fmt" "testing" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/node/testutil/keeper" @@ -134,4 +136,102 @@ func TestKeeper_BallotByIdentifier(t *testing.T) { BallotStatus: ballot.BallotStatus, }, res) }) + + t.Run("should return 100 ballots if more exist and limit is not provided", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + numOfBallots := 1000 + + ballots := make([]types.Ballot, numOfBallots) + for i := 0; i < numOfBallots; i++ { + ballot := types.Ballot{ + Index: "", + BallotIdentifier: fmt.Sprintf("index-%d", i), + VoterList: []string{sample.AccAddress()}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + BallotCreationHeight: 1, + BallotThreshold: sdk.MustNewDecFromStr("0.5"), + } + k.SetBallot(ctx, &ballot) + ballots[i] = ballot + } + + res, err := k.Ballots(wctx, &types.QueryBallotsRequest{}) + require.NoError(t, err) + require.Len(t, res.Ballots, 100) + }) + + t.Run("should return limit number of ballots if limit is provided", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + numOfBallots := 1000 + + ballots := make([]types.Ballot, numOfBallots) + for i := 0; i < numOfBallots; i++ { + ballot := types.Ballot{ + Index: "", + BallotIdentifier: fmt.Sprintf("index-%d", i), + VoterList: []string{sample.AccAddress()}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + BallotCreationHeight: 1, + BallotThreshold: sdk.MustNewDecFromStr("0.5"), + } + k.SetBallot(ctx, &ballot) + ballots[i] = ballot + } + + res, err := k.Ballots(wctx, &types.QueryBallotsRequest{ + Pagination: &query.PageRequest{ + Limit: 10, + }, + }) + require.NoError(t, err) + require.Len(t, res.Ballots, 10) + }) +} + +func TestKeeper_Ballots(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.Ballots(wctx, nil) + require.Nil(t, res) + require.Error(t, err) + }) + + t.Run("should return empty list if no ballots", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.Ballots(wctx, &types.QueryBallotsRequest{}) + require.NoError(t, err) + require.Empty(t, res.Ballots) + }) + + t.Run("should return all ballots", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + ballots := make([]types.Ballot, 10) + for i := 0; i < 10; i++ { + ballot := types.Ballot{ + Index: "", + BallotIdentifier: fmt.Sprintf("index-%d", i), + VoterList: []string{sample.AccAddress()}, + Votes: []types.VoteType{types.VoteType_SuccessObservation}, + BallotStatus: types.BallotStatus_BallotInProgress, + BallotCreationHeight: 1, + BallotThreshold: sdk.MustNewDecFromStr("0.5"), + } + k.SetBallot(ctx, &ballot) + ballots[i] = ballot + } + + res, err := k.Ballots(wctx, &types.QueryBallotsRequest{}) + require.NoError(t, err) + require.ElementsMatch(t, ballots, res.Ballots) + }) } diff --git a/x/observer/keeper/migrator.go b/x/observer/keeper/migrator.go index f6ee68c594..c98ccd9e0c 100644 --- a/x/observer/keeper/migrator.go +++ b/x/observer/keeper/migrator.go @@ -4,6 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" v8 "github.com/zeta-chain/node/x/observer/migrations/v8" + v9 "github.com/zeta-chain/node/x/observer/migrations/v9" ) // Migrator is a struct for handling in-place store migrations. @@ -49,3 +50,8 @@ func (m Migrator) Migrate6to7(_ sdk.Context) error { func (m Migrator) Migrate7to8(ctx sdk.Context) error { return v8.MigrateStore(ctx, m.observerKeeper) } + +// Migrate8to9 migrates the store from consensus version 8 to 9 +func (m Migrator) Migrate8to9(ctx sdk.Context) error { + return v9.MigrateStore(ctx, m.observerKeeper) +} diff --git a/x/observer/migrations/v9/migrate.go b/x/observer/migrations/v9/migrate.go new file mode 100644 index 0000000000..c936c7feee --- /dev/null +++ b/x/observer/migrations/v9/migrate.go @@ -0,0 +1,38 @@ +package v9 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/zeta-chain/node/x/observer/types" +) + +type observerKeeper interface { + GetBallotListForHeight(ctx sdk.Context, height int64) (val types.BallotListForHeight, found bool) + DeleteBallot(ctx sdk.Context, index string) + DeleteBallotListForHeight(ctx sdk.Context, height int64) +} + +const MaturityBlocks = int64(100) + +// MigrateStore migrates the x/observer module state from the consensus version 8 to version 9. +// The migration deletes all the ballots and ballot lists that are older than MaturityBlocks. +func MigrateStore(ctx sdk.Context, observerKeeper observerKeeper) error { + currentHeight := ctx.BlockHeight() + // Maturity blocks is a parameter in the emissions module + if currentHeight < MaturityBlocks { + return nil + } + maturedHeight := currentHeight - MaturityBlocks + for i := maturedHeight; i > 0; i-- { + ballotList, found := observerKeeper.GetBallotListForHeight(ctx, i) + if !found { + continue + } + for _, ballotIndex := range ballotList.BallotsIndexList { + observerKeeper.DeleteBallot(ctx, ballotIndex) + } + observerKeeper.DeleteBallotListForHeight(ctx, i) + } + + return nil +} diff --git a/x/observer/migrations/v9/migrate_test.go b/x/observer/migrations/v9/migrate_test.go new file mode 100644 index 0000000000..e584bb9dc9 --- /dev/null +++ b/x/observer/migrations/v9/migrate_test.go @@ -0,0 +1,147 @@ +package v9_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + keepertest "github.com/zeta-chain/node/testutil/keeper" + "github.com/zeta-chain/node/testutil/sample" + v9 "github.com/zeta-chain/node/x/observer/migrations/v9" + "github.com/zeta-chain/node/x/observer/types" +) + +func TestMigrateStore(t *testing.T) { + t.Run("delete all matured ballots", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + // Set current height to 1000 + currentHeight := int64(1000) + // 100 is the maturity blocks parameter defined in emissions module and used by the migrator script + lastMaturedHeight := currentHeight - v9.MaturityBlocks + // The first block height is 1 for zeta chain + firstBlockHeight := int64(1) + // Account for the first block height to be 1 + numberOfActualBlocks := currentHeight - firstBlockHeight + blocksWithUnMaturedBallots := numberOfActualBlocks - lastMaturedHeight + // Use this constant to add ballot to each block + numberOfBallotsPerBlock := int64(10) + + ctx = ctx.WithBlockHeight(currentHeight) + + for i := firstBlockHeight; i < currentHeight; i++ { + for j := int64(0); j < numberOfBallotsPerBlock; j++ { + b := types.Ballot{ + BallotIdentifier: sample.ZetaIndex(t), + BallotCreationHeight: i, + } + k.AddBallotToList(ctx, b) + k.SetBallot(ctx, &b) + } + } + + allBallots := k.GetAllBallots(ctx) + require.Equal(t, numberOfActualBlocks*numberOfBallotsPerBlock, int64(len(allBallots))) + + //Act + err := v9.MigrateStore(ctx, k) + require.NoError(t, err) + + //Assert + // We have 10 ballots per block for the last 999 blocks. + // However, since the maturity blocks are 100, the last 99 blocks will have unmatured ballots. + // 99*10 = 990 + remainingBallotsAfterMigration := k.GetAllBallots(ctx) + require.Equal(t, blocksWithUnMaturedBallots*numberOfBallotsPerBlock, int64(len(remainingBallotsAfterMigration))) + require.Equal(t, int64(990), int64(len(remainingBallotsAfterMigration))) + + // remaining ballots should have creation height greater than last matured height + for _, b := range remainingBallotsAfterMigration { + require.Greater(t, b.BallotCreationHeight, lastMaturedHeight) + } + + // all ballots lists before last matured height should be deleted + for i := firstBlockHeight; i < lastMaturedHeight; i++ { + _, found := k.GetBallotListForHeight(ctx, i) + require.False(t, found) + } + + // all ballots lists after last matured height should be present + for i := lastMaturedHeight + 1; i < currentHeight; i++ { + _, found := k.GetBallotListForHeight(ctx, i) + require.True(t, found) + } + }) + + t.Run("do nothing if ballot list for height is not found", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + // Set current height to 1000 + currentHeight := int64(1000) + // The first block height is 1 for zeta chain + firstBlockHeight := int64(1) + // Account for the first block height to be 1 + numberOfActualBlocks := currentHeight - firstBlockHeight + // Use this constant to add ballot to each block + numberOfBallotsPerBlock := int64(10) + + ctx = ctx.WithBlockHeight(currentHeight) + + for i := firstBlockHeight; i < currentHeight; i++ { + for j := int64(0); j < numberOfBallotsPerBlock; j++ { + b := types.Ballot{ + BallotIdentifier: sample.ZetaIndex(t), + BallotCreationHeight: i, + } + k.SetBallot(ctx, &b) + } + } + + allBallots := k.GetAllBallots(ctx) + require.Equal(t, numberOfActualBlocks*numberOfBallotsPerBlock, int64(len(allBallots))) + + //Act + err := v9.MigrateStore(ctx, k) + require.NoError(t, err) + + //Assert + allBallotsAfterMigration := k.GetAllBallots(ctx) + require.Equal(t, numberOfActualBlocks*numberOfBallotsPerBlock, int64(len(allBallotsAfterMigration))) + }) + + t.Run("do nothing if current height is less than maturity blocks", func(t *testing.T) { + //Arrange + k, ctx, _, _ := keepertest.ObserverKeeper(t) + // Set current height to 100 + currentHeight := int64(10) + // The first block height is 1 for zeta chain + firstBlockHeight := int64(1) + // Account for the first block height to be 1 + numberOfActualBlocks := currentHeight - firstBlockHeight + // Use this constant to add ballot to each block + numberOfBallotsPerBlock := int64(10) + + ctx = ctx.WithBlockHeight(currentHeight) + + for i := firstBlockHeight; i < currentHeight; i++ { + for j := int64(0); j < numberOfBallotsPerBlock; j++ { + b := types.Ballot{ + BallotIdentifier: sample.ZetaIndex(t), + BallotCreationHeight: i, + } + k.AddBallotToList(ctx, b) + k.SetBallot(ctx, &b) + } + } + + allBallots := k.GetAllBallots(ctx) + require.Equal(t, numberOfActualBlocks*numberOfBallotsPerBlock, int64(len(allBallots))) + + //Act + err := v9.MigrateStore(ctx, k) + require.NoError(t, err) + + //Assert + allBallotsAfterMigration := k.GetAllBallots(ctx) + require.Equal(t, numberOfActualBlocks*numberOfBallotsPerBlock, int64(len(allBallotsAfterMigration))) + }) +} diff --git a/x/observer/module.go b/x/observer/module.go index 1136be6ecd..b9d17995b4 100644 --- a/x/observer/module.go +++ b/x/observer/module.go @@ -145,6 +145,9 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err := cfg.RegisterMigration(types.ModuleName, 7, m.Migrate7to8); err != nil { panic(err) } + if err := cfg.RegisterMigration(types.ModuleName, 8, m.Migrate8to9); err != nil { + panic(err) + } } // RegisterInvariants registers the observer module's invariants. @@ -169,7 +172,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 8 } +func (AppModule) ConsensusVersion() uint64 { return 9 } // BeginBlock executes all ABCI BeginBlock logic respective to the observer module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { diff --git a/x/observer/types/ballot_test.go b/x/observer/types/ballot_test.go index 3f428e99d4..7c5b40a043 100644 --- a/x/observer/types/ballot_test.go +++ b/x/observer/types/ballot_test.go @@ -477,5 +477,4 @@ func Test_BuildRewardsDistribution(t *testing.T) { require.Equal(t, test.expectedMap, rewardsMap) }) } - } diff --git a/x/observer/types/errors.go b/x/observer/types/errors.go index edfd3040a1..73e2e65510 100644 --- a/x/observer/types/errors.go +++ b/x/observer/types/errors.go @@ -53,4 +53,5 @@ var ( ErrObserverNotFound = errorsmod.Register(ModuleName, 1136, "observer not found") ErrInvalidObserverAddress = errorsmod.Register(ModuleName, 1137, "invalid observer address") ErrOperationalFlagsRestartHeightNegative = errorsmod.Register(ModuleName, 1138, "restart height cannot be negative") + ErrInvalidVoterList = errorsmod.Register(ModuleName, 1139, "invalid voter list for ballot") ) diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index d9d7fe4397..3e87433547 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -32,6 +32,102 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type QueryBallotsRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryBallotsRequest) Reset() { *m = QueryBallotsRequest{} } +func (m *QueryBallotsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryBallotsRequest) ProtoMessage() {} +func (*QueryBallotsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_25b2aa420449a0c0, []int{0} +} +func (m *QueryBallotsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryBallotsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryBallotsRequest.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 *QueryBallotsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryBallotsRequest.Merge(m, src) +} +func (m *QueryBallotsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryBallotsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryBallotsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryBallotsRequest proto.InternalMessageInfo + +func (m *QueryBallotsRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +type QueryBallotsResponse struct { + Ballots []Ballot `protobuf:"bytes,1,rep,name=ballots,proto3" json:"ballots"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryBallotsResponse) Reset() { *m = QueryBallotsResponse{} } +func (m *QueryBallotsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryBallotsResponse) ProtoMessage() {} +func (*QueryBallotsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_25b2aa420449a0c0, []int{1} +} +func (m *QueryBallotsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryBallotsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryBallotsResponse.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 *QueryBallotsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryBallotsResponse.Merge(m, src) +} +func (m *QueryBallotsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryBallotsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryBallotsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryBallotsResponse proto.InternalMessageInfo + +func (m *QueryBallotsResponse) GetBallots() []Ballot { + if m != nil { + return m.Ballots + } + return nil +} + +func (m *QueryBallotsResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + type QueryOperationalFlagsRequest struct { } @@ -39,7 +135,7 @@ func (m *QueryOperationalFlagsRequest) Reset() { *m = QueryOperationalFl func (m *QueryOperationalFlagsRequest) String() string { return proto.CompactTextString(m) } func (*QueryOperationalFlagsRequest) ProtoMessage() {} func (*QueryOperationalFlagsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{0} + return fileDescriptor_25b2aa420449a0c0, []int{2} } func (m *QueryOperationalFlagsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -76,7 +172,7 @@ func (m *QueryOperationalFlagsResponse) Reset() { *m = QueryOperationalF func (m *QueryOperationalFlagsResponse) String() string { return proto.CompactTextString(m) } func (*QueryOperationalFlagsResponse) ProtoMessage() {} func (*QueryOperationalFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{1} + return fileDescriptor_25b2aa420449a0c0, []int{3} } func (m *QueryOperationalFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -119,7 +215,7 @@ func (m *QueryTssFundsMigratorInfoAllRequest) Reset() { *m = QueryTssFun func (m *QueryTssFundsMigratorInfoAllRequest) String() string { return proto.CompactTextString(m) } func (*QueryTssFundsMigratorInfoAllRequest) ProtoMessage() {} func (*QueryTssFundsMigratorInfoAllRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{2} + return fileDescriptor_25b2aa420449a0c0, []int{4} } func (m *QueryTssFundsMigratorInfoAllRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -156,7 +252,7 @@ func (m *QueryTssFundsMigratorInfoAllResponse) Reset() { *m = QueryTssFu func (m *QueryTssFundsMigratorInfoAllResponse) String() string { return proto.CompactTextString(m) } func (*QueryTssFundsMigratorInfoAllResponse) ProtoMessage() {} func (*QueryTssFundsMigratorInfoAllResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{3} + return fileDescriptor_25b2aa420449a0c0, []int{5} } func (m *QueryTssFundsMigratorInfoAllResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -200,7 +296,7 @@ func (m *QueryTssFundsMigratorInfoRequest) Reset() { *m = QueryTssFundsM func (m *QueryTssFundsMigratorInfoRequest) String() string { return proto.CompactTextString(m) } func (*QueryTssFundsMigratorInfoRequest) ProtoMessage() {} func (*QueryTssFundsMigratorInfoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{4} + return fileDescriptor_25b2aa420449a0c0, []int{6} } func (m *QueryTssFundsMigratorInfoRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -244,7 +340,7 @@ func (m *QueryTssFundsMigratorInfoResponse) Reset() { *m = QueryTssFunds func (m *QueryTssFundsMigratorInfoResponse) String() string { return proto.CompactTextString(m) } func (*QueryTssFundsMigratorInfoResponse) ProtoMessage() {} func (*QueryTssFundsMigratorInfoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{5} + return fileDescriptor_25b2aa420449a0c0, []int{7} } func (m *QueryTssFundsMigratorInfoResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -288,7 +384,7 @@ func (m *QueryGetChainNoncesRequest) Reset() { *m = QueryGetChainNoncesR func (m *QueryGetChainNoncesRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetChainNoncesRequest) ProtoMessage() {} func (*QueryGetChainNoncesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{6} + return fileDescriptor_25b2aa420449a0c0, []int{8} } func (m *QueryGetChainNoncesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -332,7 +428,7 @@ func (m *QueryGetChainNoncesResponse) Reset() { *m = QueryGetChainNonces func (m *QueryGetChainNoncesResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetChainNoncesResponse) ProtoMessage() {} func (*QueryGetChainNoncesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{7} + return fileDescriptor_25b2aa420449a0c0, []int{9} } func (m *QueryGetChainNoncesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -376,7 +472,7 @@ func (m *QueryAllChainNoncesRequest) Reset() { *m = QueryAllChainNoncesR func (m *QueryAllChainNoncesRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllChainNoncesRequest) ProtoMessage() {} func (*QueryAllChainNoncesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{8} + return fileDescriptor_25b2aa420449a0c0, []int{10} } func (m *QueryAllChainNoncesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -421,7 +517,7 @@ func (m *QueryAllChainNoncesResponse) Reset() { *m = QueryAllChainNonces func (m *QueryAllChainNoncesResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllChainNoncesResponse) ProtoMessage() {} func (*QueryAllChainNoncesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{9} + return fileDescriptor_25b2aa420449a0c0, []int{11} } func (m *QueryAllChainNoncesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -472,7 +568,7 @@ func (m *QueryAllPendingNoncesRequest) Reset() { *m = QueryAllPendingNon func (m *QueryAllPendingNoncesRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllPendingNoncesRequest) ProtoMessage() {} func (*QueryAllPendingNoncesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{10} + return fileDescriptor_25b2aa420449a0c0, []int{12} } func (m *QueryAllPendingNoncesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -517,7 +613,7 @@ func (m *QueryAllPendingNoncesResponse) Reset() { *m = QueryAllPendingNo func (m *QueryAllPendingNoncesResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllPendingNoncesResponse) ProtoMessage() {} func (*QueryAllPendingNoncesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{11} + return fileDescriptor_25b2aa420449a0c0, []int{13} } func (m *QueryAllPendingNoncesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -568,7 +664,7 @@ func (m *QueryPendingNoncesByChainRequest) Reset() { *m = QueryPendingNo func (m *QueryPendingNoncesByChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryPendingNoncesByChainRequest) ProtoMessage() {} func (*QueryPendingNoncesByChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{12} + return fileDescriptor_25b2aa420449a0c0, []int{14} } func (m *QueryPendingNoncesByChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -612,7 +708,7 @@ func (m *QueryPendingNoncesByChainResponse) Reset() { *m = QueryPendingN func (m *QueryPendingNoncesByChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryPendingNoncesByChainResponse) ProtoMessage() {} func (*QueryPendingNoncesByChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{13} + return fileDescriptor_25b2aa420449a0c0, []int{15} } func (m *QueryPendingNoncesByChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -655,7 +751,7 @@ func (m *QueryGetTSSRequest) Reset() { *m = QueryGetTSSRequest{} } func (m *QueryGetTSSRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetTSSRequest) ProtoMessage() {} func (*QueryGetTSSRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{14} + return fileDescriptor_25b2aa420449a0c0, []int{16} } func (m *QueryGetTSSRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -692,7 +788,7 @@ func (m *QueryGetTSSResponse) Reset() { *m = QueryGetTSSResponse{} } func (m *QueryGetTSSResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetTSSResponse) ProtoMessage() {} func (*QueryGetTSSResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{15} + return fileDescriptor_25b2aa420449a0c0, []int{17} } func (m *QueryGetTSSResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -736,7 +832,7 @@ func (m *QueryGetTssAddressRequest) Reset() { *m = QueryGetTssAddressReq func (m *QueryGetTssAddressRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetTssAddressRequest) ProtoMessage() {} func (*QueryGetTssAddressRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{16} + return fileDescriptor_25b2aa420449a0c0, []int{18} } func (m *QueryGetTssAddressRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -781,7 +877,7 @@ func (m *QueryGetTssAddressResponse) Reset() { *m = QueryGetTssAddressRe func (m *QueryGetTssAddressResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetTssAddressResponse) ProtoMessage() {} func (*QueryGetTssAddressResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{17} + return fileDescriptor_25b2aa420449a0c0, []int{19} } func (m *QueryGetTssAddressResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -837,7 +933,7 @@ func (m *QueryGetTssAddressByFinalizedHeightRequest) String() string { } func (*QueryGetTssAddressByFinalizedHeightRequest) ProtoMessage() {} func (*QueryGetTssAddressByFinalizedHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{18} + return fileDescriptor_25b2aa420449a0c0, []int{20} } func (m *QueryGetTssAddressByFinalizedHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -893,7 +989,7 @@ func (m *QueryGetTssAddressByFinalizedHeightResponse) String() string { } func (*QueryGetTssAddressByFinalizedHeightResponse) ProtoMessage() {} func (*QueryGetTssAddressByFinalizedHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{19} + return fileDescriptor_25b2aa420449a0c0, []int{21} } func (m *QueryGetTssAddressByFinalizedHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -944,7 +1040,7 @@ func (m *QueryTssHistoryRequest) Reset() { *m = QueryTssHistoryRequest{} func (m *QueryTssHistoryRequest) String() string { return proto.CompactTextString(m) } func (*QueryTssHistoryRequest) ProtoMessage() {} func (*QueryTssHistoryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{20} + return fileDescriptor_25b2aa420449a0c0, []int{22} } func (m *QueryTssHistoryRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -989,7 +1085,7 @@ func (m *QueryTssHistoryResponse) Reset() { *m = QueryTssHistoryResponse func (m *QueryTssHistoryResponse) String() string { return proto.CompactTextString(m) } func (*QueryTssHistoryResponse) ProtoMessage() {} func (*QueryTssHistoryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{21} + return fileDescriptor_25b2aa420449a0c0, []int{23} } func (m *QueryTssHistoryResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1041,7 +1137,7 @@ func (m *QueryHasVotedRequest) Reset() { *m = QueryHasVotedRequest{} } func (m *QueryHasVotedRequest) String() string { return proto.CompactTextString(m) } func (*QueryHasVotedRequest) ProtoMessage() {} func (*QueryHasVotedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{22} + return fileDescriptor_25b2aa420449a0c0, []int{24} } func (m *QueryHasVotedRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1092,7 +1188,7 @@ func (m *QueryHasVotedResponse) Reset() { *m = QueryHasVotedResponse{} } func (m *QueryHasVotedResponse) String() string { return proto.CompactTextString(m) } func (*QueryHasVotedResponse) ProtoMessage() {} func (*QueryHasVotedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{23} + return fileDescriptor_25b2aa420449a0c0, []int{25} } func (m *QueryHasVotedResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1136,7 +1232,7 @@ func (m *QueryBallotByIdentifierRequest) Reset() { *m = QueryBallotByIde func (m *QueryBallotByIdentifierRequest) String() string { return proto.CompactTextString(m) } func (*QueryBallotByIdentifierRequest) ProtoMessage() {} func (*QueryBallotByIdentifierRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{24} + return fileDescriptor_25b2aa420449a0c0, []int{26} } func (m *QueryBallotByIdentifierRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1181,7 +1277,7 @@ func (m *VoterList) Reset() { *m = VoterList{} } func (m *VoterList) String() string { return proto.CompactTextString(m) } func (*VoterList) ProtoMessage() {} func (*VoterList) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{25} + return fileDescriptor_25b2aa420449a0c0, []int{27} } func (m *VoterList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1235,7 +1331,7 @@ func (m *QueryBallotByIdentifierResponse) Reset() { *m = QueryBallotById func (m *QueryBallotByIdentifierResponse) String() string { return proto.CompactTextString(m) } func (*QueryBallotByIdentifierResponse) ProtoMessage() {} func (*QueryBallotByIdentifierResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{26} + return fileDescriptor_25b2aa420449a0c0, []int{28} } func (m *QueryBallotByIdentifierResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1299,7 +1395,7 @@ func (m *QueryObserverSet) Reset() { *m = QueryObserverSet{} } func (m *QueryObserverSet) String() string { return proto.CompactTextString(m) } func (*QueryObserverSet) ProtoMessage() {} func (*QueryObserverSet) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{27} + return fileDescriptor_25b2aa420449a0c0, []int{29} } func (m *QueryObserverSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1336,7 +1432,7 @@ func (m *QueryObserverSetResponse) Reset() { *m = QueryObserverSetRespon func (m *QueryObserverSetResponse) String() string { return proto.CompactTextString(m) } func (*QueryObserverSetResponse) ProtoMessage() {} func (*QueryObserverSetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{28} + return fileDescriptor_25b2aa420449a0c0, []int{30} } func (m *QueryObserverSetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1379,7 +1475,7 @@ func (m *QuerySupportedChains) Reset() { *m = QuerySupportedChains{} } func (m *QuerySupportedChains) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChains) ProtoMessage() {} func (*QuerySupportedChains) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{29} + return fileDescriptor_25b2aa420449a0c0, []int{31} } func (m *QuerySupportedChains) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1416,7 +1512,7 @@ func (m *QuerySupportedChainsResponse) Reset() { *m = QuerySupportedChai func (m *QuerySupportedChainsResponse) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChainsResponse) ProtoMessage() {} func (*QuerySupportedChainsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{30} + return fileDescriptor_25b2aa420449a0c0, []int{32} } func (m *QuerySupportedChainsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1460,7 +1556,7 @@ func (m *QueryGetChainParamsForChainRequest) Reset() { *m = QueryGetChai func (m *QueryGetChainParamsForChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsForChainRequest) ProtoMessage() {} func (*QueryGetChainParamsForChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{31} + return fileDescriptor_25b2aa420449a0c0, []int{33} } func (m *QueryGetChainParamsForChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1504,7 +1600,7 @@ func (m *QueryGetChainParamsForChainResponse) Reset() { *m = QueryGetCha func (m *QueryGetChainParamsForChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsForChainResponse) ProtoMessage() {} func (*QueryGetChainParamsForChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{32} + return fileDescriptor_25b2aa420449a0c0, []int{34} } func (m *QueryGetChainParamsForChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1547,7 +1643,7 @@ func (m *QueryGetChainParamsRequest) Reset() { *m = QueryGetChainParamsR func (m *QueryGetChainParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsRequest) ProtoMessage() {} func (*QueryGetChainParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{33} + return fileDescriptor_25b2aa420449a0c0, []int{35} } func (m *QueryGetChainParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1584,7 +1680,7 @@ func (m *QueryGetChainParamsResponse) Reset() { *m = QueryGetChainParams func (m *QueryGetChainParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsResponse) ProtoMessage() {} func (*QueryGetChainParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{34} + return fileDescriptor_25b2aa420449a0c0, []int{36} } func (m *QueryGetChainParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1628,7 +1724,7 @@ func (m *QueryGetNodeAccountRequest) Reset() { *m = QueryGetNodeAccountR func (m *QueryGetNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountRequest) ProtoMessage() {} func (*QueryGetNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{35} + return fileDescriptor_25b2aa420449a0c0, []int{37} } func (m *QueryGetNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1672,7 +1768,7 @@ func (m *QueryGetNodeAccountResponse) Reset() { *m = QueryGetNodeAccount func (m *QueryGetNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountResponse) ProtoMessage() {} func (*QueryGetNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{36} + return fileDescriptor_25b2aa420449a0c0, []int{38} } func (m *QueryGetNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1716,7 +1812,7 @@ func (m *QueryAllNodeAccountRequest) Reset() { *m = QueryAllNodeAccountR func (m *QueryAllNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountRequest) ProtoMessage() {} func (*QueryAllNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{37} + return fileDescriptor_25b2aa420449a0c0, []int{39} } func (m *QueryAllNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1761,7 +1857,7 @@ func (m *QueryAllNodeAccountResponse) Reset() { *m = QueryAllNodeAccount func (m *QueryAllNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountResponse) ProtoMessage() {} func (*QueryAllNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{38} + return fileDescriptor_25b2aa420449a0c0, []int{40} } func (m *QueryAllNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1811,7 +1907,7 @@ func (m *QueryGetCrosschainFlagsRequest) Reset() { *m = QueryGetCrosscha func (m *QueryGetCrosschainFlagsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCrosschainFlagsRequest) ProtoMessage() {} func (*QueryGetCrosschainFlagsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{39} + return fileDescriptor_25b2aa420449a0c0, []int{41} } func (m *QueryGetCrosschainFlagsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1848,7 +1944,7 @@ func (m *QueryGetCrosschainFlagsResponse) Reset() { *m = QueryGetCrossch func (m *QueryGetCrosschainFlagsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCrosschainFlagsResponse) ProtoMessage() {} func (*QueryGetCrosschainFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{40} + return fileDescriptor_25b2aa420449a0c0, []int{42} } func (m *QueryGetCrosschainFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1891,7 +1987,7 @@ func (m *QueryGetKeygenRequest) Reset() { *m = QueryGetKeygenRequest{} } func (m *QueryGetKeygenRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenRequest) ProtoMessage() {} func (*QueryGetKeygenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{41} + return fileDescriptor_25b2aa420449a0c0, []int{43} } func (m *QueryGetKeygenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1928,7 +2024,7 @@ func (m *QueryGetKeygenResponse) Reset() { *m = QueryGetKeygenResponse{} func (m *QueryGetKeygenResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenResponse) ProtoMessage() {} func (*QueryGetKeygenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{42} + return fileDescriptor_25b2aa420449a0c0, []int{44} } func (m *QueryGetKeygenResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1971,7 +2067,7 @@ func (m *QueryShowObserverCountRequest) Reset() { *m = QueryShowObserver func (m *QueryShowObserverCountRequest) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountRequest) ProtoMessage() {} func (*QueryShowObserverCountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{43} + return fileDescriptor_25b2aa420449a0c0, []int{45} } func (m *QueryShowObserverCountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2008,7 +2104,7 @@ func (m *QueryShowObserverCountResponse) Reset() { *m = QueryShowObserve func (m *QueryShowObserverCountResponse) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountResponse) ProtoMessage() {} func (*QueryShowObserverCountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{44} + return fileDescriptor_25b2aa420449a0c0, []int{46} } func (m *QueryShowObserverCountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2052,7 +2148,7 @@ func (m *QueryBlameByIdentifierRequest) Reset() { *m = QueryBlameByIdent func (m *QueryBlameByIdentifierRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierRequest) ProtoMessage() {} func (*QueryBlameByIdentifierRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{45} + return fileDescriptor_25b2aa420449a0c0, []int{47} } func (m *QueryBlameByIdentifierRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2096,7 +2192,7 @@ func (m *QueryBlameByIdentifierResponse) Reset() { *m = QueryBlameByIden func (m *QueryBlameByIdentifierResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierResponse) ProtoMessage() {} func (*QueryBlameByIdentifierResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{46} + return fileDescriptor_25b2aa420449a0c0, []int{48} } func (m *QueryBlameByIdentifierResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2140,7 +2236,7 @@ func (m *QueryAllBlameRecordsRequest) Reset() { *m = QueryAllBlameRecord func (m *QueryAllBlameRecordsRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsRequest) ProtoMessage() {} func (*QueryAllBlameRecordsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{47} + return fileDescriptor_25b2aa420449a0c0, []int{49} } func (m *QueryAllBlameRecordsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2185,7 +2281,7 @@ func (m *QueryAllBlameRecordsResponse) Reset() { *m = QueryAllBlameRecor func (m *QueryAllBlameRecordsResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsResponse) ProtoMessage() {} func (*QueryAllBlameRecordsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{48} + return fileDescriptor_25b2aa420449a0c0, []int{50} } func (m *QueryAllBlameRecordsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2237,7 +2333,7 @@ func (m *QueryBlameByChainAndNonceRequest) Reset() { *m = QueryBlameByCh func (m *QueryBlameByChainAndNonceRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlameByChainAndNonceRequest) ProtoMessage() {} func (*QueryBlameByChainAndNonceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{49} + return fileDescriptor_25b2aa420449a0c0, []int{51} } func (m *QueryBlameByChainAndNonceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2288,7 +2384,7 @@ func (m *QueryBlameByChainAndNonceResponse) Reset() { *m = QueryBlameByC func (m *QueryBlameByChainAndNonceResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlameByChainAndNonceResponse) ProtoMessage() {} func (*QueryBlameByChainAndNonceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{50} + return fileDescriptor_25b2aa420449a0c0, []int{52} } func (m *QueryBlameByChainAndNonceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2325,6 +2421,8 @@ func (m *QueryBlameByChainAndNonceResponse) GetBlameInfo() []*Blame { } func init() { + proto.RegisterType((*QueryBallotsRequest)(nil), "zetachain.zetacore.observer.QueryBallotsRequest") + proto.RegisterType((*QueryBallotsResponse)(nil), "zetachain.zetacore.observer.QueryBallotsResponse") proto.RegisterType((*QueryOperationalFlagsRequest)(nil), "zetachain.zetacore.observer.QueryOperationalFlagsRequest") proto.RegisterType((*QueryOperationalFlagsResponse)(nil), "zetachain.zetacore.observer.QueryOperationalFlagsResponse") proto.RegisterType((*QueryTssFundsMigratorInfoAllRequest)(nil), "zetachain.zetacore.observer.QueryTssFundsMigratorInfoAllRequest") @@ -2383,156 +2481,160 @@ func init() { } var fileDescriptor_25b2aa420449a0c0 = []byte{ - // 2374 bytes of a gzipped FileDescriptorProto + // 2442 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcf, 0x6f, 0x1b, 0xc7, - 0xf5, 0xf7, 0x5a, 0x89, 0x22, 0x8d, 0x6c, 0x89, 0x1a, 0xcb, 0x3f, 0x42, 0x3b, 0xb4, 0xbc, 0xb2, - 0x62, 0x59, 0x96, 0xb8, 0x36, 0xed, 0x7c, 0xfd, 0x2b, 0x8e, 0x4d, 0xfa, 0x6b, 0x49, 0x76, 0x12, - 0xdb, 0x21, 0xdd, 0x06, 0x30, 0xda, 0x32, 0x4b, 0x72, 0x48, 0x6e, 0xbd, 0xda, 0x61, 0x76, 0x46, - 0x4e, 0x18, 0x55, 0x40, 0xdb, 0x5b, 0x73, 0x28, 0x0a, 0x14, 0x68, 0x6f, 0x45, 0x2f, 0x3d, 0x16, - 0x28, 0x02, 0x04, 0x0d, 0x50, 0xf4, 0x90, 0x53, 0x73, 0xe8, 0x21, 0x45, 0x8b, 0xa2, 0xa7, 0x34, - 0xb0, 0xfb, 0x87, 0x14, 0x3b, 0xf3, 0x96, 0xdc, 0x5d, 0xee, 0x2e, 0x87, 0xb2, 0x7a, 0x22, 0x77, - 0x76, 0xde, 0x9b, 0xcf, 0xe7, 0xcd, 0xcc, 0x9b, 0xcf, 0xcc, 0x2c, 0x3a, 0xf3, 0x09, 0xe1, 0x66, - 0xbd, 0x6d, 0x5a, 0x8e, 0x21, 0xfe, 0x51, 0x97, 0x18, 0xb4, 0xc6, 0x88, 0xfb, 0x94, 0xb8, 0xc6, - 0x87, 0x5b, 0xc4, 0xed, 0xe6, 0x3b, 0x2e, 0xe5, 0x14, 0x1f, 0xef, 0x55, 0xcc, 0xfb, 0x15, 0xf3, - 0x7e, 0xc5, 0xec, 0x72, 0x9d, 0xb2, 0x4d, 0xca, 0x8c, 0x9a, 0xc9, 0x88, 0xb4, 0x32, 0x9e, 0x5e, - 0xa8, 0x11, 0x6e, 0x5e, 0x30, 0x3a, 0x66, 0xcb, 0x72, 0x4c, 0x6e, 0x51, 0x47, 0x3a, 0xca, 0xce, - 0xb5, 0x68, 0x8b, 0x8a, 0xbf, 0x86, 0xf7, 0x0f, 0x4a, 0x4f, 0xb4, 0x28, 0x6d, 0xd9, 0xc4, 0x30, - 0x3b, 0x96, 0x61, 0x3a, 0x0e, 0xe5, 0xc2, 0x84, 0xc1, 0xdb, 0xa5, 0x34, 0x94, 0x35, 0xd3, 0xb6, - 0x29, 0x87, 0x9a, 0xa9, 0x7c, 0x6a, 0xb6, 0xb9, 0x49, 0xa0, 0x62, 0x3e, 0xad, 0xa2, 0x28, 0xaf, - 0x3a, 0xd4, 0xa9, 0x13, 0x1f, 0x42, 0x21, 0xb5, 0xbe, 0x4b, 0x19, 0x93, 0x46, 0x4d, 0xdb, 0x6c, - 0x29, 0xc1, 0x7e, 0x42, 0xba, 0x2d, 0xe2, 0xa8, 0xa0, 0x71, 0x68, 0x83, 0x54, 0xcd, 0x7a, 0x9d, - 0x6e, 0x39, 0x3e, 0xcd, 0xe5, 0xb4, 0xfa, 0xfe, 0x1f, 0x15, 0x14, 0x1d, 0xd3, 0x35, 0x37, 0x7d, - 0xbc, 0xe7, 0x53, 0x6b, 0x12, 0xa7, 0x61, 0x39, 0xad, 0x70, 0x54, 0x16, 0xd3, 0x2c, 0x38, 0xf3, - 0xab, 0xad, 0xa6, 0xc2, 0xed, 0x10, 0x57, 0xf4, 0xb6, 0x69, 0xa7, 0xb0, 0xeb, 0x3c, 0x69, 0xc9, - 0x6e, 0x61, 0xf0, 0x33, 0xa4, 0x6e, 0xc7, 0xa5, 0xb4, 0xc9, 0xe0, 0x07, 0xea, 0x5e, 0x1a, 0x82, - 0xb6, 0xda, 0xdc, 0x72, 0x1a, 0xac, 0xba, 0x69, 0xb5, 0x5c, 0x93, 0x53, 0x88, 0x9f, 0x9e, 0x43, - 0x27, 0xde, 0xf3, 0x86, 0xf4, 0x83, 0x3e, 0xce, 0x35, 0xaf, 0x93, 0xcb, 0xe4, 0xc3, 0x2d, 0xc2, - 0xb8, 0xfe, 0x13, 0x0d, 0xbd, 0x96, 0x50, 0x81, 0x75, 0xa8, 0xc3, 0x08, 0xfe, 0x00, 0xcd, 0x06, - 0x48, 0xca, 0x21, 0x72, 0x4c, 0x9b, 0xd7, 0x96, 0xa6, 0x0a, 0xab, 0xf9, 0x94, 0x79, 0x95, 0x8f, - 0x7a, 0x2c, 0xbd, 0xf4, 0xd5, 0x37, 0x27, 0xf7, 0x95, 0x33, 0x34, 0x52, 0xae, 0x2f, 0xa2, 0x05, - 0x01, 0xe1, 0x11, 0x63, 0x6b, 0x1e, 0x87, 0x77, 0x81, 0xc2, 0x5d, 0xa7, 0x49, 0x8b, 0xb6, 0xed, - 0x43, 0xfd, 0xb9, 0x86, 0x4e, 0xa7, 0xd7, 0x03, 0xc4, 0x4d, 0x74, 0x68, 0x30, 0x1e, 0x1e, 0xe6, - 0xb1, 0xa5, 0xa9, 0xc2, 0xf9, 0x54, 0xcc, 0xe0, 0x3a, 0xe8, 0x19, 0x60, 0xcf, 0xf2, 0x48, 0xab, - 0x4c, 0xbf, 0x81, 0xe6, 0x13, 0xf1, 0x00, 0x68, 0xfc, 0x2a, 0x9a, 0x90, 0x53, 0xcb, 0x6a, 0x88, - 0xa0, 0x8d, 0x95, 0x5f, 0x11, 0xcf, 0x77, 0x1b, 0xfa, 0xcf, 0x34, 0x74, 0x2a, 0xc5, 0x1e, 0xc8, - 0x34, 0x10, 0x1e, 0x24, 0x03, 0xf1, 0xdf, 0x2d, 0x97, 0x4c, 0x94, 0x8b, 0x7e, 0x19, 0x65, 0x05, - 0x94, 0x75, 0xc2, 0x6f, 0x7b, 0xee, 0xee, 0x8b, 0x79, 0xa2, 0x40, 0x82, 0xa2, 0xe3, 0xb1, 0x86, - 0x80, 0xfe, 0x21, 0x9a, 0x0a, 0x14, 0x03, 0xec, 0xa5, 0x54, 0xd8, 0x81, 0xfa, 0x00, 0x37, 0xe8, - 0x42, 0x6f, 0x00, 0xd2, 0xa2, 0x6d, 0xc7, 0x20, 0x5d, 0x43, 0xa8, 0x9f, 0xb3, 0xa1, 0xb9, 0xd7, - 0xf3, 0x32, 0xc1, 0xe7, 0xbd, 0x04, 0x9f, 0x97, 0xcb, 0x02, 0x24, 0xf8, 0xfc, 0x43, 0xb3, 0x45, - 0xc0, 0xb6, 0x1c, 0xb0, 0xd4, 0xbf, 0xd0, 0x80, 0x57, 0xb4, 0x99, 0x24, 0x5e, 0x63, 0x2f, 0xc8, - 0x0b, 0xaf, 0x87, 0x90, 0xef, 0x17, 0xc8, 0xcf, 0x0c, 0x45, 0x2e, 0xe1, 0x84, 0xa0, 0x37, 0x61, - 0xc6, 0x17, 0x6d, 0xfb, 0xa1, 0xcc, 0x7a, 0xff, 0x9b, 0x10, 0x7d, 0xe9, 0x67, 0x8e, 0xc1, 0x86, - 0x20, 0x48, 0xef, 0xa3, 0xe9, 0x70, 0xde, 0x85, 0x38, 0x2d, 0xa7, 0xc6, 0x29, 0xe4, 0x0b, 0x22, - 0x75, 0xb0, 0x13, 0x2c, 0xdc, 0xbb, 0x58, 0xf9, 0x33, 0x38, 0xdc, 0x66, 0x57, 0xf4, 0x8b, 0xc2, - 0xe0, 0xff, 0x11, 0x4c, 0xe0, 0x78, 0xf3, 0x94, 0x28, 0x68, 0x7b, 0x10, 0x05, 0x7d, 0x0e, 0x61, - 0x7f, 0xea, 0x3d, 0xaa, 0x54, 0xfc, 0x2c, 0xf9, 0x00, 0x1d, 0x0a, 0x95, 0x02, 0x8a, 0x2b, 0x68, - 0xec, 0x51, 0xa5, 0x02, 0x4d, 0xcf, 0xa7, 0xe7, 0x8d, 0x4a, 0x05, 0x1a, 0xf4, 0x4c, 0xf4, 0x3b, - 0xe8, 0xd5, 0x9e, 0x43, 0xc6, 0x8a, 0x8d, 0x86, 0x4b, 0x58, 0x6f, 0x30, 0x2d, 0xa1, 0x4c, 0xcd, - 0xe2, 0x75, 0x6a, 0x39, 0xd5, 0x5e, 0x90, 0xf6, 0x8b, 0x20, 0x4d, 0x43, 0xf9, 0x6d, 0x88, 0xd5, - 0xad, 0x7e, 0x86, 0x09, 0xba, 0x01, 0x78, 0x19, 0x34, 0x46, 0x78, 0x5b, 0xc0, 0x9b, 0x2c, 0x7b, - 0x7f, 0xbd, 0x92, 0x1a, 0xaf, 0x0b, 0x67, 0x93, 0x65, 0xef, 0xaf, 0xfe, 0xa9, 0x86, 0x96, 0x07, - 0x5d, 0x94, 0xba, 0x6b, 0x96, 0x63, 0xda, 0xd6, 0x27, 0xa4, 0xb1, 0x41, 0xac, 0x56, 0x9b, 0xfb, - 0xd0, 0x0a, 0xe8, 0x70, 0xd3, 0x7f, 0x53, 0xf5, 0x58, 0x56, 0xdb, 0xe2, 0x3d, 0x74, 0xe2, 0xa1, - 0xde, 0xcb, 0xc7, 0x84, 0x9b, 0xd2, 0x74, 0x04, 0x3a, 0xef, 0xa1, 0x73, 0x4a, 0x58, 0x46, 0xe0, - 0xf7, 0x01, 0x3a, 0xe2, 0x2f, 0x07, 0x1b, 0x16, 0xe3, 0xd4, 0xed, 0xee, 0xf5, 0x94, 0xfd, 0x9d, - 0x86, 0x8e, 0x0e, 0x34, 0x01, 0x08, 0x8b, 0x68, 0xc2, 0x5b, 0x67, 0x6c, 0x8b, 0x71, 0x98, 0xa6, - 0xaa, 0xa3, 0xe4, 0x15, 0xce, 0xd8, 0x3b, 0x16, 0xe3, 0x7b, 0x37, 0x2d, 0xdb, 0x68, 0x4e, 0xc0, - 0xdc, 0x30, 0xd9, 0x77, 0x29, 0x27, 0x0d, 0x3f, 0x0e, 0xe7, 0xd0, 0xac, 0xd4, 0xcb, 0x55, 0xab, - 0x41, 0x1c, 0x6e, 0x35, 0x2d, 0xe2, 0x42, 0x4c, 0x33, 0xf2, 0xc5, 0xdd, 0x5e, 0x39, 0x5e, 0x40, - 0x07, 0x9f, 0x52, 0x4e, 0xdc, 0xaa, 0x29, 0x3b, 0x07, 0x42, 0x7d, 0x40, 0x14, 0x42, 0x87, 0xe9, - 0x97, 0xd0, 0xe1, 0x48, 0x4b, 0x10, 0x8e, 0xe3, 0x68, 0xb2, 0x6d, 0xb2, 0xaa, 0x57, 0x59, 0x4e, - 0xfb, 0x89, 0xf2, 0x44, 0x1b, 0x2a, 0xe9, 0xef, 0xa2, 0x9c, 0xb0, 0x2a, 0x89, 0x36, 0x4b, 0xdd, - 0x7e, 0xab, 0xbb, 0x41, 0xaa, 0x73, 0x34, 0xe9, 0xf9, 0x75, 0x45, 0x10, 0x07, 0x60, 0x6b, 0x83, - 0xb0, 0x71, 0x09, 0x4d, 0x7a, 0xcf, 0x55, 0xde, 0xed, 0x10, 0xc1, 0x6b, 0xba, 0xb0, 0x98, 0xda, - 0x5b, 0x9e, 0xff, 0x47, 0xdd, 0x0e, 0x29, 0x4f, 0x3c, 0x85, 0x7f, 0xfa, 0x1f, 0xf7, 0xa3, 0x93, - 0x89, 0x2c, 0x20, 0x0a, 0x23, 0x05, 0xfc, 0x2d, 0x34, 0x2e, 0x40, 0x7a, 0x91, 0x1e, 0x13, 0x23, - 0x74, 0x18, 0x22, 0xc1, 0xb8, 0x0c, 0x56, 0xf8, 0x7d, 0x94, 0x91, 0x6f, 0xc5, 0x20, 0x90, 0xdc, - 0xc6, 0x04, 0xb7, 0x95, 0x74, 0x9d, 0xd9, 0x37, 0x12, 0x14, 0x67, 0x68, 0xb8, 0x00, 0xdf, 0x47, - 0x07, 0x81, 0x05, 0xe3, 0x26, 0xdf, 0x62, 0xc7, 0x5e, 0x12, 0x5e, 0xcf, 0xa6, 0x7a, 0x95, 0x51, - 0xa9, 0x08, 0x83, 0xf2, 0x81, 0x5a, 0xe0, 0x49, 0xc7, 0x28, 0x23, 0x25, 0x33, 0xd4, 0xad, 0x10, - 0xae, 0x5f, 0x41, 0xc7, 0xa2, 0x65, 0xbd, 0x28, 0x9e, 0x40, 0x93, 0xbe, 0x5b, 0xb9, 0x04, 0x4e, - 0x96, 0xfb, 0x05, 0xfa, 0x11, 0x18, 0xec, 0x95, 0xad, 0x4e, 0x87, 0xba, 0x9c, 0x34, 0x44, 0x8a, - 0x61, 0x7a, 0x0d, 0xd6, 0xf1, 0x48, 0x79, 0xcf, 0x6b, 0x09, 0x8d, 0xcb, 0xbd, 0x04, 0x4c, 0xd7, - 0xd3, 0x71, 0x74, 0x3a, 0x4f, 0x5a, 0x79, 0xd8, 0x71, 0x08, 0x73, 0x98, 0xb2, 0x60, 0xa9, 0xdf, - 0x44, 0x7a, 0x48, 0xbd, 0x3d, 0x14, 0x1b, 0xaa, 0x35, 0xea, 0xaa, 0xae, 0x80, 0x2e, 0x48, 0xf7, - 0x24, 0x07, 0x80, 0xf5, 0x6d, 0x74, 0x40, 0x7a, 0x90, 0x3b, 0x36, 0x75, 0x1d, 0x28, 0xfd, 0x95, - 0xa7, 0xea, 0xfd, 0x07, 0xfd, 0x44, 0x44, 0xab, 0x42, 0x1d, 0x58, 0xff, 0x9c, 0x88, 0x20, 0xf5, - 0xdf, 0x02, 0x92, 0x07, 0xb1, 0x48, 0x56, 0x54, 0x91, 0x88, 0x01, 0x1b, 0x42, 0x53, 0xe8, 0xa3, - 0xb9, 0x4f, 0x1b, 0xa4, 0x28, 0x77, 0xba, 0x7e, 0xe8, 0xe6, 0xd0, 0xcb, 0x96, 0xd3, 0x20, 0x1f, - 0xc3, 0xa4, 0x91, 0x0f, 0xfa, 0x0f, 0xfb, 0x18, 0x43, 0x36, 0xfd, 0x68, 0x05, 0x77, 0xcd, 0x4a, - 0xd1, 0x0a, 0xfa, 0x99, 0x72, 0xfa, 0x0f, 0x41, 0xbd, 0x1c, 0x83, 0x6f, 0xaf, 0x56, 0x96, 0xcf, - 0x02, 0x7a, 0x39, 0x8e, 0xd2, 0x3d, 0x34, 0x15, 0x28, 0x56, 0xd2, 0xcb, 0x21, 0x46, 0x81, 0x87, - 0xbd, 0x5b, 0x66, 0xe6, 0x21, 0x8d, 0x7b, 0x43, 0xa5, 0x77, 0x06, 0x12, 0xda, 0x1d, 0xff, 0x58, - 0x83, 0x1c, 0x19, 0x57, 0x05, 0xa8, 0x7d, 0x1f, 0x65, 0xa2, 0x27, 0x28, 0x6a, 0xa3, 0x2a, 0xec, - 0x0f, 0x66, 0xe6, 0x4c, 0x3d, 0x5c, 0xac, 0x1f, 0x85, 0x15, 0x6a, 0x9d, 0xf0, 0xb7, 0xc5, 0xa1, - 0x8b, 0x8f, 0xed, 0x3b, 0x20, 0x17, 0x02, 0x2f, 0x00, 0xd1, 0x75, 0x34, 0x2e, 0xcf, 0x67, 0x00, - 0xc7, 0x42, 0x2a, 0x0e, 0x30, 0x06, 0x13, 0xfd, 0x24, 0xa8, 0xfa, 0x4a, 0x9b, 0x7e, 0xe4, 0x27, - 0xb3, 0xdb, 0x81, 0x21, 0xe3, 0xc5, 0x24, 0x97, 0x54, 0x03, 0x00, 0xfc, 0x00, 0x1d, 0xb2, 0x4d, - 0xc6, 0xab, 0x7e, 0x1b, 0xd5, 0xe0, 0x38, 0xce, 0xa7, 0xa2, 0x79, 0xc7, 0x64, 0x3c, 0xec, 0x74, - 0xd6, 0x8e, 0x16, 0xe9, 0xf7, 0x00, 0x63, 0xc9, 0x36, 0x37, 0x49, 0xdc, 0xf2, 0x7b, 0x16, 0x65, - 0xc4, 0x71, 0xd9, 0xe0, 0xb2, 0x35, 0x23, 0xca, 0x03, 0x8b, 0x6f, 0xdd, 0x5f, 0xcb, 0x07, 0x7d, - 0xf5, 0x94, 0x11, 0x02, 0x67, 0x4e, 0x93, 0x02, 0x09, 0x3d, 0x7d, 0xed, 0xf0, 0xaa, 0x97, 0x27, - 0x65, 0x53, 0x4e, 0x93, 0xea, 0xa4, 0x3f, 0x3b, 0xe4, 0x3b, 0x52, 0xa7, 0x6e, 0x63, 0xcf, 0xb7, - 0x64, 0x7f, 0xd0, 0xfa, 0x7b, 0xbf, 0x70, 0x3b, 0x40, 0x65, 0x3d, 0x42, 0x65, 0x4c, 0x8d, 0x0a, - 0x8c, 0xcd, 0x3e, 0xa1, 0xbd, 0x9b, 0x83, 0x15, 0xd8, 0x81, 0x41, 0xf8, 0x45, 0xaa, 0x2d, 0x3a, - 0x0d, 0xb1, 0xc5, 0x19, 0xbe, 0xfe, 0x78, 0xf9, 0x55, 0x6c, 0xaa, 0x40, 0xa5, 0xcb, 0x07, 0xbd, - 0x09, 0xfb, 0xb2, 0x78, 0xa7, 0x09, 0xdd, 0x3a, 0x36, 0x72, 0xb7, 0x16, 0xbe, 0x59, 0x44, 0x2f, - 0x8b, 0x86, 0xf0, 0x9f, 0x35, 0x34, 0xe1, 0x6b, 0x48, 0x7c, 0x21, 0xd5, 0x4b, 0x9c, 0xb2, 0xcd, - 0x16, 0x46, 0x31, 0x91, 0x04, 0xf4, 0x7b, 0x3f, 0xfd, 0xfb, 0x7f, 0x7e, 0xb9, 0xff, 0xff, 0x71, - 0x49, 0x9c, 0x07, 0xae, 0xca, 0xa3, 0xc1, 0xde, 0x89, 0x60, 0x4f, 0xbd, 0x1a, 0xdb, 0x03, 0x12, - 0x6e, 0xc7, 0xd8, 0x0e, 0x69, 0xcc, 0x1d, 0xfc, 0x4f, 0x0d, 0xe1, 0x41, 0x1d, 0x88, 0xaf, 0x0f, - 0x87, 0x95, 0xa8, 0x81, 0xb3, 0x6f, 0xee, 0xce, 0x18, 0xd8, 0xdd, 0x11, 0xec, 0x6e, 0xe2, 0x1b, - 0xb1, 0xec, 0x80, 0x52, 0xad, 0x1b, 0x60, 0x15, 0x47, 0x14, 0xff, 0x46, 0x43, 0x53, 0x01, 0x4d, - 0x86, 0x57, 0x87, 0x83, 0x0a, 0x54, 0xcf, 0xbe, 0x31, 0x52, 0xf5, 0x1e, 0xf8, 0xb3, 0x02, 0xfc, - 0x02, 0x3e, 0x15, 0x0b, 0xbe, 0x97, 0x16, 0x19, 0xe1, 0xf8, 0xf7, 0x1a, 0x9a, 0x89, 0x48, 0x3c, - 0x95, 0x01, 0x14, 0x31, 0xc9, 0x5e, 0x1d, 0xd9, 0xa4, 0x07, 0x76, 0x45, 0x80, 0x7d, 0x1d, 0x9f, - 0x8e, 0x05, 0xcb, 0x22, 0xd8, 0xfe, 0xad, 0xa1, 0x23, 0xf1, 0x6a, 0x0f, 0xdf, 0x1c, 0x8e, 0x21, - 0x55, 0x68, 0x66, 0x6f, 0xed, 0xde, 0x01, 0x70, 0x29, 0x09, 0x2e, 0x6f, 0xe2, 0x6b, 0xb1, 0x5c, - 0x5a, 0x84, 0x57, 0x83, 0xea, 0xaf, 0xda, 0xa4, 0xae, 0x2c, 0x30, 0xb6, 0xfd, 0x0c, 0xb3, 0x83, - 0x3f, 0xd3, 0xd0, 0x74, 0xb8, 0x19, 0x7c, 0x79, 0x54, 0x60, 0x3e, 0xa3, 0x2b, 0xa3, 0x1b, 0x02, - 0x93, 0x55, 0xc1, 0xe4, 0x0c, 0x5e, 0x54, 0x62, 0xe2, 0x81, 0x0e, 0x89, 0x24, 0x35, 0xc4, 0x83, - 0x8a, 0x50, 0x11, 0x71, 0x8c, 0xc6, 0xd3, 0xcf, 0x0b, 0xc4, 0xcb, 0x78, 0x29, 0x16, 0x71, 0x40, - 0x93, 0x1a, 0xdb, 0x42, 0x06, 0xef, 0x78, 0x63, 0x7f, 0x3a, 0xe0, 0xa9, 0x68, 0xdb, 0x2a, 0xb8, - 0x63, 0x95, 0xac, 0x0a, 0xee, 0x78, 0x6d, 0xaa, 0x2f, 0x09, 0xdc, 0x3a, 0x9e, 0x1f, 0x86, 0x1b, - 0xff, 0x49, 0x43, 0x33, 0x11, 0xd9, 0xa6, 0x92, 0x22, 0x13, 0xf5, 0xa5, 0x4a, 0x8a, 0x4c, 0x56, - 0x9e, 0x43, 0x86, 0x48, 0x54, 0x94, 0xe2, 0x5f, 0x69, 0x68, 0x5c, 0x8a, 0x3d, 0x5c, 0x50, 0x6a, - 0x37, 0xa4, 0x37, 0xb3, 0x17, 0x47, 0xb2, 0x01, 0x88, 0x0b, 0x02, 0xe2, 0x6b, 0xf8, 0x78, 0x2c, - 0x44, 0x29, 0x39, 0xf1, 0x5f, 0x34, 0x34, 0x3b, 0x20, 0x26, 0xf1, 0x35, 0x85, 0x8c, 0x96, 0xa0, - 0x51, 0xb3, 0xd7, 0x77, 0x65, 0x0b, 0x98, 0xaf, 0x0a, 0xcc, 0x17, 0xf1, 0x85, 0x20, 0xe6, 0xc1, - 0x2b, 0x37, 0xd6, 0xa6, 0x1f, 0x45, 0x14, 0x2e, 0xfe, 0x9b, 0x86, 0x66, 0x07, 0x84, 0xa4, 0x0a, - 0x93, 0x24, 0x25, 0xab, 0xc2, 0x24, 0x51, 0xb9, 0xea, 0xb7, 0x05, 0x93, 0x1b, 0xf8, 0x7a, 0xfc, - 0x1a, 0x2a, 0xd4, 0x4f, 0x74, 0x09, 0x8d, 0xc8, 0xe6, 0x1d, 0x4f, 0xda, 0xe0, 0x75, 0xc2, 0x23, - 0x92, 0x12, 0xab, 0xcd, 0xb7, 0x18, 0xb5, 0xab, 0xb2, 0x54, 0x25, 0xe8, 0x57, 0xbd, 0x20, 0x08, - 0xad, 0xe0, 0xe5, 0xc4, 0xa4, 0x68, 0xda, 0x76, 0x55, 0x72, 0x70, 0x01, 0xe8, 0xb7, 0x1a, 0x3a, - 0x2c, 0x9c, 0xb1, 0x88, 0x12, 0xc4, 0x37, 0x94, 0x63, 0x1b, 0x27, 0x4b, 0xb3, 0x6f, 0xed, 0xd6, - 0x1c, 0xc8, 0x6c, 0x08, 0x32, 0x25, 0x7c, 0x2b, 0xbd, 0x77, 0xe4, 0x14, 0x36, 0x9d, 0x86, 0xbc, - 0x3e, 0x08, 0xac, 0x54, 0xc6, 0xb6, 0x28, 0xd9, 0xc1, 0x5f, 0x6a, 0xe8, 0x60, 0xe8, 0x20, 0x1a, - 0xff, 0x9f, 0xd2, 0x64, 0x1d, 0x38, 0xcf, 0xcf, 0x5e, 0x1e, 0xd9, 0x0e, 0xc8, 0xdc, 0x14, 0x64, - 0xae, 0xe2, 0xcb, 0x89, 0x3d, 0xc3, 0x19, 0xf3, 0xf5, 0xa6, 0xb1, 0x1d, 0x3d, 0x65, 0xdf, 0xc1, - 0xbf, 0xde, 0x8f, 0x72, 0xe9, 0x87, 0xe9, 0x78, 0x7d, 0x44, 0x70, 0x49, 0x57, 0x03, 0xd9, 0x8d, - 0x17, 0x77, 0x04, 0xb4, 0x6b, 0x82, 0xf6, 0xf7, 0xf0, 0x63, 0x15, 0xda, 0xd5, 0xb6, 0x38, 0x73, - 0xb7, 0xea, 0xa6, 0x6d, 0x6c, 0xc7, 0xde, 0x4d, 0xec, 0xc4, 0x45, 0xe6, 0x53, 0x4d, 0xdc, 0xdd, - 0x60, 0x43, 0x0d, 0x75, 0xef, 0x2a, 0x28, 0x7b, 0x5e, 0xdd, 0x00, 0xe8, 0xcc, 0x0b, 0x3a, 0x59, - 0x7c, 0x2c, 0x96, 0x8e, 0x07, 0xe2, 0xb7, 0x1a, 0x42, 0xfd, 0xdb, 0x03, 0xac, 0xb0, 0x28, 0x0c, - 0x5c, 0x67, 0x64, 0x2f, 0x8d, 0x66, 0x04, 0xd8, 0xce, 0x08, 0x6c, 0xa7, 0xf0, 0xc9, 0x58, 0x6c, - 0xbc, 0x8f, 0xe9, 0x73, 0x0d, 0x65, 0x42, 0xd7, 0x67, 0x9e, 0xae, 0x50, 0x4b, 0x3a, 0x71, 0x17, - 0xa6, 0xd9, 0x6b, 0xbb, 0x31, 0x05, 0xd0, 0xcb, 0x02, 0xf4, 0x69, 0xac, 0xc7, 0x82, 0x0e, 0xdf, - 0x6a, 0xfe, 0x55, 0x43, 0x73, 0x71, 0x37, 0x89, 0x2a, 0x79, 0x2a, 0xe5, 0x02, 0x53, 0x25, 0x4f, - 0xa5, 0x5d, 0x60, 0xea, 0x6f, 0x08, 0x0e, 0x06, 0x5e, 0x1d, 0xce, 0x21, 0x28, 0xa3, 0x3f, 0xd7, - 0x42, 0x77, 0xe4, 0xa3, 0x68, 0xe8, 0x70, 0xfc, 0xaf, 0x8c, 0x6e, 0x08, 0xc8, 0x2f, 0x0a, 0xe4, - 0xab, 0xf8, 0x5c, 0xbc, 0x40, 0xea, 0x5b, 0x04, 0x71, 0x7b, 0xa2, 0x34, 0xe0, 0x4c, 0x5d, 0x94, - 0xee, 0x0e, 0x7a, 0xfc, 0x07, 0x06, 0x43, 0x44, 0x69, 0x00, 0xba, 0xa7, 0x9e, 0xe6, 0xe2, 0xbe, - 0x20, 0x51, 0x19, 0x36, 0x29, 0x5f, 0xae, 0xa8, 0x0c, 0x9b, 0xb4, 0x0f, 0x57, 0x86, 0x6c, 0x07, - 0x5a, 0x22, 0xbf, 0x86, 0xac, 0xf1, 0x3f, 0x34, 0x74, 0x34, 0xe1, 0xdb, 0x1e, 0x7c, 0x6b, 0x77, - 0x68, 0xfa, 0x9f, 0x0f, 0x65, 0x8b, 0x2f, 0xe0, 0x01, 0x28, 0x5d, 0x12, 0x94, 0xf2, 0x78, 0x25, - 0x89, 0x52, 0xd1, 0xb6, 0xa3, 0x3e, 0x18, 0xfe, 0x42, 0x43, 0x99, 0xe8, 0xb7, 0x50, 0x2a, 0xf9, - 0x28, 0xe1, 0x93, 0x2d, 0x95, 0x7c, 0x94, 0xf4, 0x31, 0xd7, 0x90, 0x2d, 0x43, 0xf4, 0xcb, 0xac, - 0xd2, 0x9d, 0xaf, 0x9e, 0xe5, 0xb4, 0xaf, 0x9f, 0xe5, 0xb4, 0x6f, 0x9f, 0xe5, 0xb4, 0x5f, 0x3c, - 0xcf, 0xed, 0xfb, 0xfa, 0x79, 0x6e, 0xdf, 0xbf, 0x9e, 0xe7, 0xf6, 0x3d, 0x3e, 0xd7, 0xb2, 0x78, - 0x7b, 0xab, 0x96, 0xaf, 0xd3, 0xcd, 0xa0, 0x2b, 0x6f, 0xb7, 0x64, 0x7c, 0x1c, 0x48, 0xcb, 0xdd, - 0x0e, 0x61, 0xb5, 0x71, 0xf1, 0x2d, 0xda, 0xc5, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x8c, - 0xf5, 0xdd, 0xb0, 0x29, 0x00, 0x00, + 0x15, 0xf6, 0x5a, 0x89, 0x2d, 0x8d, 0x6c, 0x89, 0x1a, 0xcb, 0xb6, 0x42, 0x2b, 0xb4, 0xbc, 0x92, + 0x6d, 0x59, 0x96, 0xb8, 0x12, 0xed, 0xd4, 0xbf, 0xe2, 0xd8, 0xa4, 0x6a, 0x49, 0x76, 0x12, 0xdb, + 0x21, 0xdd, 0x06, 0x30, 0x9a, 0x32, 0x4b, 0x72, 0x48, 0x6e, 0xbd, 0xda, 0x61, 0x76, 0x56, 0x4e, + 0x18, 0x55, 0x40, 0xdb, 0x5b, 0x73, 0x28, 0x0a, 0xb4, 0x68, 0x6f, 0x45, 0x0f, 0xed, 0xb1, 0x40, + 0x11, 0x20, 0x68, 0x80, 0xa2, 0x87, 0x9c, 0x9a, 0x43, 0x0f, 0x29, 0x5a, 0x14, 0x3d, 0xb5, 0x81, + 0xdd, 0x7f, 0xa1, 0xf7, 0x62, 0x67, 0xde, 0x92, 0xbb, 0xcb, 0xdd, 0xe5, 0x50, 0x66, 0x4f, 0xe4, + 0xce, 0xce, 0x7b, 0xf3, 0x7d, 0x6f, 0x66, 0xde, 0x7c, 0x33, 0xb3, 0xe8, 0xfc, 0xc7, 0xc4, 0xd1, + 0xab, 0x4d, 0xdd, 0xb0, 0x34, 0xfe, 0x8f, 0xda, 0x44, 0xa3, 0x15, 0x46, 0xec, 0xa7, 0xc4, 0xd6, + 0x3e, 0xd8, 0x21, 0x76, 0x3b, 0xdb, 0xb2, 0xa9, 0x43, 0xf1, 0xa9, 0x4e, 0xc5, 0xac, 0x57, 0x31, + 0xeb, 0x55, 0x4c, 0x2f, 0x55, 0x29, 0xdb, 0xa6, 0x4c, 0xab, 0xe8, 0x8c, 0x08, 0x2b, 0xed, 0xe9, + 0x5a, 0x85, 0x38, 0xfa, 0x9a, 0xd6, 0xd2, 0x1b, 0x86, 0xa5, 0x3b, 0x06, 0xb5, 0x84, 0xa3, 0xf4, + 0x74, 0x83, 0x36, 0x28, 0xff, 0xab, 0xb9, 0xff, 0xa0, 0x74, 0xb6, 0x41, 0x69, 0xc3, 0x24, 0x9a, + 0xde, 0x32, 0x34, 0xdd, 0xb2, 0xa8, 0xc3, 0x4d, 0x18, 0xbc, 0x5d, 0x4c, 0x42, 0x59, 0xd1, 0x4d, + 0x93, 0x3a, 0x50, 0x33, 0x91, 0x4f, 0xc5, 0xd4, 0xb7, 0x09, 0x54, 0xcc, 0x26, 0x55, 0xe4, 0xe5, + 0x65, 0x8b, 0x5a, 0x55, 0xe2, 0x41, 0xc8, 0x25, 0xd6, 0xb7, 0x29, 0x63, 0xc2, 0xa8, 0x6e, 0xea, + 0x0d, 0x29, 0xd8, 0x4f, 0x48, 0xbb, 0x41, 0x2c, 0x19, 0x34, 0x16, 0xad, 0x91, 0xb2, 0x5e, 0xad, + 0xd2, 0x1d, 0xcb, 0xa3, 0xb9, 0x94, 0x54, 0xdf, 0xfb, 0x23, 0x83, 0xa2, 0xa5, 0xdb, 0xfa, 0xb6, + 0x87, 0x77, 0x35, 0xb1, 0x26, 0xb1, 0x6a, 0x86, 0xd5, 0x08, 0x46, 0xe5, 0x6c, 0x92, 0x85, 0xc3, + 0xbc, 0x6a, 0x2b, 0x89, 0x70, 0x5b, 0xc4, 0xe6, 0xbd, 0xad, 0x9b, 0x09, 0xec, 0x5a, 0x4f, 0x1a, + 0xa2, 0x5b, 0x18, 0xfc, 0xf4, 0xa9, 0xdb, 0xb2, 0x29, 0xad, 0x33, 0xf8, 0x81, 0xba, 0x97, 0xfb, + 0xa0, 0x2d, 0xd7, 0x77, 0xac, 0x1a, 0x2b, 0x6f, 0x1b, 0x0d, 0x5b, 0x77, 0x28, 0xc4, 0x4f, 0x7d, + 0x0f, 0x1d, 0x7b, 0xc7, 0x1d, 0xd2, 0x05, 0x3e, 0xce, 0x58, 0x91, 0x7c, 0xb0, 0x43, 0x98, 0x83, + 0x37, 0x10, 0xea, 0x8e, 0xed, 0x19, 0x65, 0x4e, 0x59, 0x1c, 0xcf, 0x9d, 0xcb, 0x8a, 0x89, 0x90, + 0x75, 0x27, 0x42, 0x56, 0x4c, 0x1f, 0x98, 0x08, 0xd9, 0x87, 0x7a, 0x83, 0x80, 0x6d, 0xd1, 0x67, + 0xa9, 0xfe, 0x46, 0x41, 0xd3, 0x41, 0xff, 0xac, 0x45, 0x2d, 0x46, 0xf0, 0x3a, 0x3a, 0x2c, 0x86, + 0x36, 0x9b, 0x51, 0xe6, 0x46, 0x16, 0xc7, 0x73, 0xf3, 0xd9, 0x84, 0x39, 0x98, 0x15, 0xe6, 0x85, + 0x97, 0xbe, 0xfc, 0xd7, 0xe9, 0x03, 0x45, 0xcf, 0x12, 0x6f, 0x06, 0x50, 0x1e, 0xe4, 0x28, 0xcf, + 0xf7, 0x45, 0x29, 0x10, 0x04, 0x60, 0x66, 0xd0, 0x2c, 0x47, 0xf9, 0xa0, 0xdb, 0x5b, 0x1b, 0xee, + 0x50, 0x07, 0x4a, 0xea, 0x0f, 0x15, 0xf4, 0x6a, 0x4c, 0x05, 0xe0, 0xf3, 0x3e, 0x9a, 0xf2, 0x75, + 0xb5, 0x98, 0x28, 0x10, 0xb7, 0x95, 0x44, 0x66, 0x61, 0x8f, 0xc0, 0x31, 0x45, 0x43, 0xe5, 0xea, + 0x59, 0x34, 0xcf, 0x21, 0x3c, 0x62, 0x6c, 0xc3, 0xed, 0xc9, 0xb7, 0xa1, 0x23, 0xef, 0x5a, 0x75, + 0x9a, 0x37, 0x4d, 0x0f, 0xea, 0x4f, 0x14, 0xb4, 0x90, 0x5c, 0x0f, 0x10, 0xd7, 0xd1, 0xb1, 0xde, + 0x51, 0xe1, 0xf5, 0xc6, 0x6a, 0x22, 0x66, 0x70, 0xed, 0xf7, 0x0c, 0xb0, 0xa7, 0x9c, 0x50, 0xab, + 0x4c, 0xbd, 0x89, 0xe6, 0x62, 0xf1, 0x78, 0xc3, 0xed, 0x15, 0x34, 0x2a, 0x12, 0x8c, 0x51, 0xe3, + 0x41, 0x1b, 0x29, 0x1e, 0xe6, 0xcf, 0x77, 0x6b, 0xea, 0x8f, 0x15, 0x74, 0x26, 0xc1, 0x1e, 0xc8, + 0xd4, 0x10, 0xee, 0x25, 0x03, 0xf1, 0xdf, 0x2f, 0x97, 0x54, 0x98, 0x8b, 0x7a, 0x05, 0xa5, 0x39, + 0x94, 0x4d, 0xe2, 0xac, 0xbb, 0xee, 0xee, 0xf3, 0x6c, 0x21, 0x41, 0x82, 0xa2, 0x53, 0x91, 0x86, + 0x80, 0xfe, 0x21, 0x1a, 0xf7, 0x15, 0x03, 0xec, 0xc5, 0x44, 0xd8, 0xbe, 0xfa, 0x00, 0xd7, 0xef, + 0x42, 0xad, 0x01, 0xd2, 0xbc, 0x69, 0x46, 0x20, 0x1d, 0xd6, 0xec, 0xfe, 0x5c, 0x01, 0x5e, 0xe1, + 0x66, 0xe2, 0x78, 0x8d, 0xbc, 0x20, 0xaf, 0xe1, 0xcd, 0xf8, 0x3a, 0xcc, 0xf8, 0xbc, 0x69, 0x3e, + 0x14, 0xb9, 0xff, 0xff, 0x13, 0xa2, 0x2f, 0xbc, 0xcc, 0xd1, 0xdb, 0x10, 0x04, 0xe9, 0x5d, 0x34, + 0x11, 0x5c, 0x7d, 0x20, 0x4e, 0x4b, 0x89, 0x71, 0x0a, 0xf8, 0x82, 0x48, 0x1d, 0x6d, 0xf9, 0x0b, + 0x87, 0x17, 0x2b, 0x6f, 0x06, 0x07, 0xdb, 0x6c, 0xf3, 0x7e, 0x91, 0x18, 0xfc, 0xdf, 0x87, 0x09, + 0x1c, 0x6d, 0x9e, 0x10, 0x05, 0x65, 0x08, 0x51, 0x50, 0xa7, 0x11, 0xf6, 0xa6, 0xde, 0xa3, 0x52, + 0xc9, 0xcb, 0x92, 0x0f, 0x60, 0xd9, 0xf3, 0x4a, 0x01, 0xc5, 0x55, 0x34, 0xf2, 0xa8, 0x54, 0x82, + 0xa6, 0xe7, 0x92, 0xf3, 0x46, 0xa9, 0x04, 0x0d, 0xba, 0x26, 0xea, 0x1d, 0xf4, 0x4a, 0xc7, 0x21, + 0x63, 0xf9, 0x5a, 0xcd, 0x26, 0xac, 0x33, 0x98, 0x16, 0x51, 0xaa, 0x62, 0x38, 0x55, 0x6a, 0x58, + 0xe5, 0x4e, 0x90, 0x0e, 0xf2, 0x20, 0x4d, 0x40, 0xf9, 0x3a, 0xc4, 0xea, 0x76, 0x37, 0xc3, 0xf8, + 0xdd, 0x00, 0xbc, 0x14, 0x1a, 0x21, 0x4e, 0x93, 0xc3, 0x1b, 0x2b, 0xba, 0x7f, 0xdd, 0x92, 0x8a, + 0x53, 0xe5, 0xce, 0xc6, 0x8a, 0xee, 0x5f, 0xf5, 0x13, 0x05, 0x2d, 0xf5, 0xba, 0x28, 0xb4, 0x37, + 0x0c, 0x4b, 0x37, 0x8d, 0x8f, 0x49, 0x6d, 0x8b, 0x18, 0x8d, 0xa6, 0xe3, 0x41, 0xcb, 0xa1, 0xe3, + 0x75, 0xef, 0x4d, 0xd9, 0x65, 0x59, 0x6e, 0xf2, 0xf7, 0xd0, 0x89, 0xc7, 0x3a, 0x2f, 0x1f, 0x13, + 0x47, 0x17, 0xa6, 0x03, 0xd0, 0x79, 0x07, 0x5d, 0x94, 0xc2, 0x32, 0x00, 0xbf, 0xf7, 0xd1, 0x09, + 0x6f, 0x39, 0xd8, 0x32, 0x98, 0x43, 0xed, 0xf6, 0xb0, 0xa7, 0xec, 0x6f, 0x15, 0x74, 0xb2, 0xa7, + 0x09, 0x40, 0x98, 0x47, 0xa3, 0xee, 0x3a, 0x63, 0x1a, 0xcc, 0x81, 0x69, 0x2a, 0x3b, 0x4a, 0x0e, + 0x3b, 0x8c, 0xbd, 0x65, 0x30, 0x67, 0x78, 0xd3, 0xb2, 0x09, 0xd2, 0x6a, 0x4b, 0x67, 0xdf, 0xa6, + 0x0e, 0xa9, 0x79, 0x71, 0xb8, 0x88, 0xa6, 0x84, 0x40, 0x2a, 0x1b, 0x35, 0x62, 0x39, 0x46, 0xdd, + 0x20, 0x36, 0xc4, 0x34, 0x25, 0x5e, 0xdc, 0xed, 0x94, 0xe3, 0x79, 0x74, 0xf4, 0x29, 0x75, 0x88, + 0x5d, 0xd6, 0x45, 0xe7, 0x40, 0xa8, 0x8f, 0xf0, 0x42, 0xe8, 0x30, 0xf5, 0x32, 0x3a, 0x1e, 0x6a, + 0x09, 0xc2, 0x71, 0x0a, 0x8d, 0x35, 0x75, 0x56, 0x76, 0x2b, 0x8b, 0x69, 0x3f, 0x5a, 0x1c, 0x6d, + 0x42, 0x25, 0xf5, 0x6d, 0x94, 0xf1, 0x49, 0xbf, 0x42, 0xbb, 0xdb, 0xea, 0x7e, 0x90, 0xaa, 0x0e, + 0x1a, 0x73, 0xfd, 0xda, 0x3c, 0x88, 0x3d, 0xb0, 0x95, 0x5e, 0xd8, 0xb8, 0x80, 0xc6, 0xdc, 0xe7, + 0xb2, 0xd3, 0x6e, 0x11, 0xce, 0x6b, 0x22, 0x77, 0x36, 0xb1, 0xb7, 0x5c, 0xff, 0x8f, 0xda, 0x2d, + 0x52, 0x1c, 0x7d, 0x0a, 0xff, 0xd4, 0x3f, 0x1c, 0x44, 0xa7, 0x63, 0x59, 0x40, 0x14, 0x06, 0x0a, + 0xf8, 0x1b, 0xe8, 0x10, 0x07, 0xe9, 0x46, 0x7a, 0x84, 0x8f, 0xd0, 0x7e, 0x88, 0x38, 0xe3, 0x22, + 0x58, 0xe1, 0x77, 0x51, 0x4a, 0xbc, 0xe5, 0x83, 0x40, 0x70, 0x1b, 0xe1, 0xdc, 0x96, 0x93, 0x75, + 0x66, 0xd7, 0x88, 0x53, 0x9c, 0xa4, 0xc1, 0x02, 0x7c, 0x1f, 0x1d, 0x05, 0x16, 0xcc, 0xd1, 0x9d, + 0x1d, 0x36, 0xf3, 0x12, 0xf7, 0x7a, 0x41, 0x42, 0x97, 0x97, 0xb8, 0x41, 0xf1, 0x48, 0xc5, 0xf7, + 0xa4, 0x62, 0x94, 0x12, 0x92, 0x19, 0xea, 0x96, 0x88, 0xa3, 0x5e, 0x45, 0x33, 0xe1, 0xb2, 0x4e, + 0x14, 0x67, 0xd1, 0x98, 0xe7, 0x56, 0x2c, 0x81, 0x63, 0xc5, 0x6e, 0x81, 0x7a, 0x02, 0x06, 0x7b, + 0x69, 0xa7, 0xd5, 0xa2, 0xb6, 0x43, 0x6a, 0x3c, 0xc5, 0x30, 0xb5, 0x02, 0xeb, 0x78, 0xa8, 0xbc, + 0xe3, 0xb5, 0x80, 0x0e, 0x89, 0x1d, 0x15, 0x4c, 0xd7, 0x85, 0x28, 0x3a, 0xad, 0x27, 0x8d, 0x2c, + 0xec, 0xbb, 0xb8, 0x39, 0x4c, 0x59, 0xb0, 0x54, 0x6f, 0x21, 0x35, 0xa0, 0xde, 0x1e, 0xf2, 0x6d, + 0xe5, 0x06, 0xb5, 0x65, 0x57, 0x40, 0x1b, 0xa4, 0x7b, 0x9c, 0x03, 0xc0, 0xfa, 0x26, 0x3a, 0x22, + 0x3c, 0x88, 0x7d, 0xab, 0xbc, 0x0e, 0x14, 0xfe, 0x8a, 0xe3, 0xd5, 0xee, 0x83, 0x3a, 0x1b, 0xd2, + 0xaa, 0x50, 0x07, 0xd6, 0x3f, 0x2b, 0x24, 0x48, 0xbd, 0xb7, 0x80, 0xe4, 0x41, 0x24, 0x92, 0x65, + 0x59, 0x24, 0x7c, 0xc0, 0x06, 0xd0, 0xe4, 0xba, 0x68, 0xee, 0xd3, 0x1a, 0xc9, 0x8b, 0xfd, 0xbe, + 0x17, 0xba, 0x69, 0xf4, 0xb2, 0x61, 0xd5, 0xc8, 0x47, 0x30, 0x69, 0xc4, 0x83, 0xfa, 0xbd, 0x2e, + 0xc6, 0x80, 0x4d, 0x37, 0x5a, 0xfe, 0xb3, 0x03, 0xa9, 0x68, 0xf9, 0xfd, 0x8c, 0x5b, 0xdd, 0x07, + 0xbf, 0x5e, 0x8e, 0xc0, 0x37, 0xac, 0x95, 0xe5, 0x53, 0x9f, 0x5e, 0x8e, 0xa2, 0x74, 0x0f, 0x8d, + 0xfb, 0x8a, 0xa5, 0xf4, 0x72, 0x80, 0x91, 0xef, 0x61, 0x78, 0xcb, 0xcc, 0x1c, 0xa4, 0x71, 0x77, + 0xa8, 0x74, 0x4e, 0x82, 0x02, 0xbb, 0xe3, 0x1f, 0x28, 0x90, 0x23, 0xa3, 0xaa, 0x00, 0xb5, 0xf7, + 0x50, 0x2a, 0x7c, 0x8e, 0x24, 0x37, 0xaa, 0x82, 0xfe, 0x60, 0x66, 0x4e, 0x56, 0x83, 0xc5, 0xea, + 0x49, 0x58, 0xa1, 0x36, 0x89, 0xf3, 0x26, 0x3f, 0x7a, 0xf2, 0xb0, 0x7d, 0x0b, 0xe4, 0x82, 0xef, + 0x05, 0x20, 0xba, 0x81, 0x0e, 0x89, 0x53, 0x2a, 0xc0, 0x91, 0x7c, 0x00, 0x01, 0xc6, 0x60, 0xa2, + 0x9e, 0x06, 0x55, 0x5f, 0x6a, 0xd2, 0x0f, 0xbd, 0x64, 0xb6, 0xee, 0x1b, 0x32, 0x6e, 0x4c, 0x32, + 0x71, 0x35, 0x00, 0xc0, 0x77, 0xd1, 0x31, 0x53, 0x67, 0x4e, 0xd9, 0x6b, 0xa3, 0xec, 0x1f, 0xc7, + 0xd9, 0x44, 0x34, 0x6f, 0xe9, 0xcc, 0x09, 0x3a, 0x9d, 0x32, 0xc3, 0x45, 0xea, 0x3d, 0xc0, 0x58, + 0x30, 0xf5, 0x6d, 0x12, 0xb5, 0xfc, 0x5e, 0x40, 0x29, 0x7e, 0x68, 0xd8, 0xbb, 0x6c, 0x4d, 0xf2, + 0x72, 0xdf, 0xe2, 0x5b, 0xf5, 0xd6, 0xf2, 0x5e, 0x5f, 0x1d, 0x65, 0x84, 0xc0, 0x99, 0x55, 0xa7, + 0x40, 0x42, 0x4d, 0x5e, 0x3b, 0xdc, 0xea, 0xc5, 0x31, 0xd1, 0x94, 0x55, 0xa7, 0x2a, 0xe9, 0xce, + 0x0e, 0xf1, 0x8e, 0x54, 0xa9, 0x5d, 0x1b, 0xfa, 0x96, 0xec, 0xf7, 0x4a, 0x77, 0xef, 0x17, 0x6c, + 0x07, 0xa8, 0x6c, 0x86, 0xa8, 0x8c, 0xc8, 0x51, 0x81, 0xb1, 0xd9, 0x25, 0x34, 0xbc, 0x39, 0x58, + 0x82, 0x1d, 0x18, 0x84, 0x9f, 0xa7, 0xda, 0xbc, 0x55, 0xe3, 0x5b, 0x9c, 0xfe, 0xeb, 0x8f, 0x9b, + 0x5f, 0xf9, 0xa6, 0x0a, 0x54, 0xba, 0x78, 0x50, 0xeb, 0xb0, 0x2f, 0x8b, 0x76, 0x1a, 0xd3, 0xad, + 0x23, 0x03, 0x77, 0x6b, 0xee, 0xbf, 0xe7, 0xd0, 0xcb, 0xbc, 0x21, 0xfc, 0x27, 0x05, 0x8d, 0x7a, + 0x1a, 0x12, 0xaf, 0x25, 0x7a, 0x89, 0x52, 0xb6, 0xe9, 0xdc, 0x20, 0x26, 0x82, 0x80, 0x7a, 0xef, + 0x47, 0x7f, 0xfb, 0xcf, 0xcf, 0x0e, 0x7e, 0x13, 0x17, 0xf8, 0xa9, 0xe8, 0x8a, 0x38, 0x20, 0xed, + 0x9c, 0x8b, 0x76, 0xd4, 0xab, 0xb6, 0xdb, 0x23, 0xe1, 0xf6, 0xb4, 0xdd, 0x80, 0xc6, 0xdc, 0xc3, + 0xff, 0x50, 0x10, 0xee, 0xd5, 0x81, 0xf8, 0x46, 0x7f, 0x58, 0xb1, 0x1a, 0x38, 0xfd, 0xfa, 0xfe, + 0x8c, 0x81, 0xdd, 0x1d, 0xce, 0xee, 0x16, 0xbe, 0x19, 0xc9, 0x0e, 0x28, 0x55, 0xda, 0x3e, 0x56, + 0x51, 0x44, 0xf1, 0xaf, 0x14, 0x34, 0xee, 0xd3, 0x64, 0x78, 0xa5, 0x3f, 0x28, 0x5f, 0xf5, 0xf4, + 0x6b, 0x03, 0x55, 0xef, 0x80, 0xbf, 0xc0, 0xc1, 0xcf, 0xe3, 0x33, 0x91, 0xe0, 0x3b, 0x69, 0x91, + 0x11, 0x07, 0xff, 0x4e, 0x41, 0x93, 0x21, 0x89, 0x27, 0x33, 0x80, 0x42, 0x26, 0xe9, 0x6b, 0x03, + 0x9b, 0x74, 0xc0, 0x2e, 0x73, 0xb0, 0xe7, 0xf0, 0x42, 0x24, 0x58, 0x16, 0xc2, 0xf6, 0x6f, 0x05, + 0x9d, 0x88, 0x56, 0x7b, 0xf8, 0x56, 0x7f, 0x0c, 0x89, 0x42, 0x33, 0x7d, 0x7b, 0xff, 0x0e, 0x80, + 0x4b, 0x81, 0x73, 0x79, 0x1d, 0x5f, 0x8f, 0xe4, 0xd2, 0x20, 0x4e, 0xd9, 0xaf, 0xfe, 0xca, 0x75, + 0x6a, 0x8b, 0x02, 0x6d, 0xd7, 0xcb, 0x30, 0x7b, 0xf8, 0x53, 0x05, 0x4d, 0x04, 0x9b, 0xc1, 0x57, + 0x06, 0x05, 0xe6, 0x31, 0xba, 0x3a, 0xb8, 0x21, 0x30, 0x59, 0xe1, 0x4c, 0xce, 0xe3, 0xb3, 0x52, + 0x4c, 0x5c, 0xd0, 0x01, 0x91, 0x24, 0x87, 0xb8, 0x57, 0x11, 0x4a, 0x22, 0x8e, 0xd0, 0x78, 0xea, + 0x2a, 0x47, 0xbc, 0x84, 0x17, 0x23, 0x11, 0xfb, 0x34, 0xa9, 0xb6, 0xcb, 0x65, 0xf0, 0x9e, 0x3b, + 0xf6, 0x27, 0x7c, 0x9e, 0xf2, 0xa6, 0x29, 0x83, 0x3b, 0x52, 0xc9, 0xca, 0xe0, 0x8e, 0xd6, 0xa6, + 0xea, 0x22, 0xc7, 0xad, 0xe2, 0xb9, 0x7e, 0xb8, 0xf1, 0x1f, 0x15, 0x34, 0x19, 0x92, 0x6d, 0x32, + 0x29, 0x32, 0x56, 0x5f, 0xca, 0xa4, 0xc8, 0x78, 0xe5, 0xd9, 0x67, 0x88, 0x84, 0x45, 0x29, 0xfe, + 0x85, 0x82, 0x0e, 0x09, 0xb1, 0x87, 0x73, 0x52, 0xed, 0x06, 0xf4, 0x66, 0xfa, 0xd2, 0x40, 0x36, + 0x00, 0x71, 0x9e, 0x43, 0x7c, 0x15, 0x9f, 0x8a, 0x84, 0x28, 0x24, 0x27, 0xfe, 0xb3, 0x82, 0xa6, + 0x7a, 0xc4, 0x24, 0xbe, 0x2e, 0x91, 0xd1, 0x62, 0x34, 0x6a, 0xfa, 0xc6, 0xbe, 0x6c, 0x01, 0xf3, + 0x35, 0x8e, 0xf9, 0x12, 0x5e, 0xf3, 0x63, 0xee, 0xbd, 0x78, 0x64, 0x4d, 0xfa, 0x61, 0x48, 0xe1, + 0xe2, 0xbf, 0x2a, 0x68, 0xaa, 0x47, 0x48, 0xca, 0x30, 0x89, 0x53, 0xb2, 0x32, 0x4c, 0x62, 0x95, + 0xab, 0xba, 0xce, 0x99, 0xdc, 0xc4, 0x37, 0xa2, 0xd7, 0x50, 0xae, 0x7e, 0xc2, 0x4b, 0x68, 0x48, + 0x36, 0xef, 0xb9, 0xd2, 0x06, 0x6f, 0x12, 0x27, 0x24, 0x29, 0xb1, 0xdc, 0x7c, 0x8b, 0x50, 0xbb, + 0x32, 0x4b, 0x55, 0x8c, 0x7e, 0x55, 0x73, 0x9c, 0xd0, 0x32, 0x5e, 0x8a, 0x4d, 0x8a, 0xba, 0x69, + 0x96, 0x05, 0x07, 0x1b, 0x80, 0x7e, 0xad, 0xa0, 0xe3, 0xdc, 0x19, 0x0b, 0x29, 0x41, 0x7c, 0x53, + 0x3a, 0xb6, 0x51, 0xb2, 0x34, 0xfd, 0xc6, 0x7e, 0xcd, 0x81, 0xcc, 0x16, 0x27, 0x53, 0xc0, 0xb7, + 0x93, 0x7b, 0x47, 0x4c, 0x61, 0xdd, 0xaa, 0x89, 0xeb, 0x03, 0xdf, 0x4a, 0xa5, 0xed, 0xf2, 0x92, + 0x3d, 0xfc, 0x85, 0x82, 0x8e, 0x06, 0x0e, 0xa2, 0xf1, 0x37, 0xa4, 0x26, 0x6b, 0xcf, 0x79, 0x7e, + 0xfa, 0xca, 0xc0, 0x76, 0x40, 0xe6, 0x16, 0x27, 0x73, 0x0d, 0x5f, 0x89, 0xed, 0x19, 0x87, 0x31, + 0x4f, 0x6f, 0x6a, 0xbb, 0xe1, 0x53, 0xf6, 0x3d, 0xfc, 0xcb, 0x83, 0x28, 0x93, 0x7c, 0x98, 0x8e, + 0x37, 0x07, 0x04, 0x17, 0x77, 0x35, 0x90, 0xde, 0x7a, 0x71, 0x47, 0x40, 0xbb, 0xc2, 0x69, 0x7f, + 0x07, 0x3f, 0x96, 0xa1, 0x5d, 0x6e, 0xf2, 0x33, 0x77, 0xa3, 0xaa, 0x9b, 0xda, 0x6e, 0xe4, 0xdd, + 0xc4, 0x5e, 0x54, 0x64, 0x3e, 0x51, 0xf8, 0xdd, 0x0d, 0xd6, 0xe4, 0x50, 0x77, 0xae, 0x82, 0xd2, + 0xab, 0xf2, 0x06, 0x40, 0x67, 0x8e, 0xd3, 0x49, 0xe3, 0x99, 0x48, 0x3a, 0x2e, 0x88, 0x5f, 0x2b, + 0x08, 0x75, 0x6f, 0x0f, 0xb0, 0xc4, 0xa2, 0xd0, 0x73, 0x9d, 0x91, 0xbe, 0x3c, 0x98, 0x11, 0x60, + 0x3b, 0xcf, 0xb1, 0x9d, 0xc1, 0xa7, 0x23, 0xb1, 0x39, 0x5d, 0x4c, 0x9f, 0x29, 0x28, 0x15, 0xb8, + 0x3e, 0x73, 0x75, 0x85, 0x5c, 0xd2, 0x89, 0xba, 0x30, 0x4d, 0x5f, 0xdf, 0x8f, 0x29, 0x80, 0x5e, + 0xe2, 0xa0, 0x17, 0xb0, 0x1a, 0x09, 0x3a, 0x78, 0xab, 0xf9, 0x17, 0x05, 0x4d, 0x47, 0xdd, 0x24, + 0xca, 0xe4, 0xa9, 0x84, 0x0b, 0x4c, 0x99, 0x3c, 0x95, 0x74, 0x81, 0xa9, 0xbe, 0xc6, 0x39, 0x68, + 0x78, 0xa5, 0x3f, 0x07, 0xbf, 0x8c, 0xfe, 0x4c, 0x09, 0xdc, 0x91, 0x0f, 0xa2, 0xa1, 0x83, 0xf1, + 0xbf, 0x3a, 0xb8, 0x21, 0x20, 0xbf, 0xc4, 0x91, 0xaf, 0xe0, 0x8b, 0xd1, 0x02, 0xa9, 0x6b, 0xe1, + 0xc7, 0xed, 0x8a, 0x52, 0x9f, 0x33, 0x79, 0x51, 0xba, 0x3f, 0xe8, 0xd1, 0x1f, 0x18, 0xf4, 0x11, + 0xa5, 0x3e, 0xe8, 0xae, 0x7a, 0x9a, 0x8e, 0xfa, 0x82, 0x44, 0x66, 0xd8, 0x24, 0x7c, 0xb9, 0x22, + 0x33, 0x6c, 0x92, 0x3e, 0x5c, 0xe9, 0xb3, 0x1d, 0x68, 0xf0, 0xfc, 0x1a, 0xb0, 0xc6, 0x7f, 0x57, + 0xd0, 0xc9, 0x98, 0x6f, 0x7b, 0xf0, 0xed, 0xfd, 0xa1, 0xe9, 0x7e, 0x3e, 0x94, 0xce, 0xbf, 0x80, + 0x07, 0xa0, 0x74, 0x99, 0x53, 0xca, 0xe2, 0xe5, 0x38, 0x4a, 0x79, 0xd3, 0x0c, 0xfb, 0x60, 0xf8, + 0x73, 0x05, 0xa5, 0xc2, 0xdf, 0x42, 0xc9, 0xe4, 0xa3, 0x98, 0x4f, 0xb6, 0x64, 0xf2, 0x51, 0xdc, + 0xc7, 0x5c, 0x7d, 0xb6, 0x0c, 0xe1, 0x2f, 0xb3, 0xf0, 0xcf, 0x15, 0x74, 0x18, 0xbe, 0x6f, 0xc3, + 0xab, 0xb2, 0xc7, 0x39, 0x1d, 0xa0, 0x6b, 0x03, 0x58, 0x00, 0xbe, 0x05, 0x8e, 0x2f, 0x83, 0x67, + 0x13, 0x4e, 0x7d, 0x58, 0xe1, 0xce, 0x97, 0xcf, 0x32, 0xca, 0x57, 0xcf, 0x32, 0xca, 0xd7, 0xcf, + 0x32, 0xca, 0x4f, 0x9f, 0x67, 0x0e, 0x7c, 0xf5, 0x3c, 0x73, 0xe0, 0x9f, 0xcf, 0x33, 0x07, 0x1e, + 0x5f, 0x6c, 0x18, 0x4e, 0x73, 0xa7, 0x92, 0xad, 0xd2, 0x6d, 0xbf, 0x07, 0x77, 0x13, 0xa7, 0x7d, + 0xe4, 0x5b, 0x2d, 0xda, 0x2d, 0xc2, 0x2a, 0x87, 0xf8, 0x87, 0x82, 0x97, 0xfe, 0x17, 0x00, 0x00, + 0xff, 0xff, 0xd0, 0xca, 0x0b, 0x7b, 0x4d, 0x2b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2591,6 +2693,8 @@ type QueryClient interface { TssFundsMigratorInfoAll(ctx context.Context, in *QueryTssFundsMigratorInfoAllRequest, opts ...grpc.CallOption) (*QueryTssFundsMigratorInfoAllResponse, error) // Queries operational flags OperationalFlags(ctx context.Context, in *QueryOperationalFlagsRequest, opts ...grpc.CallOption) (*QueryOperationalFlagsResponse, error) + // Query all ballots + Ballots(ctx context.Context, in *QueryBallotsRequest, opts ...grpc.CallOption) (*QueryBallotsResponse, error) } type queryClient struct { @@ -2826,6 +2930,15 @@ func (c *queryClient) OperationalFlags(ctx context.Context, in *QueryOperational return out, nil } +func (c *queryClient) Ballots(ctx context.Context, in *QueryBallotsRequest, opts ...grpc.CallOption) (*QueryBallotsResponse, error) { + out := new(QueryBallotsResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/Ballots", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Query if a voter has voted for a ballot @@ -2872,6 +2985,8 @@ type QueryServer interface { TssFundsMigratorInfoAll(context.Context, *QueryTssFundsMigratorInfoAllRequest) (*QueryTssFundsMigratorInfoAllResponse, error) // Queries operational flags OperationalFlags(context.Context, *QueryOperationalFlagsRequest) (*QueryOperationalFlagsResponse, error) + // Query all ballots + Ballots(context.Context, *QueryBallotsRequest) (*QueryBallotsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -2953,6 +3068,9 @@ func (*UnimplementedQueryServer) TssFundsMigratorInfoAll(ctx context.Context, re func (*UnimplementedQueryServer) OperationalFlags(ctx context.Context, req *QueryOperationalFlagsRequest) (*QueryOperationalFlagsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method OperationalFlags not implemented") } +func (*UnimplementedQueryServer) Ballots(ctx context.Context, req *QueryBallotsRequest) (*QueryBallotsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Ballots not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -3408,6 +3526,24 @@ func _Query_OperationalFlags_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _Query_Ballots_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryBallotsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Ballots(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Query/Ballots", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Ballots(ctx, req.(*QueryBallotsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.observer.Query", HandlerType: (*QueryServer)(nil), @@ -3512,11 +3648,99 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "OperationalFlags", Handler: _Query_OperationalFlags_Handler, }, + { + MethodName: "Ballots", + Handler: _Query_Ballots_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "zetachain/zetacore/observer/query.proto", } +func (m *QueryBallotsRequest) 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 *QueryBallotsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryBallotsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryBallotsResponse) 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 *QueryBallotsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryBallotsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Ballots) > 0 { + for iNdEx := len(m.Ballots) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ballots[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *QueryOperationalFlagsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -5235,6 +5459,38 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *QueryBallotsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryBallotsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ballots) > 0 { + for _, e := range m.Ballots { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QueryOperationalFlagsRequest) Size() (n int) { if m == nil { return 0 @@ -5919,6 +6175,212 @@ func sovQuery(x uint64) (n int) { func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *QueryBallotsRequest) 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 ErrIntOverflowQuery + } + 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: QueryBallotsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBallotsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryBallotsResponse) 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 ErrIntOverflowQuery + } + 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: QueryBallotsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryBallotsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ballots", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ballots = append(m.Ballots, Ballot{}) + if err := m.Ballots[len(m.Ballots)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryOperationalFlagsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/observer/types/query.pb.gw.go b/x/observer/types/query.pb.gw.go index 48bd9447dd..ba2d1831f2 100644 --- a/x/observer/types/query.pb.gw.go +++ b/x/observer/types/query.pb.gw.go @@ -1017,6 +1017,42 @@ func local_request_Query_OperationalFlags_0(ctx context.Context, marshaler runti } +var ( + filter_Query_Ballots_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_Ballots_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryBallotsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Ballots_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Ballots(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Ballots_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryBallotsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Ballots_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Ballots(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1598,6 +1634,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_Ballots_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Ballots_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Ballots_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2139,6 +2198,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_Ballots_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Ballots_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Ballots_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -2192,6 +2271,8 @@ var ( pattern_Query_TssFundsMigratorInfoAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "getAllTssFundsMigrators"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_OperationalFlags_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "operationalFlags"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_Ballots_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "ballots"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -2244,4 +2325,6 @@ var ( forward_Query_TssFundsMigratorInfoAll_0 = runtime.ForwardResponseMessage forward_Query_OperationalFlags_0 = runtime.ForwardResponseMessage + + forward_Query_Ballots_0 = runtime.ForwardResponseMessage )