From dd0929472d70da812537609f6383cb9d1ff3ca99 Mon Sep 17 00:00:00 2001 From: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Date: Fri, 25 Oct 2024 18:50:48 +0200 Subject: [PATCH] feat!: Add support for priority validators (#2101) * Start adding priority validators * Add new priority_validator field * Added priority list to the PowerShapingParameters * Add documentation for priority list * Add priority list in local-testnet.sh * Update .changelog/unreleased/features/provider/xxxx-priority-validators.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update x/ccv/provider/keeper/power_shaping.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update x/ccv/provider/keeper/power_shaping_test.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update x/ccv/provider/keeper/power_shaping_test.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update .changelog/unreleased/api-breaking/provider/xxxx-priority-validators.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Fix typo in provider.proto * Remove unnecessary priority list from test in steps_permissionless_ics.go * Remove comment from grpc_query.go * Add e2e test for priority list * Improved e2e test * Fixed some issues * Refactored code logic * Refactored code logic * Renamed files * Removed priority list from migrations.go * Fixed bug for priority list * Added priority list to e2e nightly tests * Update tx.go * Refactored TestCapValidatorSet * Small fixes * Small fixes * Fix PartitionBasedOnPriorityList function * Update contrib/local-testnet.sh Co-authored-by: Marius Poke * Moved 2101-introduce-priority-validators.md into state-breaking * Fixed TestGetConsumerChain * Added test case in TestCapValidatorSet * Revert changes made by the merge * Removed changes from ADRs that were already implemented * Added a comment in CapValidatorSet function * Removed unnecessary imports --------- Co-authored-by: kirdatatjana Co-authored-by: kirdatatjana <116630536+kirdatatjana@users.noreply.github.com> Co-authored-by: Marius Poke --- .../2101-introduce-priority-validators.md | 2 + .../2101-introduce-priority-validators.md | 2 + .github/workflows/nightly-e2e.yml | 17 + contrib/local-testnet.sh | 3 +- docs/docs/build/modules/02-provider.md | 13 +- docs/docs/consumer-development/onboarding.md | 4 +- docs/docs/features/power-shaping.md | 4 + .../ccv/provider/v1/provider.proto | 152 +++++--- .../ccv/provider/v1/query.proto | 5 + tests/e2e/actions.go | 9 + tests/e2e/main.go | 7 + tests/e2e/steps_partial_set_security.go | 184 +++++++++ testutil/keeper/unit_test_helpers.go | 1 + x/ccv/provider/client/cli/tx.go | 6 +- x/ccv/provider/client/legacy_proposals.go | 2 + x/ccv/provider/keeper/consumer_lifecycle.go | 1 + .../keeper/consumer_lifecycle_test.go | 5 + x/ccv/provider/keeper/grpc_query.go | 7 + x/ccv/provider/keeper/grpc_query_test.go | 17 +- x/ccv/provider/keeper/power_shaping.go | 116 +++++- x/ccv/provider/keeper/power_shaping_test.go | 237 +++++++++--- x/ccv/provider/keeper/validator_set_update.go | 4 +- x/ccv/provider/types/keys.go | 16 + x/ccv/provider/types/keys_test.go | 3 + x/ccv/provider/types/msg.go | 3 + x/ccv/provider/types/msg_test.go | 4 + x/ccv/provider/types/provider.pb.go | 346 ++++++++++------- x/ccv/provider/types/query.pb.go | 362 ++++++++++-------- 28 files changed, 1106 insertions(+), 426 deletions(-) create mode 100644 .changelog/unreleased/features/provider/2101-introduce-priority-validators.md create mode 100644 .changelog/unreleased/state-breaking/2101-introduce-priority-validators.md diff --git a/.changelog/unreleased/features/provider/2101-introduce-priority-validators.md b/.changelog/unreleased/features/provider/2101-introduce-priority-validators.md new file mode 100644 index 0000000000..a90e0a6e26 --- /dev/null +++ b/.changelog/unreleased/features/provider/2101-introduce-priority-validators.md @@ -0,0 +1,2 @@ +- Allow consumer chains to specify a list of priority validators that are included in the validator set before other validators are considered + ([\#2101](https://github.com/cosmos/interchain-security/pull/2101)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/2101-introduce-priority-validators.md b/.changelog/unreleased/state-breaking/2101-introduce-priority-validators.md new file mode 100644 index 0000000000..a90e0a6e26 --- /dev/null +++ b/.changelog/unreleased/state-breaking/2101-introduce-priority-validators.md @@ -0,0 +1,2 @@ +- Allow consumer chains to specify a list of priority validators that are included in the validator set before other validators are considered + ([\#2101](https://github.com/cosmos/interchain-security/pull/2101)) \ No newline at end of file diff --git a/.github/workflows/nightly-e2e.yml b/.github/workflows/nightly-e2e.yml index efac898687..2751aa598f 100644 --- a/.github/workflows/nightly-e2e.yml +++ b/.github/workflows/nightly-e2e.yml @@ -277,6 +277,22 @@ jobs: go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E partial set security denylist run: go run ./tests/e2e/... --tc partial-set-security-validators-denylisted + partial-set-security-validators-prioritylisted-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security prioritylist + run: go run ./tests/e2e/... --tc partial-set-security-validators-prioritylisted partial-set-security-modification-proposal: runs-on: ubuntu-latest timeout-minutes: 20 @@ -376,6 +392,7 @@ jobs: - partial-set-security-validators-power-cap-test - partial-set-security-validators-allowlisted-test - partial-set-security-validators-denylisted-test + - partial-set-security-validators-prioritylisted-test - partial-set-security-modification-proposal - active-set-changes-test - permissionless-basic-test diff --git a/contrib/local-testnet.sh b/contrib/local-testnet.sh index 3aebbbe262..a321bfe7f1 100755 --- a/contrib/local-testnet.sh +++ b/contrib/local-testnet.sh @@ -317,7 +317,8 @@ tee ${PROV_NODE_DIR}/consumer_prop.json< []byte{}`, wi Format: `byte(40) | len(consumerId) | []byte(consumerId) -> uint64` +#### Prioritylist + +`Prioritylist` is the list of provider validators that have priority to validate a given consumer chain. + +Format: `byte(56) | len(consumerId) | []byte(consumerId) | addr -> []byte{}`, with `addr` the validator's consensus address on the provider chain. + ### Validator Set Updates #### ValidatorSetUpdateId @@ -1089,6 +1095,7 @@ Output: chains: - allow_inactive_vals: true allowlist: [] + prioritylist: [] chain_id: pion-1 client_id: 07-tendermint-0 consumer_id: "0" @@ -1554,6 +1561,7 @@ power_shaping_params: top_N: 100 validator_set_cap: 0 validators_power_cap: 0 + prioritylist: [] ``` @@ -1679,8 +1687,9 @@ where `update-consumer-msg.json` contains: "validator_set_cap": 50, "allowlist":["cosmosvalcons1l9qq4m300z8c5ez86ak2mp8znftewkwgjlxh88"], "denylist":[], - "min_stake": 1000, - "allow_inactive_vals":true + "min_stake": "1000", + "allow_inactive_vals":true, + "prioritylist":[] }, "allowlisted_reward_denoms": { "denoms": ["ibc/0025F8A87464A471E66B234C4F93AEC5B4DA3D42D7986451A059273426290DD5"] diff --git a/docs/docs/consumer-development/onboarding.md b/docs/docs/consumer-development/onboarding.md index 1e48c7366f..1613a2f268 100644 --- a/docs/docs/consumer-development/onboarding.md +++ b/docs/docs/consumer-development/onboarding.md @@ -125,7 +125,9 @@ Example of power-shaping parameters: // Corresponds to the minimal amount of (provider chain) stake required to validate on the consumer chain. "min_stake": 0, // Corresponds to whether inactive validators are allowed to validate the consumer chain. - "allow_inactive_vals": false + "allow_inactive_vals": false, + // Corresponds to a list of provider consensus addresses of validators that have priority + "prioritylist": [], } ``` diff --git a/docs/docs/features/power-shaping.md b/docs/docs/features/power-shaping.md index 7bfad38588..08b4e94cd6 100644 --- a/docs/docs/features/power-shaping.md +++ b/docs/docs/features/power-shaping.md @@ -80,6 +80,10 @@ This can be useful for chains that want to have a larger validator set than the Consumer chains that enable this feature should strongly consider setting a minimum validator stake to ensure that only validators with some reputation/stake can validate the chain. By default, this parameter is set to `false`, i.e., validators outside of the provider's active set are not eligible to opt in. +### Prioritylist + +The consumer chain can specify a priority list of validators for participation in the validator set. Validators on the priority list are considered first when forming the consumer chain's validator set. If a priority list isn't set, the remaining slots are filled based on validator power. + ## Setting Power Shaping Parameters All the power shaping parameters can be set by the consumer chain in the `MsgCreateConsumer` or `MsgUpdateConsumer` messages. diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index e2e6b32c30..138e5fa23b 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -2,24 +2,24 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/v6/x/ccv/provider/types"; - -import "interchain_security/ccv/v1/wire.proto"; +import "amino/amino.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/evidence/v1beta1/evidence.proto"; +import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; -import "google/protobuf/timestamp.proto"; import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; import "ibc/core/client/v1/client.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; +import "interchain_security/ccv/v1/wire.proto"; import "tendermint/crypto/keys.proto"; -import "cosmos/evidence/v1beta1/evidence.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos_proto/cosmos.proto"; -import "amino/amino.proto"; + +option go_package = "github.com/cosmos/interchain-security/v6/x/ccv/provider/types"; // // Note any type defined in this file is ONLY used internally to the provider CCV module. -// These schemas can change with proper consideration of compatibility or migration. -// +// These schemas can change with proper consideration of compatibility or migration. +// // WARNING: This message is deprecated in favor of `MsgCreateConsumer`. // ConsumerAdditionProposal is a governance proposal on the provider chain to @@ -44,7 +44,7 @@ message ConsumerAdditionProposal { // the proposed initial height of new consumer chain. // For a completely new chain, this will be {0,1}. However, it may be // different if this is a chain that is converting to a consumer chain. - ibc.core.client.v1.Height initial_height = 4 [ (gogoproto.nullable) = false ]; + ibc.core.client.v1.Height initial_height = 4 [(gogoproto.nullable) = false]; // The hash of the consumer chain genesis state without the consumer CCV // module genesis params. It is used for off-chain confirmation of // genesis.json validity by validators and other parties. @@ -56,19 +56,27 @@ message ConsumerAdditionProposal { // spawn time is the time on the provider chain at which the consumer chain // genesis is finalized and all validators will be responsible for starting // their consumer chain validator node. - google.protobuf.Timestamp spawn_time = 7 - [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; + google.protobuf.Timestamp spawn_time = 7 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false + ]; // Unbonding period for the consumer, // which should be smaller than that of the provider in general. - google.protobuf.Duration unbonding_period = 8 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + google.protobuf.Duration unbonding_period = 8 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // Sent CCV related IBC packets will timeout after this duration - google.protobuf.Duration ccv_timeout_period = 9 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + google.protobuf.Duration ccv_timeout_period = 9 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // Sent transfer related IBC packets will timeout after this duration - google.protobuf.Duration transfer_timeout_period = 10 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + google.protobuf.Duration transfer_timeout_period = 10 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // The fraction of tokens allocated to the consumer redistribution address // during distribution events. The fraction is a string representing a // decimal number. For example "0.75" would represent 75%. @@ -124,7 +132,6 @@ message ConsumerRemovalProposal { option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; option deprecated = true; - // the title of the proposal string title = 1; // the description of the proposal @@ -133,8 +140,10 @@ message ConsumerRemovalProposal { string chain_id = 3; // the time on the provider chain at which all validators are responsible to // stop their consumer chain validator node - google.protobuf.Timestamp stop_time = 4 - [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; + google.protobuf.Timestamp stop_time = 4 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false + ]; } // WARNING: This message is deprecated in favor of `MsgUpdateConsumer`. @@ -174,11 +183,10 @@ message ConsumerModificationProposal { bool allow_inactive_vals = 10; } - // EquivocationProposal is a governance proposal on the provider chain to // punish a validator for equivocation on a consumer chain. -// -// This type is only used internally to the consumer CCV module. +// +// This type is only used internally to the consumer CCV module. // WARNING: This message is deprecated now that equivocations can be submitted // and verified automatically on the provider. (see SubmitConsumerDoubleVoting in proto/interchain-security/ccv/provider/v1/tx.proto). message EquivocationProposal { @@ -213,10 +221,12 @@ message ChangeRewardDenomsProposal { message GlobalSlashEntry { // Block time that slash packet was received by provider chain. // This field is used for store key iteration ordering. - google.protobuf.Timestamp recv_time = 1 - [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; + google.protobuf.Timestamp recv_time = 1 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false + ]; // The consumer that sent a slash packet. - string consumer_chain_id = 2 [ (gogoproto.customname) = "ConsumerChainID" ]; + string consumer_chain_id = 2 [(gogoproto.customname) = "ConsumerChainID"]; // The IBC sequence number of the recv packet. // This field is used in the store key to ensure uniqueness. uint64 ibc_seq_num = 3; @@ -230,7 +240,6 @@ message GlobalSlashEntry { // Params defines the parameters for CCV Provider module message Params { - // Reserve 4th slot for removed init_timeout_period param reserved 4; @@ -245,12 +254,16 @@ message Params { // client's TrustingPeriod from the chain defined UnbondingPeriod string trusting_period_fraction = 2; // Sent IBC packets will timeout after this duration - google.protobuf.Duration ccv_timeout_period = 3 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + google.protobuf.Duration ccv_timeout_period = 3 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // The period for which the slash meter is replenished - google.protobuf.Duration slash_meter_replenish_period = 6 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + google.protobuf.Duration slash_meter_replenish_period = 6 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // The fraction of total voting power that is replenished to the slash meter // every replenish period. This param also serves as a maximum fraction of @@ -258,23 +271,24 @@ message Params { string slash_meter_replenish_fraction = 7; // The fee required to be paid to add a reward denom - cosmos.base.v1beta1.Coin consumer_reward_denom_registration_fee = 9 - [ (gogoproto.nullable) = false ]; + cosmos.base.v1beta1.Coin consumer_reward_denom_registration_fee = 9 [(gogoproto.nullable) = false]; // The number of blocks that comprise an epoch. int64 blocks_per_epoch = 10; // The number of epochs a validator has to validate a consumer chain in order to start receiving rewards from that chain. int64 number_of_epochs_to_start_receiving_rewards = 11; - + // The maximal number of validators that will be passed // to the consensus engine on the provider. int64 max_provider_consensus_validators = 12; } // SlashAcks contains cons addresses of consumer chain validators -// successfully slashed on the provider chain. -message SlashAcks { repeated string addresses = 1; } +// successfully slashed on the provider chain. +message SlashAcks { + repeated string addresses = 1; +} // ConsumerAdditionProposals holds pending governance proposals on the provider // chain to spawn a new chain. @@ -291,21 +305,22 @@ message ConsumerRemovalProposals { } // AddressList contains a list of consensus addresses -message AddressList { repeated bytes addresses = 1; } +message AddressList { + repeated bytes addresses = 1; +} // WARNING: This message is deprecated and is not used. // ChannelToChain is used to map a CCV channel ID to the consumer chainID message ChannelToChain { option deprecated = true; - + string channel_id = 1; string chain_id = 2; } // ValidatorSetChangePackets is a pb list of ccv.ValidatorSetChangePacketData. message ValidatorSetChangePackets { - repeated interchain_security.ccv.v1.ValidatorSetChangePacketData list = 1 - [ (gogoproto.nullable) = false ]; + repeated interchain_security.ccv.v1.ValidatorSetChangePacketData list = 1 [(gogoproto.nullable) = false]; } // @@ -340,15 +355,17 @@ message ValidatorByConsumerAddr { // ConsumerAddrsToPruneV2: (chainID, pruneTs time.Time) -> consumerAddrs AddressList message ConsumerAddrsToPruneV2 { string chain_id = 1; - google.protobuf.Timestamp prune_ts = 2 - [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; + google.protobuf.Timestamp prune_ts = 2 [ + (gogoproto.stdtime) = true, + (gogoproto.nullable) = false + ]; AddressList consumer_addrs = 3; } // ConsensusValidator is used to express a validator that -// should be validating on a chain. +// should be validating on a chain. // It contains relevant info for -// a validator that is expected to validate on +// a validator that is expected to validate on // either the provider or a consumer chain. message ConsensusValidator { // validator's consensus address on the provider chain @@ -363,13 +380,14 @@ message ConsensusValidator { // stops being a consumer validator during an epoch and later becomes again a consumer validator. int64 join_height = 4; } + // ConsumerRewardsAllocation stores the rewards allocated by a consumer chain -// to the consumer rewards pool. It is used to allocate the tokens to the consumer +// to the consumer rewards pool. It is used to allocate the tokens to the consumer // opted-in validators and the community pool during BeginBlock. message ConsumerRewardsAllocation { repeated cosmos.base.v1beta1.DecCoin rewards = 1 [ - (gogoproto.nullable) = false, - (amino.dont_omitempty) = true, + (gogoproto.nullable) = false, + (amino.dont_omitempty) = true, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins" ]; } @@ -393,7 +411,7 @@ message ConsumerInitializationParameters { // the proposed initial height of new consumer chain. // For a completely new chain, this will be {0,1}. However, it may be // different if this is a chain that is converting to a consumer chain. - ibc.core.client.v1.Height initial_height = 1 [ (gogoproto.nullable) = false ]; + ibc.core.client.v1.Height initial_height = 1 [(gogoproto.nullable) = false]; // The hash of the consumer chain genesis state without the consumer CCV // module genesis params. It is used for off-chain confirmation of // genesis.json validity by validators and other parties. @@ -405,11 +423,16 @@ message ConsumerInitializationParameters { // spawn time is the time on the provider chain at which the consumer chain // genesis is finalized and all validators will be responsible for starting // their consumer chain validator node. - google.protobuf.Timestamp spawn_time = 4 [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; + google.protobuf.Timestamp spawn_time = 4 [ + (gogoproto.nullable) = false, + (gogoproto.stdtime) = true + ]; // Unbonding period for the consumer, // which should be smaller than that of the provider in general. - google.protobuf.Duration unbonding_period = 5 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - + google.protobuf.Duration unbonding_period = 5 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // ---------- ---------- ---------- // Following fields are used to construct the consumer genesis of the to-be-launched consumer chain @@ -417,9 +440,15 @@ message ConsumerInitializationParameters { // ---------- ---------- ---------- // Sent CCV related IBC packets will timeout after this duration - google.protobuf.Duration ccv_timeout_period = 6 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + google.protobuf.Duration ccv_timeout_period = 6 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // Sent transfer related IBC packets will timeout after this duration - google.protobuf.Duration transfer_timeout_period = 7 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + google.protobuf.Duration transfer_timeout_period = 7 [ + (gogoproto.nullable) = false, + (gogoproto.stdduration) = true + ]; // The fraction of tokens allocated to the consumer redistribution address // during distribution events. The fraction is a string representing a // decimal number. For example "0.75" would represent 75%. @@ -489,11 +518,18 @@ message PowerShapingParameters { uint64 min_stake = 6; // Corresponds to whether inactive validators are allowed to validate the consumer chain. bool allow_inactive_vals = 7; + // Corresponds to a list of provider consensus addresses of validators that should have PRIORITY to validate on the consumer chain, + // meaning as long as they are eligible/opted in to validate on the consumer chain, the validator set will be + // filled with these validators first, and other validators will be added to the validator set only if there are + // not enough eligible priority validators. + repeated string prioritylist = 8; } // ConsumerIds contains consumer ids of chains // Used so we can easily (de)serialize slices of strings -message ConsumerIds { repeated string ids = 1; } +message ConsumerIds { + repeated string ids = 1; +} // ConsumerPhase indicates the phases of a consumer chain according to ADR 019 enum ConsumerPhase { @@ -517,4 +553,6 @@ enum ConsumerPhase { } // AllowlistedRewardDenoms corresponds to the denoms allowlisted by a specific consumer id -message AllowlistedRewardDenoms { repeated string denoms = 1; } \ No newline at end of file +message AllowlistedRewardDenoms { + repeated string denoms = 1; +} diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto index 910af58278..e7ce6002eb 100644 --- a/proto/interchain_security/ccv/provider/v1/query.proto +++ b/proto/interchain_security/ccv/provider/v1/query.proto @@ -196,6 +196,11 @@ message Chain { string consumer_id = 13; // the reward denoms allowlisted by this consumer chain AllowlistedRewardDenoms allowlisted_reward_denoms = 14; + // Corresponds to a list of provider consensus addresses of validators that should have PRIORITY to validate on the consumer chain, + // meaning as long as they are eligible/opted in to validate on the consumer chain, the validator set will be + // filled with these validators first, and other validators will be added to the validator set only if there are + // not enough eligible priority validators. + repeated string prioritylist = 15; } message QueryValidatorConsumerAddrRequest { diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 06bc94c6af..f43bf0bc5e 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -289,6 +289,7 @@ type PowerShapingParameters struct { Denylist []string MinStake uint64 AllowInactiveVals bool + Prioritylist []string } func (tr Chain) updateConsumerChain(action UpdateConsumerChainAction, verbose bool) { @@ -320,6 +321,7 @@ func (tr Chain) updateConsumerChain(action UpdateConsumerChainAction, verbose bo Denylist: action.PowerShapingParams.Denylist, MinStake: action.PowerShapingParams.MinStake, AllowInactiveVals: action.PowerShapingParams.AllowInactiveVals, + Prioritylist: action.PowerShapingParams.Prioritylist, } consumerId := tr.testConfig.chainConfigs[action.ConsumerChain].ConsumerId @@ -376,6 +378,7 @@ func (tr Chain) createConsumerChain(action CreateConsumerChainAction, verbose bo Denylist: action.PowerShapingParams.Denylist, MinStake: action.PowerShapingParams.MinStake, AllowInactiveVals: action.PowerShapingParams.AllowInactiveVals, + Prioritylist: action.PowerShapingParams.Prioritylist, } metadata := types.ConsumerMetadata{ @@ -463,6 +466,7 @@ type SubmitConsumerAdditionProposalAction struct { Denylist []string MinStake uint64 AllowInactiveVals bool + Prioritylist []string } func (tr Chain) UpdateConsumer(providerChain ChainID, validator ValidatorID, update types.MsgUpdateConsumer, verbose bool) { @@ -657,6 +661,7 @@ func (tr Chain) submitConsumerAdditionProposal( Denylist: action.Denylist, MinStake: action.MinStake, AllowInactiveVals: action.AllowInactiveVals, + Prioritylist: action.Prioritylist, } update.PowerShapingParameters = &powerShapingParameters tr.UpdateConsumer(action.Chain, action.From, *update, verbose) @@ -757,6 +762,7 @@ func (tr Chain) submitConsumerAdditionLegacyProposal( Denylist: action.Denylist, MinStake: action.MinStake, AllowInactiveVals: action.AllowInactiveVals, + Prioritylist: action.Prioritylist, } bz, err := json.Marshal(prop) @@ -937,6 +943,7 @@ type SubmitConsumerModificationProposalAction struct { AllowInactiveVals bool MinStake uint64 NewOwner string + Prioritylist []string } func (tr Chain) submitConsumerModificationProposal( @@ -962,6 +969,7 @@ func (tr Chain) submitConsumerModificationProposal( ValidatorSetCap: action.ValidatorSetCap, Allowlist: action.Allowlist, Denylist: action.Denylist, + Prioritylist: action.Prioritylist, }, } @@ -1019,6 +1027,7 @@ func (tr Chain) submitConsumerModificationLegacyProposal( ValidatorSetCap: action.ValidatorSetCap, Allowlist: action.Allowlist, Denylist: action.Denylist, + Prioritylist: action.Prioritylist, } bz, err := json.Marshal(prop) diff --git a/tests/e2e/main.go b/tests/e2e/main.go index 7b066a2020..e8e3e0640a 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -192,6 +192,12 @@ var stepChoices = map[string]StepChoice{ description: "test partial set security for an Opt-In chain that has a validator denylisted", testConfig: DefaultTestCfg, }, + "partial-set-security-validators-prioritylisted": { + name: "partial-set-security-validators-prioritylisted", + steps: stepsValidatorsPrioritylistedChain(), + description: "test partial set security for an Opt-In chain that has has some validators prioritylisted", + testConfig: DefaultTestCfg, + }, "partial-set-security-modification-proposal": { name: "partial-set-security-modification-proposal", steps: stepsModifyChain(), @@ -360,6 +366,7 @@ func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet, providerVe "partial-set-security-validators-power-cap", "partial-set-security-validators-allowlisted", "partial-set-security-validators-denylisted", + "partial-set-security-validators-prioritylisted", "partial-set-security-modification-proposal", "active-set-changes", "inactive-provider-validators-on-consumer", diff --git a/tests/e2e/steps_partial_set_security.go b/tests/e2e/steps_partial_set_security.go index 6b23d675c2..06d41bf4d9 100644 --- a/tests/e2e/steps_partial_set_security.go +++ b/tests/e2e/steps_partial_set_security.go @@ -1840,6 +1840,190 @@ func stepsValidatorsDenylistedChain() []Step { return s } +// stepsValidatorsPrioritylistedChain starts a provider chain and an Opt-In chain with an prioritylist +func stepsValidatorsPrioritylistedChain() []Step { + s := []Step{ + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: CreateConsumerChainAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + ConsumerChain: ChainID("consu"), + InitParams: &InitializationParameters{ + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + SpawnTime: uint(time.Minute * 10), + }, + PowerShapingParams: &PowerShapingParameters{ + TopN: 0, + ValidatorSetCap: 2, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ProposedConsumerChains: &[]string{"consu"}, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: UpdateConsumerChainAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + ConsumerChain: ChainID("consu"), + InitParams: &InitializationParameters{ + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + SpawnTime: 0, + }, + PowerShapingParams: &PowerShapingParameters{ + TopN: 0, + ValidatorSetCap: 2, + Prioritylist: []string{ + "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", //alice + }, + }, + }, + State: State{}, + }, + { + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 0, // Bob is not in the validator set due to ValidatorSetCap and priority list + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 0, + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + } + + return s +} + // stepsModifyChain issues multiple `ConsumerModificationProposal`s on a consumer chain to assert that indeed // partial-set security parameters can be changed. func stepsModifyChain() []Step { diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index 929ce7be30..b6038025ed 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -309,6 +309,7 @@ func GetTestPowerShapingParameters() providertypes.PowerShapingParameters { Denylist: nil, MinStake: 0, AllowInactiveVals: false, + Prioritylist: nil, } } diff --git a/x/ccv/provider/client/cli/tx.go b/x/ccv/provider/client/cli/tx.go index ec694fd49e..52a53f3ebe 100644 --- a/x/ccv/provider/client/cli/tx.go +++ b/x/ccv/provider/client/cli/tx.go @@ -254,7 +254,8 @@ where create_consumer.json has the following structure: "allowlist": ["cosmosvalcons..."], "denylist": ["cosmosvalcons..."], "min_stake": 0, - "allow_inactive_vals": false + "allow_inactive_vals": false, + "prioritylist": ["cosmosvalcons..."] }, "allowlisted_reward_denoms": { "denoms": ["ibc/...", "ibc/..."] @@ -352,7 +353,8 @@ where update_consumer.json has the following structure: "allowlist": ["cosmosvalcons..."], "denylist": ["cosmosvalcons..."], "min_stake": 0, - "allow_inactive_vals": false + "allow_inactive_vals": false, + "prioritylist": ["cosmosvalcons..."] }, "allowlisted_reward_denoms": { "denoms": ["ibc/...", "ibc/..."] diff --git a/x/ccv/provider/client/legacy_proposals.go b/x/ccv/provider/client/legacy_proposals.go index af96ec054b..8993ad9e73 100644 --- a/x/ccv/provider/client/legacy_proposals.go +++ b/x/ccv/provider/client/legacy_proposals.go @@ -43,6 +43,7 @@ type ConsumerAdditionProposalJSON struct { Denylist []string `json:"denylist"` MinStake uint64 `json:"min_stake"` AllowInactiveVals bool `json:"allow_inactive_vals"` + Prioritylist []string `json:"prioritylist"` } type ConsumerAdditionProposalReq struct { @@ -176,6 +177,7 @@ type ConsumerModificationProposalJSON struct { Denylist []string `json:"denylist"` MinStake uint64 `json:"min_stake"` AllowInactiveVals bool `json:"allow_inactive_vals"` + Prioritylist []string `json:"prioritylist"` Deposit string `json:"deposit"` } diff --git a/x/ccv/provider/keeper/consumer_lifecycle.go b/x/ccv/provider/keeper/consumer_lifecycle.go index 7bde45df8a..51d2120f89 100644 --- a/x/ccv/provider/keeper/consumer_lifecycle.go +++ b/x/ccv/provider/keeper/consumer_lifecycle.go @@ -486,6 +486,7 @@ func (k Keeper) DeleteConsumerChain(ctx sdk.Context, consumerId string) (err err k.DeleteDenylist(ctx, consumerId) k.DeleteAllOptedIn(ctx, consumerId) k.DeleteConsumerValSet(ctx, consumerId) + k.DeletePrioritylist(ctx, consumerId) k.DeleteConsumerRemovalTime(ctx, consumerId) diff --git a/x/ccv/provider/keeper/consumer_lifecycle_test.go b/x/ccv/provider/keeper/consumer_lifecycle_test.go index 200c2b949f..f90c359e4c 100644 --- a/x/ccv/provider/keeper/consumer_lifecycle_test.go +++ b/x/ccv/provider/keeper/consumer_lifecycle_test.go @@ -226,6 +226,7 @@ func TestBeginBlockLaunchConsumers(t *testing.T) { ValidatorSetCap: 0, Allowlist: []string{}, Denylist: []string{}, + Prioritylist: []string{}, }, { Top_N: 50, @@ -233,6 +234,7 @@ func TestBeginBlockLaunchConsumers(t *testing.T) { ValidatorSetCap: 0, Allowlist: []string{}, Denylist: []string{}, + Prioritylist: []string{}, }, { Top_N: 50, @@ -240,6 +242,7 @@ func TestBeginBlockLaunchConsumers(t *testing.T) { ValidatorSetCap: 0, Allowlist: []string{}, Denylist: []string{}, + Prioritylist: []string{}, }, { Top_N: 0, @@ -247,6 +250,7 @@ func TestBeginBlockLaunchConsumers(t *testing.T) { ValidatorSetCap: 0, Allowlist: []string{}, Denylist: []string{}, + Prioritylist: []string{}, }, { Top_N: 0, @@ -254,6 +258,7 @@ func TestBeginBlockLaunchConsumers(t *testing.T) { ValidatorSetCap: 0, Allowlist: []string{}, Denylist: []string{}, + Prioritylist: []string{}, }, } diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go index 9a16e8c5f9..dfc6b06501 100644 --- a/x/ccv/provider/keeper/grpc_query.go +++ b/x/ccv/provider/keeper/grpc_query.go @@ -114,6 +114,12 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, consumerId string) (types.Chai strDenylist[i] = addr.String() } + prioritylist := k.GetPriorityList(ctx, consumerId) + strPrioritylist := make([]string, len(prioritylist)) + for i, addr := range prioritylist { + strPrioritylist[i] = addr.String() + } + metadata, err := k.GetConsumerMetadata(ctx, consumerId) if err != nil { return types.Chain{}, fmt.Errorf("cannot find metadata (%s): %s", consumerId, err.Error()) @@ -139,6 +145,7 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, consumerId string) (types.Chai MinStake: powerShapingParameters.MinStake, ConsumerId: consumerId, AllowlistedRewardDenoms: &types.AllowlistedRewardDenoms{Denoms: allowlistedRewardDenoms}, + Prioritylist: strPrioritylist, }, nil } diff --git a/x/ccv/provider/keeper/grpc_query_test.go b/x/ccv/provider/keeper/grpc_query_test.go index a8fe617f53..5f664a331a 100644 --- a/x/ccv/provider/keeper/grpc_query_test.go +++ b/x/ccv/provider/keeper/grpc_query_test.go @@ -451,7 +451,12 @@ func TestGetConsumerChain(t *testing.T) { {types.NewProviderConsAddress([]byte("providerAddr6"))}, {}, } - + prioritylists := [][]types.ProviderConsAddress{ + {}, + {types.NewProviderConsAddress([]byte("providerAddr1")), types.NewProviderConsAddress([]byte("providerAddr2"))}, + {types.NewProviderConsAddress([]byte("providerAddr3"))}, + {}, + } allowInactiveVals := []bool{true, false, true, false} minStakes := []math.Int{ @@ -490,6 +495,9 @@ func TestGetConsumerChain(t *testing.T) { for _, addr := range denylists[i] { pk.SetDenylist(ctx, consumerID, addr) } + for _, addr := range prioritylists[i] { + pk.SetPrioritylist(ctx, consumerID, addr) + } strAllowlist := make([]string, len(allowlists[i])) for j, addr := range allowlists[i] { strAllowlist[j] = addr.String() @@ -500,6 +508,11 @@ func TestGetConsumerChain(t *testing.T) { strDenylist[j] = addr.String() } + strPrioritylist := make([]string, len(prioritylists[i])) + for j, addr := range prioritylists[i] { + strPrioritylist[j] = addr.String() + } + metadataLists = append(metadataLists, types.ConsumerMetadata{Name: chainIDs[i]}) pk.SetConsumerMetadata(ctx, consumerID, metadataLists[i]) @@ -524,6 +537,7 @@ func TestGetConsumerChain(t *testing.T) { MinStake: minStakes[i].Uint64(), ConsumerId: consumerIDs[i], AllowlistedRewardDenoms: allowlistedRewardDenoms[i], + Prioritylist: strPrioritylist, }) } @@ -674,6 +688,7 @@ func TestQueryConsumerChains(t *testing.T) { Metadata: metadata, ConsumerId: consumerId, AllowlistedRewardDenoms: &types.AllowlistedRewardDenoms{Denoms: []string{}}, + Prioritylist: []string{}, } consumerIds[i] = consumerId consumers[i] = &c diff --git a/x/ccv/provider/keeper/power_shaping.go b/x/ccv/provider/keeper/power_shaping.go index 87624922b0..1c789ce30f 100644 --- a/x/ccv/provider/keeper/power_shaping.go +++ b/x/ccv/provider/keeper/power_shaping.go @@ -88,7 +88,7 @@ func (k Keeper) UpdateMinimumPowerInTopN(ctx sdk.Context, consumerId string, old } // CapValidatorSet caps the provided `validators` if chain with `consumerId` is an Opt In chain with a validator-set cap. -// If cap is `k`, `CapValidatorSet` returns the first `k` validators from `validators` with the highest power. +// If cap is `k`, `CapValidatorSet` returns the first `k` validators from `validators`. func (k Keeper) CapValidatorSet( ctx sdk.Context, powerShapingParameters types.PowerShapingParameters, @@ -101,10 +101,7 @@ func (k Keeper) CapValidatorSet( validatorSetCap := powerShapingParameters.ValidatorSetCap if validatorSetCap != 0 && int(validatorSetCap) < len(validators) { - sort.Slice(validators, func(i, j int) bool { - return validators[i].Power > validators[j].Power - }) - + // validators are already sorted by priority and power return validators[:int(validatorSetCap)] } else { return validators @@ -337,13 +334,16 @@ func (k Keeper) SetConsumerPowerShapingParameters(ctx sdk.Context, consumerId st store.Set(types.ConsumerIdToPowerShapingParametersKey(consumerId), bz) - // update allowlist and denylist indexes if needed + // update allowlist, denylist and prioritylist indexes if needed if !equalStringSlices(oldParameters.Allowlist, parameters.Allowlist) { k.UpdateAllowlist(ctx, consumerId, parameters.Allowlist) } if !equalStringSlices(oldParameters.Denylist, parameters.Denylist) { k.UpdateDenylist(ctx, consumerId, parameters.Denylist) } + if !equalStringSlices(oldParameters.Prioritylist, parameters.Prioritylist) { + k.UpdatePrioritylist(ctx, consumerId, parameters.Prioritylist) + } return nil } @@ -551,3 +551,107 @@ func (k Keeper) DeleteMinimumPowerInTopN( store := ctx.KVStore(k.storeKey) store.Delete(types.MinimumPowerInTopNKey(consumerId)) } + +// SetPrioritylist prioritylists validator with `providerAddr` address on chain `consumerId` +func (k Keeper) SetPrioritylist( + ctx sdk.Context, + consumerId string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.PrioritylistKey(consumerId, providerAddr), []byte{}) +} + +// GetPriorityList returns all prioritylisted validators +func (k Keeper) GetPriorityList( + ctx sdk.Context, + consumerId string, +) (providerConsAddresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.StringIdWithLenKey(types.PrioritylistKeyPrefix(), consumerId) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerConsAddresses = append(providerConsAddresses, types.NewProviderConsAddress(iterator.Key()[len(key):])) + } + + return providerConsAddresses +} + +// IsPrioritylisted returns `true` if validator with `providerAddr` has been prioritylisted on chain `consumerId` +func (k Keeper) IsPrioritylisted( + ctx sdk.Context, + consumerId string, + providerAddr types.ProviderConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + return store.Get(types.PrioritylistKey(consumerId, providerAddr)) != nil +} + +// DeletePrioritylist deletes all prioritylisted validators +func (k Keeper) DeletePrioritylist(ctx sdk.Context, consumerId string) { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.StringIdWithLenKey(types.PrioritylistKeyPrefix(), consumerId)) + defer iterator.Close() + + keysToDel := [][]byte{} + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + + for _, key := range keysToDel { + store.Delete(key) + } +} + +// IsPrioritylistEmpty returns `true` if no validator is prioritylisted on chain `consumerId` +func (k Keeper) IsPrioritylistEmpty(ctx sdk.Context, consumerId string) bool { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.StringIdWithLenKey(types.PrioritylistKeyPrefix(), consumerId)) + defer iterator.Close() + + return !iterator.Valid() +} + +// UpdatePrioritylist populates the prioritylist store for the consumer chain with this consumer id +func (k Keeper) UpdatePrioritylist(ctx sdk.Context, consumerId string, prioritylist []string) { + k.DeletePrioritylist(ctx, consumerId) + for _, address := range prioritylist { + consAddr, err := sdk.ConsAddressFromBech32(address) + if err != nil { + continue + } + + k.SetPrioritylist(ctx, consumerId, types.NewProviderConsAddress(consAddr)) + } +} + +// PartitionBasedOnPriorityList filters the priority list to include only validators that can validate the chain +// and splits the validators into priority and non-priority sets. +func (k Keeper) PartitionBasedOnPriorityList(ctx sdk.Context, consumerId string, nextValidators []types.ConsensusValidator) ([]types.ConsensusValidator, []types.ConsensusValidator) { + + priorityValidators := make([]types.ConsensusValidator, 0) + nonPriorityValidators := make([]types.ConsensusValidator, 0) + + // Form priorityValidators + for _, validator := range nextValidators { + addr := types.NewProviderConsAddress(validator.ProviderConsAddr) + if k.IsPrioritylisted(ctx, consumerId, addr) { + priorityValidators = append(priorityValidators, validator) + } else { + // Add remaining validators to nonPriorityValidators + nonPriorityValidators = append(nonPriorityValidators, validator) + } + } + + sort.Slice(priorityValidators, func(i, j int) bool { + return priorityValidators[i].Power > priorityValidators[j].Power + }) + + sort.Slice(nonPriorityValidators, func(i, j int) bool { + return nonPriorityValidators[i].Power > nonPriorityValidators[j].Power + }) + + return priorityValidators, nonPriorityValidators +} diff --git a/x/ccv/provider/keeper/power_shaping_test.go b/x/ccv/provider/keeper/power_shaping_test.go index b0853588ee..20358db3f4 100644 --- a/x/ccv/provider/keeper/power_shaping_test.go +++ b/x/ccv/provider/keeper/power_shaping_test.go @@ -250,74 +250,134 @@ func TestCapValidatorSet(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - validatorA := providertypes.ConsensusValidator{ - ProviderConsAddr: []byte("providerConsAddrA"), - Power: 1, - PublicKey: &crypto.PublicKey{}, - } - - validatorB := providertypes.ConsensusValidator{ - ProviderConsAddr: []byte("providerConsAddrB"), - Power: 2, - PublicKey: &crypto.PublicKey{}, - } - - validatorC := providertypes.ConsensusValidator{ - ProviderConsAddr: []byte("providerConsAddrC"), - Power: 3, - PublicKey: &crypto.PublicKey{}, - } - validators := []providertypes.ConsensusValidator{validatorA, validatorB, validatorC} + valAddrA := "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + valAddrB := "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39" + valAddrC := "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq" + valAddrD := "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + + validatorA := providertypes.ConsensusValidator{ProviderConsAddr: consAddressFromBech32(valAddrA), Power: 1, PublicKey: &crypto.PublicKey{}} + validatorB := providertypes.ConsensusValidator{ProviderConsAddr: consAddressFromBech32(valAddrB), Power: 2, PublicKey: &crypto.PublicKey{}} + validatorC := providertypes.ConsensusValidator{ProviderConsAddr: consAddressFromBech32(valAddrC), Power: 3, PublicKey: &crypto.PublicKey{}} + validatorD := providertypes.ConsensusValidator{ProviderConsAddr: consAddressFromBech32(valAddrD), Power: 4, PublicKey: &crypto.PublicKey{}} + validators := []providertypes.ConsensusValidator{validatorA, validatorB, validatorC, validatorD} + // Initial error check powerShapingParameters, err := providerKeeper.GetConsumerPowerShapingParameters(ctx, CONSUMER_ID) require.Error(t, err) - consumerValidators := providerKeeper.CapValidatorSet(ctx, powerShapingParameters, validators) - require.Equal(t, validators, consumerValidators) - - err = providerKeeper.SetConsumerPowerShapingParameters(ctx, CONSUMER_ID, providertypes.PowerShapingParameters{ - ValidatorSetCap: 0, - }) - require.NoError(t, err) - powerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, CONSUMER_ID) - require.NoError(t, err) - consumerValidators = providerKeeper.CapValidatorSet(ctx, powerShapingParameters, validators) - require.Equal(t, validators, consumerValidators) + priorityValidators, nonPriorityValidators := providerKeeper.PartitionBasedOnPriorityList(ctx, CONSUMER_ID, validators) + consumerValidators := providerKeeper.CapValidatorSet(ctx, powerShapingParameters, append(priorityValidators, nonPriorityValidators...)) + require.Equal(t, []providertypes.ConsensusValidator{validatorD, validatorC, validatorB, validatorA}, consumerValidators) - err = providerKeeper.SetConsumerPowerShapingParameters(ctx, CONSUMER_ID, providertypes.PowerShapingParameters{ - ValidatorSetCap: 100, - }) - require.NoError(t, err) - powerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, CONSUMER_ID) - require.NoError(t, err) - consumerValidators = providerKeeper.CapValidatorSet(ctx, powerShapingParameters, validators) - require.Equal(t, validators, consumerValidators) + testCases := []struct { + name string + powerShapingParameters providertypes.PowerShapingParameters + expectedValidators []providertypes.ConsensusValidator + expectError bool + }{ + { + name: "ValidatorSetCap = 0 (no capping)", + powerShapingParameters: providertypes.PowerShapingParameters{ValidatorSetCap: 0}, + expectedValidators: []providertypes.ConsensusValidator{validatorD, validatorC, validatorB, validatorA}, + }, + { + name: "ValidatorSetCap = 0, with priority list", + powerShapingParameters: providertypes.PowerShapingParameters{ + ValidatorSetCap: 0, + Prioritylist: []string{ + valAddrA, + valAddrB, + }, + }, + expectedValidators: []providertypes.ConsensusValidator{validatorB, validatorA, validatorD, validatorC}, + }, + { + name: "ValidatorSetCap > len(validators) (no capping)", + powerShapingParameters: providertypes.PowerShapingParameters{ValidatorSetCap: 100}, + expectedValidators: []providertypes.ConsensusValidator{validatorD, validatorC, validatorB, validatorA}, + }, + { + name: "ValidatorSetCap = 1 (capping to highest power, no priority list)", + powerShapingParameters: providertypes.PowerShapingParameters{ValidatorSetCap: 1}, + expectedValidators: []providertypes.ConsensusValidator{validatorD}, + }, + { + name: "ValidatorSetCap = 2 (capping to two highest power, no priority list)", + powerShapingParameters: providertypes.PowerShapingParameters{ValidatorSetCap: 2}, + expectedValidators: []providertypes.ConsensusValidator{validatorD, validatorC}, + }, + { + name: "ValidatorSetCap = 3 (capping to three highest power, no priority list)", + powerShapingParameters: providertypes.PowerShapingParameters{ValidatorSetCap: 3}, + expectedValidators: []providertypes.ConsensusValidator{validatorD, validatorC, validatorB}, + }, + { + name: "ValidatorSetCap = 2, with priority list", + powerShapingParameters: providertypes.PowerShapingParameters{ + ValidatorSetCap: 2, + Prioritylist: []string{ + valAddrA, + valAddrB, + }, + }, + expectedValidators: []providertypes.ConsensusValidator{validatorB, validatorA}, + }, + { + name: "ValidatorSetCap = 3, with partial priority list", + powerShapingParameters: providertypes.PowerShapingParameters{ + ValidatorSetCap: 3, + Prioritylist: []string{valAddrA}, + }, + expectedValidators: []providertypes.ConsensusValidator{validatorA, validatorD, validatorC}, + }, + { + name: "All validators in priority list", + powerShapingParameters: providertypes.PowerShapingParameters{ + ValidatorSetCap: 4, + Prioritylist: []string{ + valAddrC, + valAddrA, + valAddrD, + valAddrB, + }, + }, + expectedValidators: []providertypes.ConsensusValidator{validatorD, validatorC, validatorB, validatorA}, + }, + { + name: "ValidatorSetCap = 1 (capping to highest power, with priority list)", + powerShapingParameters: providertypes.PowerShapingParameters{ + ValidatorSetCap: 1, + Prioritylist: []string{valAddrA}, + }, + expectedValidators: []providertypes.ConsensusValidator{validatorA}, + }, + } - err = providerKeeper.SetConsumerPowerShapingParameters(ctx, CONSUMER_ID, providertypes.PowerShapingParameters{ - ValidatorSetCap: 1, - }) - require.NoError(t, err) - powerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, CONSUMER_ID) - require.NoError(t, err) - consumerValidators = providerKeeper.CapValidatorSet(ctx, powerShapingParameters, validators) - require.Equal(t, []providertypes.ConsensusValidator{validatorC}, consumerValidators) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := providerKeeper.SetConsumerPowerShapingParameters(ctx, CONSUMER_ID, tc.powerShapingParameters) + require.NoError(t, err) - err = providerKeeper.SetConsumerPowerShapingParameters(ctx, CONSUMER_ID, providertypes.PowerShapingParameters{ - ValidatorSetCap: 2, - }) - require.NoError(t, err) - powerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, CONSUMER_ID) - require.NoError(t, err) - consumerValidators = providerKeeper.CapValidatorSet(ctx, powerShapingParameters, validators) - require.Equal(t, []providertypes.ConsensusValidator{validatorC, validatorB}, consumerValidators) + powerShapingParameters, err := providerKeeper.GetConsumerPowerShapingParameters(ctx, CONSUMER_ID) + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.powerShapingParameters, powerShapingParameters) + } + priorityValidators, nonPriorityValidators := providerKeeper.PartitionBasedOnPriorityList(ctx, CONSUMER_ID, validators) + consumerValidators := providerKeeper.CapValidatorSet(ctx, powerShapingParameters, append(priorityValidators, nonPriorityValidators...)) + require.Equal(t, tc.expectedValidators, consumerValidators) + }) + } +} - err = providerKeeper.SetConsumerPowerShapingParameters(ctx, CONSUMER_ID, providertypes.PowerShapingParameters{ - ValidatorSetCap: 3, - }) - require.NoError(t, err) - powerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, CONSUMER_ID) - require.NoError(t, err) - consumerValidators = providerKeeper.CapValidatorSet(ctx, powerShapingParameters, validators) - require.Equal(t, []providertypes.ConsensusValidator{validatorC, validatorB, validatorA}, consumerValidators) +// Helper function to handle address conversion +func consAddressFromBech32(addr string) sdk.ConsAddress { + consAddr, err := sdk.ConsAddressFromBech32(addr) + if err != nil { + panic(fmt.Sprintf("invalid consensus address: %s", addr)) + } + return consAddr } func TestCapValidatorsPower(t *testing.T) { @@ -745,11 +805,14 @@ func TestConsumerPowerShapingParameters(t *testing.T) { Denylist: []string{consAddrs[2], consAddrs[3]}, MinStake: 234, AllowInactiveVals: true, + Prioritylist: []string{consAddrs[1]}, } expectedAllowlist := []providertypes.ProviderConsAddress{providerConsAddr[0], providerConsAddr[1]} sortProviderConsAddr(expectedAllowlist) expectedDenylist := []providertypes.ProviderConsAddress{providerConsAddr[2], providerConsAddr[3]} sortProviderConsAddr(expectedDenylist) + expectedPrioritylist := []providertypes.ProviderConsAddress{providerConsAddr[1]} + sortProviderConsAddr(expectedPrioritylist) err = providerKeeper.SetConsumerPowerShapingParameters(ctx, consumerId, expectedPowerShapingParameters) require.NoError(t, err) actualPowerShapingParameters, err := providerKeeper.GetConsumerPowerShapingParameters(ctx, consumerId) @@ -757,6 +820,7 @@ func TestConsumerPowerShapingParameters(t *testing.T) { require.Equal(t, expectedPowerShapingParameters, actualPowerShapingParameters) require.Equal(t, expectedAllowlist, providerKeeper.GetAllowList(ctx, consumerId)) require.Equal(t, expectedDenylist, providerKeeper.GetDenyList(ctx, consumerId)) + require.Equal(t, expectedPrioritylist, providerKeeper.GetPriorityList(ctx, consumerId)) // assert that overwriting the current initialization record works expectedPowerShapingParameters = providertypes.PowerShapingParameters{ @@ -767,11 +831,14 @@ func TestConsumerPowerShapingParameters(t *testing.T) { Denylist: []string{consAddrs[2], consAddrs[3]}, MinStake: 567, AllowInactiveVals: false, + Prioritylist: []string{consAddrs[4], consAddrs[5]}, } expectedAllowlist = []providertypes.ProviderConsAddress{providerConsAddr[4], providerConsAddr[5]} sortProviderConsAddr(expectedAllowlist) expectedDenylist = []providertypes.ProviderConsAddress{providerConsAddr[2], providerConsAddr[3]} sortProviderConsAddr(expectedDenylist) + expectedPrioritylist = []providertypes.ProviderConsAddress{providerConsAddr[4], providerConsAddr[5]} + sortProviderConsAddr(expectedAllowlist) err = providerKeeper.SetConsumerPowerShapingParameters(ctx, consumerId, expectedPowerShapingParameters) require.NoError(t, err) actualPowerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, consumerId) @@ -779,6 +846,7 @@ func TestConsumerPowerShapingParameters(t *testing.T) { require.Equal(t, expectedPowerShapingParameters, actualPowerShapingParameters) require.Equal(t, expectedAllowlist, providerKeeper.GetAllowList(ctx, consumerId)) require.Equal(t, expectedDenylist, providerKeeper.GetDenyList(ctx, consumerId)) + require.Equal(t, expectedPrioritylist, providerKeeper.GetPriorityList(ctx, consumerId)) } // TestAllowlist tests the `SetAllowlist`, `IsAllowlisted`, `DeleteAllowlist`, and `IsAllowlistEmpty` methods @@ -1006,3 +1074,50 @@ func TestUpdateMinimumPowerInTopN(t *testing.T) { require.True(t, found) require.Equal(t, int64(10), minimumPowerInTopN) } + +func TestPrioritylist(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerID := CONSUMER_ID + + // no validator was prioritylisted and hence the prioritylist is empty + require.True(t, providerKeeper.IsPrioritylistEmpty(ctx, consumerID)) + + providerAddr1 := providertypes.NewProviderConsAddress([]byte("providerAddr1")) + providerKeeper.SetPrioritylist(ctx, consumerID, providerAddr1) + require.True(t, providerKeeper.IsPrioritylisted(ctx, consumerID, providerAddr1)) + + // prioritylist is not empty anymore + require.False(t, providerKeeper.IsPrioritylistEmpty(ctx, consumerID)) + + providerAddr2 := providertypes.NewProviderConsAddress([]byte("providerAddr2")) + providerKeeper.SetPrioritylist(ctx, consumerID, providerAddr2) + require.True(t, providerKeeper.IsPrioritylisted(ctx, consumerID, providerAddr2)) + require.False(t, providerKeeper.IsPrioritylistEmpty(ctx, consumerID)) + + providerKeeper.DeletePrioritylist(ctx, consumerID) + require.False(t, providerKeeper.IsPrioritylisted(ctx, consumerID, providerAddr1)) + require.False(t, providerKeeper.IsPrioritylisted(ctx, consumerID, providerAddr2)) + require.True(t, providerKeeper.IsPrioritylistEmpty(ctx, consumerID)) +} + +func TestUpdatePrioritylist(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + consumerId := "0" + + providerConsAddr1 := "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq" + consAddr1, _ := sdk.ConsAddressFromBech32(providerConsAddr1) + providerConsAddr2 := "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39" + consAddr2, _ := sdk.ConsAddressFromBech32(providerConsAddr2) + + providerKeeper.UpdatePrioritylist(ctx, consumerId, []string{providerConsAddr1, providerConsAddr2}) + + expectedPrioritylist := []providertypes.ProviderConsAddress{ + providertypes.NewProviderConsAddress(consAddr1), + providertypes.NewProviderConsAddress(consAddr2), + } + require.Equal(t, expectedPrioritylist, providerKeeper.GetPriorityList(ctx, consumerId)) +} diff --git a/x/ccv/provider/keeper/validator_set_update.go b/x/ccv/provider/keeper/validator_set_update.go index d375d42d8f..265911d5d2 100644 --- a/x/ccv/provider/keeper/validator_set_update.go +++ b/x/ccv/provider/keeper/validator_set_update.go @@ -233,7 +233,9 @@ func (k Keeper) ComputeNextValidators( return []types.ConsensusValidator{}, err } - nextValidators = k.CapValidatorSet(ctx, powerShapingParameters, nextValidators) + priorityValidators, nonPriorityValidators := k.PartitionBasedOnPriorityList(ctx, consumerId, nextValidators) + + nextValidators = k.CapValidatorSet(ctx, powerShapingParameters, append(priorityValidators, nonPriorityValidators...)) nextValidators = k.CapValidatorsPower(ctx, powerShapingParameters.ValidatorsPowerCap, nextValidators) diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index ca78611fd8..2e712b3e6e 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -154,6 +154,8 @@ const ( ConsumerIdToAllowlistedRewardDenomKeyName = "ConsumerIdToAllowlistedRewardDenomKey" ConsumerRewardsAllocationByDenomKeyName = "ConsumerRewardsAllocationByDenomKey" + + PrioritylistKeyName = "PrioritylistKey" ) // getKeyPrefixes returns a constant map of all the byte prefixes for existing keys @@ -391,6 +393,10 @@ func getKeyPrefixes() map[string]byte { // ConsumerRewardsAllocationByDenomKeyName is the key for storing the consumer rewards for a specific consumer chain and denom ConsumerRewardsAllocationByDenomKeyName: 55, + // PrioritylistKey is the key for storing the mapping from a consumer chain to the set of validators that are + // prioritylisted. + PrioritylistKeyName: 56, + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO TestPreserveBytePrefix() IN keys_test.go } } @@ -597,6 +603,16 @@ func DenylistKey(consumerId string, providerAddr ProviderConsAddress) []byte { return StringIdAndConsAddrKey(DenylistKeyPrefix(), consumerId, providerAddr.ToSdkConsAddr()) } +// PrioritylistKeyPrefix returns the key prefix for storing consumer chains prioritylists +func PrioritylistKeyPrefix() byte { + return mustGetKeyPrefix(PrioritylistKeyName) +} + +// PrioritylistKey returns the key for storing consumer chains prioritylists +func PrioritylistKey(consumerId string, providerAddr ProviderConsAddress) []byte { + return StringIdAndConsAddrKey(PrioritylistKeyPrefix(), consumerId, providerAddr.ToSdkConsAddr()) +} + // OptedInKeyPrefix returns the key prefix for storing whether a validator is opted in on a consumer chain. func OptedInKeyPrefix() byte { return mustGetKeyPrefix(OptedInKeyName) diff --git a/x/ccv/provider/types/keys_test.go b/x/ccv/provider/types/keys_test.go index 814ece665a..de8156c8ec 100644 --- a/x/ccv/provider/types/keys_test.go +++ b/x/ccv/provider/types/keys_test.go @@ -147,6 +147,8 @@ func TestPreserveBytePrefix(t *testing.T) { i++ require.Equal(t, byte(55), providertypes.ConsumerRewardsAllocationByDenomKey("13", "denom")[0]) i++ + require.Equal(t, byte(56), providertypes.PrioritylistKeyPrefix()) + i++ prefixes := providertypes.GetAllKeyPrefixes() require.Equal(t, len(prefixes), i) @@ -216,6 +218,7 @@ func getAllFullyDefinedKeys() [][]byte { providertypes.ClientIdToConsumerIdKey("clientId"), providertypes.ConsumerIdToAllowlistedRewardDenomKey("13"), providertypes.ConsumerRewardsAllocationByDenomKey("13", "denom"), + providertypes.PrioritylistKey("13", providertypes.NewProviderConsAddress([]byte{0x05})), } } diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index acfdf1bd8b..91a5282c4f 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -529,6 +529,9 @@ func ValidatePowerShapingParameters(powerShapingParameters PowerShapingParameter if err := ValidateConsAddressList(powerShapingParameters.Denylist, MaxValidatorCount); err != nil { return errorsmod.Wrapf(ErrInvalidPowerShapingParameters, "Denylist: %s", err.Error()) } + if err := ValidateConsAddressList(powerShapingParameters.Prioritylist, MaxValidatorCount); err != nil { + return errorsmod.Wrapf(ErrInvalidPowerShapingParameters, "Prioritylist: %s", err.Error()) + } return nil } diff --git a/x/ccv/provider/types/msg_test.go b/x/ccv/provider/types/msg_test.go index b0f0f11102..f1eaa3124a 100644 --- a/x/ccv/provider/types/msg_test.go +++ b/x/ccv/provider/types/msg_test.go @@ -502,6 +502,7 @@ func TestMsgUpdateConsumerValidateBasic(t *testing.T) { Denylist: nil, MinStake: 0, AllowInactiveVals: false, + Prioritylist: []string{consAddr1}, }, true, }, @@ -513,6 +514,7 @@ func TestMsgUpdateConsumerValidateBasic(t *testing.T) { ValidatorSetCap: 0, Allowlist: nil, Denylist: nil, + Prioritylist: nil, }, false, }, @@ -526,6 +528,7 @@ func TestMsgUpdateConsumerValidateBasic(t *testing.T) { Denylist: nil, MinStake: 0, AllowInactiveVals: false, + Prioritylist: nil, }, false, }, @@ -539,6 +542,7 @@ func TestMsgUpdateConsumerValidateBasic(t *testing.T) { Denylist: []string{consAddr2, consAddr3}, MinStake: 0, AllowInactiveVals: false, + Prioritylist: []string{consAddr1}, }, true, }, diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index c390ab752b..ae7402200e 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -1699,6 +1699,11 @@ type PowerShapingParameters struct { MinStake uint64 `protobuf:"varint,6,opt,name=min_stake,json=minStake,proto3" json:"min_stake,omitempty"` // Corresponds to whether inactive validators are allowed to validate the consumer chain. AllowInactiveVals bool `protobuf:"varint,7,opt,name=allow_inactive_vals,json=allowInactiveVals,proto3" json:"allow_inactive_vals,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that should have PRIORITY to validate on the consumer chain, + // meaning as long as they are eligible/opted in to validate on the consumer chain, the validator set will be + // filled with these validators first, and other validators will be added to the validator set only if there are + // not enough eligible priority validators. + Prioritylist []string `protobuf:"bytes,8,rep,name=prioritylist,proto3" json:"prioritylist,omitempty"` } func (m *PowerShapingParameters) Reset() { *m = PowerShapingParameters{} } @@ -1783,6 +1788,13 @@ func (m *PowerShapingParameters) GetAllowInactiveVals() bool { return false } +func (m *PowerShapingParameters) GetPrioritylist() []string { + if m != nil { + return m.Prioritylist + } + return nil +} + // ConsumerIds contains consumer ids of chains // Used so we can easily (de)serialize slices of strings type ConsumerIds struct { @@ -1907,149 +1919,150 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 2267 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcb, 0x6f, 0x1b, 0xc9, - 0xd1, 0xd7, 0x88, 0x94, 0x44, 0x16, 0xf5, 0xa0, 0xda, 0x5e, 0x99, 0x92, 0xb5, 0x24, 0xcd, 0xfd, - 0xbc, 0xe0, 0x67, 0xc7, 0xe4, 0x4a, 0x0b, 0x04, 0x86, 0x93, 0x85, 0x41, 0x93, 0xb4, 0x4d, 0x3f, - 0x64, 0x66, 0x48, 0x6b, 0x01, 0xe7, 0x30, 0x68, 0xce, 0xb4, 0xc8, 0x8e, 0xe6, 0xe5, 0xe9, 0x26, - 0x6d, 0xe6, 0x90, 0xf3, 0x22, 0x40, 0x80, 0x4d, 0x4e, 0x8b, 0x5c, 0xb2, 0x40, 0x2e, 0x41, 0x4e, - 0x39, 0x04, 0xf9, 0x03, 0x72, 0xda, 0x04, 0x08, 0xb0, 0xb9, 0xe5, 0xb4, 0x1b, 0xd8, 0x87, 0x1c, - 0x02, 0x24, 0xe7, 0xdc, 0x82, 0xee, 0x79, 0x70, 0xa8, 0x97, 0x69, 0xd8, 0xce, 0x45, 0x9a, 0xae, - 0xfa, 0x55, 0x75, 0x75, 0x77, 0xbd, 0xba, 0x09, 0xbb, 0xd4, 0xe6, 0xc4, 0xd3, 0x07, 0x98, 0xda, - 0x1a, 0x23, 0xfa, 0xd0, 0xa3, 0x7c, 0x5c, 0xd5, 0xf5, 0x51, 0xd5, 0xf5, 0x9c, 0x11, 0x35, 0x88, - 0x57, 0x1d, 0xed, 0x44, 0xdf, 0x15, 0xd7, 0x73, 0xb8, 0x83, 0x3e, 0x38, 0x41, 0xa6, 0xa2, 0xeb, - 0xa3, 0x4a, 0x84, 0x1b, 0xed, 0x6c, 0x5d, 0x3e, 0x4d, 0xf1, 0x68, 0xa7, 0xfa, 0x8c, 0x7a, 0xc4, - 0xd7, 0xb5, 0x75, 0xbe, 0xef, 0xf4, 0x1d, 0xf9, 0x59, 0x15, 0x5f, 0x01, 0xb5, 0xd0, 0x77, 0x9c, - 0xbe, 0x49, 0xaa, 0x72, 0xd4, 0x1b, 0x1e, 0x54, 0x39, 0xb5, 0x08, 0xe3, 0xd8, 0x72, 0x03, 0x40, - 0xfe, 0x28, 0xc0, 0x18, 0x7a, 0x98, 0x53, 0xc7, 0x0e, 0x15, 0xd0, 0x9e, 0x5e, 0xd5, 0x1d, 0x8f, - 0x54, 0x75, 0x93, 0x12, 0x9b, 0x8b, 0x59, 0xfd, 0xaf, 0x00, 0x50, 0x15, 0x00, 0x93, 0xf6, 0x07, - 0xdc, 0x27, 0xb3, 0x2a, 0x27, 0xb6, 0x41, 0x3c, 0x8b, 0xfa, 0xe0, 0xc9, 0x28, 0x10, 0xd8, 0x8e, - 0xf1, 0x75, 0x6f, 0xec, 0x72, 0xa7, 0x7a, 0x48, 0xc6, 0x2c, 0xe0, 0x7e, 0xa8, 0x3b, 0xcc, 0x72, - 0x58, 0x95, 0x88, 0xf5, 0xdb, 0x3a, 0xa9, 0x8e, 0x76, 0x7a, 0x84, 0xe3, 0x9d, 0x88, 0x10, 0xda, - 0x1d, 0xe0, 0x7a, 0x98, 0x4d, 0x30, 0xba, 0x43, 0x43, 0xbb, 0x37, 0x7d, 0xbe, 0xe6, 0xef, 0x88, - 0x3f, 0x08, 0x58, 0xeb, 0xd8, 0xa2, 0xb6, 0x53, 0x95, 0x7f, 0x7d, 0x52, 0xe9, 0x3f, 0x29, 0xc8, - 0xd5, 0x1d, 0x9b, 0x0d, 0x2d, 0xe2, 0xd5, 0x0c, 0x83, 0x8a, 0x0d, 0x68, 0x7b, 0x8e, 0xeb, 0x30, - 0x6c, 0xa2, 0xf3, 0xb0, 0xc0, 0x29, 0x37, 0x49, 0x4e, 0x29, 0x2a, 0xe5, 0xb4, 0xea, 0x0f, 0x50, - 0x11, 0x32, 0x06, 0x61, 0xba, 0x47, 0x5d, 0x01, 0xce, 0xcd, 0x4b, 0x5e, 0x9c, 0x84, 0x36, 0x21, - 0xe5, 0x9f, 0x1a, 0x35, 0x72, 0x09, 0xc9, 0x5e, 0x92, 0xe3, 0x96, 0x81, 0xee, 0xc0, 0x2a, 0xb5, - 0x29, 0xa7, 0xd8, 0xd4, 0x06, 0x44, 0xec, 0x5d, 0x2e, 0x59, 0x54, 0xca, 0x99, 0xdd, 0xad, 0x0a, - 0xed, 0xe9, 0x15, 0xb1, 0xdd, 0x95, 0x60, 0x93, 0x47, 0x3b, 0x95, 0xbb, 0x12, 0x71, 0x2b, 0xf9, - 0xd5, 0x37, 0x85, 0x39, 0x75, 0x25, 0x90, 0xf3, 0x89, 0xe8, 0x12, 0x2c, 0xf7, 0x89, 0x4d, 0x18, - 0x65, 0xda, 0x00, 0xb3, 0x41, 0x6e, 0xa1, 0xa8, 0x94, 0x97, 0xd5, 0x4c, 0x40, 0xbb, 0x8b, 0xd9, - 0x00, 0x15, 0x20, 0xd3, 0xa3, 0x36, 0xf6, 0xc6, 0x3e, 0x62, 0x51, 0x22, 0xc0, 0x27, 0x49, 0x40, - 0x1d, 0x80, 0xb9, 0xf8, 0x99, 0xad, 0x09, 0xdf, 0xc8, 0x2d, 0x05, 0x86, 0xf8, 0x7e, 0x51, 0x09, - 0xfd, 0xa2, 0xd2, 0x0d, 0x1d, 0xe7, 0x56, 0x4a, 0x18, 0xf2, 0xf9, 0xb7, 0x05, 0x45, 0x4d, 0x4b, - 0x39, 0xc1, 0x41, 0x7b, 0x90, 0x1d, 0xda, 0x3d, 0xc7, 0x36, 0xa8, 0xdd, 0xd7, 0x5c, 0xe2, 0x51, - 0xc7, 0xc8, 0xa5, 0xa4, 0xaa, 0xcd, 0x63, 0xaa, 0x1a, 0x81, 0x8b, 0xf9, 0x9a, 0xbe, 0x10, 0x9a, - 0xd6, 0x22, 0xe1, 0xb6, 0x94, 0x45, 0x3f, 0x00, 0xa4, 0xeb, 0x23, 0x69, 0x92, 0x33, 0xe4, 0xa1, - 0xc6, 0xf4, 0xec, 0x1a, 0xb3, 0xba, 0x3e, 0xea, 0xfa, 0xd2, 0x81, 0xca, 0x1f, 0xc2, 0x05, 0xee, - 0x61, 0x9b, 0x1d, 0x10, 0xef, 0xa8, 0x5e, 0x98, 0x5d, 0xef, 0x7b, 0xa1, 0x8e, 0x69, 0xe5, 0x77, - 0xa1, 0xa8, 0x07, 0x0e, 0xa4, 0x79, 0xc4, 0xa0, 0x8c, 0x7b, 0xb4, 0x37, 0x14, 0xb2, 0xda, 0x81, - 0x87, 0x75, 0xe9, 0x23, 0x19, 0xe9, 0x04, 0xf9, 0x10, 0xa7, 0x4e, 0xc1, 0x6e, 0x07, 0x28, 0xf4, - 0x08, 0xfe, 0xaf, 0x67, 0x3a, 0xfa, 0x21, 0x13, 0xc6, 0x69, 0x53, 0x9a, 0xe4, 0xd4, 0x16, 0x65, - 0x4c, 0x68, 0x5b, 0x2e, 0x2a, 0xe5, 0x84, 0x7a, 0xc9, 0xc7, 0xb6, 0x89, 0xd7, 0x88, 0x21, 0xbb, - 0x31, 0x20, 0xba, 0x06, 0x68, 0x40, 0x19, 0x77, 0x3c, 0xaa, 0x63, 0x53, 0x23, 0x36, 0xf7, 0x28, - 0x61, 0xb9, 0x15, 0x29, 0xbe, 0x3e, 0xe1, 0x34, 0x7d, 0x06, 0xba, 0x07, 0x97, 0x4e, 0x9d, 0x54, - 0xd3, 0x07, 0xd8, 0xb6, 0x89, 0x99, 0x5b, 0x95, 0x4b, 0x29, 0x18, 0xa7, 0xcc, 0x59, 0xf7, 0x61, - 0xe8, 0x1c, 0x2c, 0x70, 0xc7, 0xd5, 0xf6, 0x72, 0x6b, 0x45, 0xa5, 0xbc, 0xa2, 0x26, 0xb9, 0xe3, - 0xee, 0xa1, 0x8f, 0xe0, 0xfc, 0x08, 0x9b, 0xd4, 0xc0, 0xdc, 0xf1, 0x98, 0xe6, 0x3a, 0xcf, 0x88, - 0xa7, 0xe9, 0xd8, 0xcd, 0x65, 0x25, 0x06, 0x4d, 0x78, 0x6d, 0xc1, 0xaa, 0x63, 0x17, 0x5d, 0x81, - 0xf5, 0x88, 0xaa, 0x31, 0xc2, 0x25, 0x7c, 0x5d, 0xc2, 0xd7, 0x22, 0x46, 0x87, 0x70, 0x81, 0xdd, - 0x86, 0x34, 0x36, 0x4d, 0xe7, 0x99, 0x49, 0x19, 0xcf, 0xa1, 0x62, 0xa2, 0x9c, 0x56, 0x27, 0x04, - 0xb4, 0x05, 0x29, 0x83, 0xd8, 0x63, 0xc9, 0x3c, 0x27, 0x99, 0xd1, 0x18, 0x5d, 0x84, 0xb4, 0x25, - 0x72, 0x2c, 0xc7, 0x87, 0x24, 0x77, 0xbe, 0xa8, 0x94, 0x93, 0x6a, 0xca, 0xa2, 0x76, 0x47, 0x8c, - 0x51, 0x05, 0xce, 0x49, 0x2d, 0x1a, 0xb5, 0xc5, 0x39, 0x8d, 0x88, 0x36, 0xc2, 0x26, 0xcb, 0xbd, - 0x57, 0x54, 0xca, 0x29, 0x75, 0x5d, 0xb2, 0x5a, 0x01, 0x67, 0x1f, 0x9b, 0xec, 0x46, 0xf9, 0xb3, - 0x2f, 0x0b, 0x73, 0x5f, 0x7c, 0x59, 0x98, 0xfb, 0xf3, 0xef, 0xaf, 0x6d, 0x05, 0xe9, 0xa7, 0xef, - 0x8c, 0x2a, 0x41, 0xaa, 0xaa, 0xd4, 0x1d, 0x9b, 0x13, 0x9b, 0xe7, 0x94, 0xd2, 0x5f, 0x15, 0xb8, - 0x50, 0x8f, 0x5c, 0xc2, 0x72, 0x46, 0xd8, 0x7c, 0x97, 0xa9, 0xa7, 0x06, 0x69, 0x26, 0xce, 0x44, - 0x06, 0x7b, 0xf2, 0x35, 0x82, 0x3d, 0x25, 0xc4, 0x04, 0xe3, 0x46, 0xf1, 0x95, 0x6b, 0xfa, 0xf7, - 0x3c, 0x6c, 0x87, 0x6b, 0x7a, 0xe8, 0x18, 0xf4, 0x80, 0xea, 0xf8, 0x5d, 0xe7, 0xd4, 0xc8, 0xd7, - 0x92, 0x33, 0xf8, 0xda, 0xc2, 0xeb, 0xf9, 0xda, 0xe2, 0x0c, 0xbe, 0xb6, 0x74, 0x96, 0xaf, 0xa5, - 0xce, 0xf2, 0xb5, 0xf4, 0x6c, 0xbe, 0x06, 0xa7, 0xf9, 0xda, 0x7c, 0x4e, 0x29, 0xfd, 0x4a, 0x81, - 0xf3, 0xcd, 0xa7, 0x43, 0x3a, 0x72, 0xde, 0xd2, 0x4e, 0xdf, 0x87, 0x15, 0x12, 0xd3, 0xc7, 0x72, - 0x89, 0x62, 0xa2, 0x9c, 0xd9, 0xbd, 0x5c, 0x09, 0x0e, 0x3e, 0xaa, 0xc7, 0xe1, 0xe9, 0xc7, 0x67, - 0x57, 0xa7, 0x65, 0xa5, 0x85, 0x7f, 0x54, 0x60, 0x4b, 0xe4, 0x85, 0x3e, 0x51, 0xc9, 0x33, 0xec, - 0x19, 0x0d, 0x62, 0x3b, 0x16, 0x7b, 0x63, 0x3b, 0x4b, 0xb0, 0x62, 0x48, 0x4d, 0x1a, 0x77, 0x34, - 0x6c, 0x18, 0xd2, 0x4e, 0x89, 0x11, 0xc4, 0xae, 0x53, 0x33, 0x0c, 0x54, 0x86, 0xec, 0x04, 0xe3, - 0x89, 0x18, 0x13, 0xae, 0x2f, 0x60, 0xab, 0x21, 0x4c, 0x46, 0x1e, 0xb9, 0x91, 0x3f, 0xdb, 0xb5, - 0x4b, 0xff, 0x54, 0x20, 0x7b, 0xc7, 0x74, 0x7a, 0xd8, 0xec, 0x98, 0x98, 0x0d, 0x44, 0xce, 0x1c, - 0x8b, 0x90, 0xf2, 0x48, 0x50, 0xac, 0xa4, 0xf9, 0x33, 0x87, 0x94, 0x10, 0x93, 0xe5, 0xf3, 0x26, - 0xac, 0x47, 0xe5, 0x23, 0x72, 0x70, 0xb9, 0xda, 0x5b, 0xe7, 0x5e, 0x7c, 0x53, 0x58, 0x0b, 0x83, - 0xa9, 0x2e, 0x9d, 0xbd, 0xa1, 0xae, 0xe9, 0x53, 0x04, 0x03, 0xe5, 0x21, 0x43, 0x7b, 0xba, 0xc6, - 0xc8, 0x53, 0xcd, 0x1e, 0x5a, 0x32, 0x36, 0x92, 0x6a, 0x9a, 0xf6, 0xf4, 0x0e, 0x79, 0xba, 0x37, - 0xb4, 0xd0, 0xc7, 0xb0, 0x11, 0x36, 0x95, 0xc2, 0x9b, 0x34, 0x21, 0x2f, 0xb6, 0xcb, 0x93, 0xe1, - 0xb2, 0xac, 0x9e, 0x0b, 0xb9, 0xfb, 0xd8, 0x14, 0x93, 0xd5, 0x0c, 0xc3, 0x2b, 0xfd, 0x6b, 0x01, - 0x16, 0xdb, 0xd8, 0xc3, 0x16, 0x43, 0x5d, 0x58, 0xe3, 0xc4, 0x72, 0x4d, 0xcc, 0x89, 0xe6, 0xb7, - 0x26, 0xc1, 0x4a, 0xaf, 0xca, 0x96, 0x25, 0xde, 0x00, 0x56, 0x62, 0x2d, 0xdf, 0x68, 0xa7, 0x52, - 0x97, 0xd4, 0x0e, 0xc7, 0x9c, 0xa8, 0xab, 0xa1, 0x0e, 0x9f, 0x88, 0xae, 0x43, 0x8e, 0x7b, 0x43, - 0xc6, 0x27, 0x4d, 0xc3, 0xa4, 0x5a, 0xfa, 0x67, 0xbd, 0x11, 0xf2, 0xfd, 0x3a, 0x1b, 0x55, 0xc9, - 0x93, 0xfb, 0x83, 0xc4, 0x9b, 0xf4, 0x07, 0x06, 0x6c, 0x33, 0x71, 0xa8, 0x9a, 0x45, 0xb8, 0xac, - 0xe2, 0xae, 0x49, 0x6c, 0xca, 0x06, 0xa1, 0xf2, 0xc5, 0xd9, 0x95, 0x6f, 0x4a, 0x45, 0x0f, 0x85, - 0x1e, 0x35, 0x54, 0x13, 0xcc, 0x52, 0x87, 0xfc, 0xc9, 0xb3, 0x44, 0x0b, 0x5f, 0x92, 0x0b, 0xbf, - 0x78, 0x82, 0x8a, 0x68, 0xf5, 0x0c, 0x3e, 0x8c, 0x75, 0x1b, 0x22, 0x9a, 0x34, 0xe9, 0xc8, 0x9a, - 0x47, 0xfa, 0xa2, 0x24, 0x63, 0xbf, 0xf1, 0x20, 0x24, 0xea, 0x98, 0x02, 0x9f, 0x16, 0xed, 0x72, - 0xcc, 0xa9, 0xa9, 0x1d, 0xb4, 0x95, 0xa5, 0x49, 0x53, 0x12, 0xc5, 0xa6, 0x1a, 0xd3, 0x75, 0x9b, - 0x10, 0x11, 0x45, 0xb1, 0xc6, 0x84, 0xb8, 0x8e, 0x3e, 0x90, 0x39, 0x29, 0xa1, 0xae, 0x46, 0x4d, - 0x48, 0x53, 0x50, 0xd1, 0x13, 0xb8, 0x6a, 0x0f, 0xad, 0x1e, 0xf1, 0x34, 0xe7, 0xc0, 0x07, 0xca, - 0xc8, 0x63, 0x1c, 0x7b, 0x5c, 0xf3, 0x88, 0x4e, 0xe8, 0x48, 0x9c, 0xb8, 0x6f, 0x39, 0x93, 0x7d, - 0x51, 0x42, 0xbd, 0xec, 0x8b, 0x3c, 0x3a, 0x90, 0x3a, 0x58, 0xd7, 0xe9, 0x08, 0xb8, 0x1a, 0xa2, - 0x7d, 0xc3, 0x18, 0x6a, 0xc1, 0x25, 0x0b, 0x3f, 0xd7, 0x22, 0x67, 0x16, 0x86, 0x13, 0x9b, 0x0d, - 0x99, 0x36, 0x49, 0xe6, 0x41, 0x6f, 0x94, 0xb7, 0xf0, 0xf3, 0x76, 0x80, 0xab, 0x87, 0xb0, 0xfd, - 0x08, 0x75, 0x2f, 0x99, 0x4a, 0x66, 0x17, 0xee, 0x25, 0x53, 0x0b, 0xd9, 0xc5, 0x7b, 0xc9, 0x54, - 0x2a, 0x9b, 0x2e, 0xfd, 0x3f, 0xa4, 0x65, 0x5c, 0xd7, 0xf4, 0x43, 0x26, 0xb3, 0xbb, 0x61, 0x78, - 0x84, 0x31, 0xc2, 0x72, 0x4a, 0x90, 0xdd, 0x43, 0x42, 0x89, 0xc3, 0xe6, 0x69, 0x37, 0x06, 0x86, - 0x3e, 0x85, 0x25, 0x97, 0xc8, 0x76, 0x56, 0x0a, 0x66, 0x76, 0x3f, 0xa9, 0xcc, 0x70, 0xd5, 0xab, - 0x9c, 0xa6, 0x50, 0x0d, 0xb5, 0x95, 0xbc, 0xc9, 0x3d, 0xe5, 0x48, 0xaf, 0xc0, 0xd0, 0xfe, 0xd1, - 0x49, 0xbf, 0xff, 0x5a, 0x93, 0x1e, 0xd1, 0x37, 0x99, 0xf3, 0x2a, 0x64, 0x6a, 0xfe, 0xb2, 0x1f, - 0x88, 0xd2, 0x75, 0x6c, 0x5b, 0x96, 0xe3, 0xdb, 0xb2, 0x07, 0xab, 0x41, 0xf3, 0xd7, 0x75, 0x64, - 0x6e, 0x42, 0xef, 0x03, 0x04, 0x5d, 0xa3, 0xc8, 0x69, 0x7e, 0x76, 0x4f, 0x07, 0x94, 0x96, 0x31, - 0x55, 0xd1, 0xe7, 0xa7, 0x2a, 0xba, 0xac, 0x1a, 0x0e, 0x6c, 0xee, 0xc7, 0xab, 0xae, 0x2c, 0x20, - 0x6d, 0xac, 0x1f, 0x12, 0xce, 0x90, 0x0a, 0x49, 0x59, 0x5d, 0xfd, 0xe5, 0x5e, 0x3f, 0x75, 0xb9, - 0xa3, 0x9d, 0xca, 0x69, 0x4a, 0x1a, 0x98, 0xe3, 0x20, 0x06, 0xa4, 0xae, 0xd2, 0xcf, 0x15, 0xc8, - 0xdd, 0x27, 0xe3, 0x1a, 0x63, 0xb4, 0x6f, 0x5b, 0xc4, 0xe6, 0x22, 0xfa, 0xb0, 0x4e, 0xc4, 0x27, - 0xfa, 0x00, 0x56, 0x22, 0xc7, 0x93, 0xc9, 0x53, 0x91, 0xc9, 0x73, 0x39, 0x24, 0x8a, 0x7d, 0x42, - 0x37, 0x00, 0x5c, 0x8f, 0x8c, 0x34, 0x5d, 0x3b, 0x24, 0x63, 0xb9, 0xa6, 0xcc, 0xee, 0x76, 0x3c, - 0x29, 0xfa, 0xb7, 0xde, 0x4a, 0x7b, 0xd8, 0x33, 0xa9, 0x7e, 0x9f, 0x8c, 0xd5, 0x94, 0xc0, 0xd7, - 0xef, 0x93, 0xb1, 0xa8, 0x82, 0xb2, 0x49, 0x91, 0x99, 0x2c, 0xa1, 0xfa, 0x83, 0xd2, 0x2f, 0x15, - 0xb8, 0x10, 0x2d, 0x20, 0x3c, 0xaf, 0xf6, 0xb0, 0x27, 0x24, 0xe2, 0xfb, 0xa7, 0x4c, 0x77, 0x44, - 0xc7, 0xac, 0x9d, 0x3f, 0xc1, 0xda, 0x9b, 0xb0, 0x1c, 0xa5, 0x12, 0x61, 0x6f, 0x62, 0x06, 0x7b, - 0x33, 0xa1, 0xc4, 0x7d, 0x32, 0x2e, 0xfd, 0x24, 0x66, 0xdb, 0xad, 0x71, 0xcc, 0x85, 0xbd, 0x57, - 0xd8, 0x16, 0x4d, 0x1b, 0xb7, 0x4d, 0x8f, 0xcb, 0x1f, 0x5b, 0x40, 0xe2, 0xf8, 0x02, 0x4a, 0x7f, - 0x51, 0x60, 0x23, 0x3e, 0x2b, 0xeb, 0x3a, 0x6d, 0x6f, 0x68, 0x93, 0xfd, 0xdd, 0xb3, 0xe6, 0xbf, - 0x09, 0x29, 0x57, 0xa0, 0x34, 0xce, 0x82, 0x23, 0x9a, 0xad, 0x64, 0x2f, 0x49, 0xa9, 0xae, 0x08, - 0xf1, 0xd5, 0xa9, 0x05, 0xb0, 0x60, 0xe7, 0x3e, 0x9a, 0x29, 0xe8, 0x62, 0x01, 0xa5, 0xae, 0xc4, - 0xd7, 0xcc, 0x4a, 0x7f, 0x50, 0x00, 0x1d, 0xcf, 0x56, 0xe8, 0x3b, 0x80, 0xa6, 0x72, 0x5e, 0xdc, - 0xff, 0xb2, 0x6e, 0x2c, 0xcb, 0xc9, 0x9d, 0x8b, 0xfc, 0x68, 0x3e, 0xe6, 0x47, 0xe8, 0x7b, 0x00, - 0xae, 0x3c, 0xc4, 0x99, 0x4f, 0x3a, 0xed, 0x86, 0x9f, 0xa8, 0x00, 0x99, 0x1f, 0x39, 0xd4, 0x8e, - 0x3f, 0x58, 0x24, 0x54, 0x10, 0x24, 0xff, 0x2d, 0xa2, 0xf4, 0x33, 0x65, 0x92, 0x12, 0x83, 0x6c, - 0x5d, 0x33, 0xcd, 0xa0, 0x07, 0x44, 0x2e, 0x2c, 0x85, 0xf9, 0xde, 0x0f, 0xd7, 0xed, 0x13, 0x6b, - 0x52, 0x83, 0xe8, 0xb2, 0x2c, 0x5d, 0x17, 0x3b, 0xfe, 0xdb, 0x6f, 0x0b, 0x57, 0xfb, 0x94, 0x0f, - 0x86, 0xbd, 0x8a, 0xee, 0x58, 0xc1, 0x2b, 0x4e, 0xf0, 0xef, 0x1a, 0x33, 0x0e, 0xab, 0x7c, 0xec, - 0x12, 0x16, 0xca, 0xb0, 0xdf, 0xfc, 0xe3, 0x77, 0x57, 0x14, 0x35, 0x9c, 0xa6, 0x64, 0x40, 0x36, - 0xba, 0x83, 0x10, 0x8e, 0x0d, 0xcc, 0x31, 0x42, 0x90, 0xb4, 0xb1, 0x15, 0x36, 0x99, 0xf2, 0x7b, - 0x86, 0x1e, 0x73, 0x0b, 0x52, 0x56, 0xa0, 0x21, 0xb8, 0x75, 0x44, 0xe3, 0xd2, 0x4f, 0x17, 0xa1, - 0x18, 0x4e, 0xd3, 0xf2, 0xdf, 0x66, 0xe8, 0x8f, 0xfd, 0x16, 0x5c, 0x74, 0x4e, 0xa2, 0x7e, 0xb3, - 0x13, 0xde, 0x7b, 0x94, 0xb7, 0xf3, 0xde, 0x33, 0xff, 0xca, 0xf7, 0x9e, 0xc4, 0x2b, 0xde, 0x7b, - 0x92, 0x6f, 0xef, 0xbd, 0x67, 0xe1, 0xad, 0xbf, 0xf7, 0x2c, 0xbe, 0xa3, 0xf7, 0x9e, 0xa5, 0xff, - 0xc9, 0x7b, 0x4f, 0xea, 0xad, 0xbe, 0xf7, 0xa4, 0xdf, 0xec, 0xbd, 0x07, 0xde, 0xe8, 0xbd, 0x27, - 0x33, 0xd3, 0x7b, 0x4f, 0xe9, 0x17, 0xf3, 0xb0, 0x21, 0x6f, 0xd2, 0x9d, 0x01, 0x76, 0xc5, 0xe1, - 0x4e, 0x42, 0x20, 0xba, 0x9e, 0x2b, 0x33, 0x5c, 0xcf, 0xe7, 0x5f, 0xef, 0x7a, 0x9e, 0x98, 0xe1, - 0x7a, 0x9e, 0x3c, 0xeb, 0x7a, 0xbe, 0x70, 0xd6, 0xf5, 0x7c, 0x71, 0xb6, 0xeb, 0xf9, 0xd2, 0x29, - 0xd7, 0xf3, 0x52, 0x01, 0x32, 0x51, 0x82, 0x30, 0x18, 0xca, 0x42, 0x82, 0x1a, 0x61, 0x43, 0x29, - 0x3e, 0x4b, 0x3b, 0x70, 0xa1, 0x16, 0x9a, 0x45, 0x8c, 0xf8, 0xed, 0x18, 0x6d, 0xc0, 0xa2, 0x7f, - 0x43, 0x0d, 0xf0, 0xc1, 0xe8, 0xca, 0x9f, 0x14, 0x58, 0x89, 0x1a, 0x81, 0x01, 0x66, 0x04, 0xe5, - 0x61, 0xab, 0xfe, 0x68, 0xaf, 0xf3, 0xf8, 0x61, 0x53, 0xd5, 0xda, 0x77, 0x6b, 0x9d, 0xa6, 0xf6, - 0x78, 0xaf, 0xd3, 0x6e, 0xd6, 0x5b, 0xb7, 0x5b, 0xcd, 0x46, 0x76, 0x0e, 0xbd, 0x0f, 0x9b, 0x47, - 0xf8, 0x6a, 0xf3, 0x4e, 0xab, 0xd3, 0x6d, 0xaa, 0xcd, 0x46, 0x56, 0x39, 0x41, 0xbc, 0xb5, 0xd7, - 0xea, 0xb6, 0x6a, 0x0f, 0x5a, 0x4f, 0x9a, 0x8d, 0xec, 0x3c, 0xba, 0x08, 0x17, 0x8e, 0xf0, 0x1f, - 0xd4, 0x1e, 0xef, 0xd5, 0xef, 0x36, 0x1b, 0xd9, 0x04, 0xda, 0x82, 0x8d, 0x23, 0xcc, 0x4e, 0xf7, - 0x51, 0xbb, 0xdd, 0x6c, 0x64, 0x93, 0x27, 0xf0, 0x1a, 0xcd, 0x07, 0xcd, 0x6e, 0xb3, 0x91, 0x5d, - 0xd8, 0x4a, 0x7e, 0xf6, 0xeb, 0xfc, 0xdc, 0xad, 0x4f, 0xbf, 0x7a, 0x91, 0x57, 0xbe, 0x7e, 0x91, - 0x57, 0xfe, 0xfe, 0x22, 0xaf, 0x7c, 0xfe, 0x32, 0x3f, 0xf7, 0xf5, 0xcb, 0xfc, 0xdc, 0xdf, 0x5e, - 0xe6, 0xe7, 0x9e, 0x7c, 0x72, 0x3c, 0xf9, 0x4f, 0x8a, 0xeb, 0xb5, 0xe8, 0xc7, 0x90, 0xd1, 0x77, - 0xab, 0xcf, 0xa7, 0x7f, 0x6a, 0x91, 0x75, 0xa1, 0xb7, 0x28, 0xe3, 0xfa, 0xe3, 0xff, 0x06, 0x00, - 0x00, 0xff, 0xff, 0x21, 0xa7, 0x53, 0x56, 0x9b, 0x19, 0x00, 0x00, + // 2280 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcd, 0x6f, 0x1b, 0xc7, + 0xd9, 0xd7, 0x8a, 0x94, 0x44, 0x0e, 0xf5, 0x41, 0x8d, 0x1d, 0x99, 0x92, 0x15, 0x92, 0xde, 0xbc, + 0x0e, 0xf8, 0xda, 0x35, 0x19, 0x29, 0x40, 0x61, 0xb8, 0x0d, 0x0c, 0x9a, 0xa4, 0x6d, 0xfa, 0x43, + 0x66, 0x97, 0xb4, 0x02, 0xb8, 0x87, 0xc5, 0x70, 0x77, 0x44, 0x4e, 0xb5, 0xbb, 0xb3, 0xde, 0x19, + 0xae, 0xcd, 0x1e, 0x7a, 0x0e, 0x0a, 0x14, 0x48, 0x6f, 0x41, 0x2f, 0x0d, 0xd0, 0x4b, 0xd1, 0x53, + 0x0f, 0x45, 0xfe, 0x80, 0x9e, 0xd2, 0x02, 0x05, 0xd2, 0x5b, 0x4f, 0x49, 0x61, 0x1f, 0x7a, 0x28, + 0xd0, 0x9e, 0x7b, 0x2b, 0x66, 0xf6, 0x83, 0x4b, 0x7d, 0x99, 0x86, 0xed, 0x5e, 0xa4, 0x9d, 0x79, + 0x7e, 0xcf, 0x33, 0xcf, 0x33, 0xf3, 0x7c, 0xcd, 0x10, 0xec, 0x12, 0x87, 0x63, 0xcf, 0x18, 0x22, + 0xe2, 0xe8, 0x0c, 0x1b, 0x23, 0x8f, 0xf0, 0x71, 0xcd, 0x30, 0xfc, 0x9a, 0xeb, 0x51, 0x9f, 0x98, + 0xd8, 0xab, 0xf9, 0x3b, 0xf1, 0x77, 0xd5, 0xf5, 0x28, 0xa7, 0xf0, 0x83, 0x13, 0x78, 0xaa, 0x86, + 0xe1, 0x57, 0x63, 0x9c, 0xbf, 0xb3, 0xb5, 0x8e, 0x6c, 0xe2, 0xd0, 0x9a, 0xfc, 0x1b, 0xf0, 0x6d, + 0x15, 0x0d, 0xca, 0x6c, 0xca, 0x6a, 0x7d, 0xc4, 0x70, 0xcd, 0xdf, 0xe9, 0x63, 0x8e, 0x76, 0x6a, + 0x06, 0x25, 0x4e, 0x48, 0xff, 0x30, 0xa4, 0x63, 0x21, 0xc4, 0x31, 0x26, 0x98, 0x68, 0x22, 0xc4, + 0x6d, 0x06, 0x38, 0x5d, 0x8e, 0x6a, 0xc1, 0x20, 0x24, 0x9d, 0x1f, 0xd0, 0x01, 0x0d, 0xe6, 0xc5, + 0x57, 0xb4, 0xf0, 0x80, 0xd2, 0x81, 0x85, 0x6b, 0x72, 0xd4, 0x1f, 0x1d, 0xd4, 0xcc, 0x91, 0x87, + 0x38, 0xa1, 0xd1, 0xc2, 0xa5, 0xa3, 0x74, 0x4e, 0x6c, 0xcc, 0x38, 0xb2, 0xdd, 0x08, 0x40, 0xfa, + 0x46, 0xcd, 0xa0, 0x1e, 0xae, 0x19, 0x16, 0xc1, 0x0e, 0x17, 0x9b, 0x12, 0x7c, 0x85, 0x80, 0x9a, + 0x00, 0x58, 0x64, 0x30, 0xe4, 0xc1, 0x34, 0xab, 0x71, 0xec, 0x98, 0xd8, 0xb3, 0x49, 0x00, 0x9e, + 0x8c, 0x42, 0x86, 0xcb, 0xa7, 0xed, 0xbb, 0xbf, 0x53, 0x7b, 0x46, 0xbc, 0xc8, 0xd4, 0xed, 0x84, + 0x18, 0xc3, 0x1b, 0xbb, 0x9c, 0xd6, 0x0e, 0xf1, 0x38, 0xb4, 0x56, 0xfd, 0x4f, 0x06, 0x14, 0x1a, + 0xd4, 0x61, 0x23, 0x1b, 0x7b, 0x75, 0xd3, 0x24, 0xc2, 0xa4, 0x8e, 0x47, 0x5d, 0xca, 0x90, 0x05, + 0xcf, 0x83, 0x05, 0x4e, 0xb8, 0x85, 0x0b, 0x4a, 0x59, 0xa9, 0x64, 0xb5, 0x60, 0x00, 0xcb, 0x20, + 0x67, 0x62, 0x66, 0x78, 0xc4, 0x15, 0xe0, 0xc2, 0xbc, 0xa4, 0x25, 0xa7, 0xe0, 0x26, 0xc8, 0x04, + 0x6a, 0x11, 0xb3, 0x90, 0x92, 0xe4, 0x25, 0x39, 0x6e, 0x9b, 0xf0, 0x0e, 0x58, 0x25, 0x0e, 0xe1, + 0x04, 0x59, 0xfa, 0x10, 0x0b, 0x63, 0x0b, 0xe9, 0xb2, 0x52, 0xc9, 0xed, 0x6e, 0x55, 0x49, 0xdf, + 0xa8, 0x8a, 0xfd, 0xa9, 0x86, 0xbb, 0xe2, 0xef, 0x54, 0xef, 0x4a, 0xc4, 0xad, 0xf4, 0xd7, 0xdf, + 0x96, 0xe6, 0xb4, 0x95, 0x90, 0x2f, 0x98, 0x84, 0x97, 0xc0, 0xf2, 0x00, 0x3b, 0x98, 0x11, 0xa6, + 0x0f, 0x11, 0x1b, 0x16, 0x16, 0xca, 0x4a, 0x65, 0x59, 0xcb, 0x85, 0x73, 0x77, 0x11, 0x1b, 0xc2, + 0x12, 0xc8, 0xf5, 0x89, 0x83, 0xbc, 0x71, 0x80, 0x58, 0x94, 0x08, 0x10, 0x4c, 0x49, 0x40, 0x03, + 0x00, 0xe6, 0xa2, 0x67, 0x8e, 0x2e, 0x0e, 0xab, 0xb0, 0x14, 0x2a, 0x12, 0x9c, 0x64, 0x35, 0x3a, + 0xc9, 0x6a, 0x2f, 0x3a, 0xc9, 0x5b, 0x19, 0xa1, 0xc8, 0xe7, 0xdf, 0x95, 0x14, 0x2d, 0x2b, 0xf9, + 0x04, 0x05, 0xee, 0x81, 0xfc, 0xc8, 0xe9, 0x53, 0xc7, 0x24, 0xce, 0x40, 0x77, 0xb1, 0x47, 0xa8, + 0x59, 0xc8, 0x48, 0x51, 0x9b, 0xc7, 0x44, 0x35, 0x43, 0xa7, 0x09, 0x24, 0x7d, 0x21, 0x24, 0xad, + 0xc5, 0xcc, 0x1d, 0xc9, 0x0b, 0x7f, 0x04, 0xa0, 0x61, 0xf8, 0x52, 0x25, 0x3a, 0xe2, 0x91, 0xc4, + 0xec, 0xec, 0x12, 0xf3, 0x86, 0xe1, 0xf7, 0x02, 0xee, 0x50, 0xe4, 0x8f, 0xc1, 0x05, 0xee, 0x21, + 0x87, 0x1d, 0x60, 0xef, 0xa8, 0x5c, 0x30, 0xbb, 0xdc, 0xf7, 0x22, 0x19, 0xd3, 0xc2, 0xef, 0x82, + 0xb2, 0x11, 0x3a, 0x90, 0xee, 0x61, 0x93, 0x30, 0xee, 0x91, 0xfe, 0x48, 0xf0, 0xea, 0x07, 0x1e, + 0x32, 0xa4, 0x8f, 0xe4, 0xa4, 0x13, 0x14, 0x23, 0x9c, 0x36, 0x05, 0xbb, 0x1d, 0xa2, 0xe0, 0x23, + 0xf0, 0x7f, 0x7d, 0x8b, 0x1a, 0x87, 0x4c, 0x28, 0xa7, 0x4f, 0x49, 0x92, 0x4b, 0xdb, 0x84, 0x31, + 0x21, 0x6d, 0xb9, 0xac, 0x54, 0x52, 0xda, 0xa5, 0x00, 0xdb, 0xc1, 0x5e, 0x33, 0x81, 0xec, 0x25, + 0x80, 0xf0, 0x1a, 0x80, 0x43, 0xc2, 0x38, 0xf5, 0x88, 0x81, 0x2c, 0x1d, 0x3b, 0xdc, 0x23, 0x98, + 0x15, 0x56, 0x24, 0xfb, 0xfa, 0x84, 0xd2, 0x0a, 0x08, 0xf0, 0x1e, 0xb8, 0x74, 0xea, 0xa2, 0xba, + 0x31, 0x44, 0x8e, 0x83, 0xad, 0xc2, 0xaa, 0x34, 0xa5, 0x64, 0x9e, 0xb2, 0x66, 0x23, 0x80, 0xc1, + 0x73, 0x60, 0x81, 0x53, 0x57, 0xdf, 0x2b, 0xac, 0x95, 0x95, 0xca, 0x8a, 0x96, 0xe6, 0xd4, 0xdd, + 0x83, 0x1f, 0x81, 0xf3, 0x3e, 0xb2, 0x88, 0x89, 0x38, 0xf5, 0x98, 0xee, 0xd2, 0x67, 0xd8, 0xd3, + 0x0d, 0xe4, 0x16, 0xf2, 0x12, 0x03, 0x27, 0xb4, 0x8e, 0x20, 0x35, 0x90, 0x0b, 0xaf, 0x80, 0xf5, + 0x78, 0x56, 0x67, 0x98, 0x4b, 0xf8, 0xba, 0x84, 0xaf, 0xc5, 0x84, 0x2e, 0xe6, 0x02, 0xbb, 0x0d, + 0xb2, 0xc8, 0xb2, 0xe8, 0x33, 0x8b, 0x30, 0x5e, 0x80, 0xe5, 0x54, 0x25, 0xab, 0x4d, 0x26, 0xe0, + 0x16, 0xc8, 0x98, 0xd8, 0x19, 0x4b, 0xe2, 0x39, 0x49, 0x8c, 0xc7, 0xf0, 0x22, 0xc8, 0xda, 0x22, + 0x89, 0x70, 0x74, 0x88, 0x0b, 0xe7, 0xcb, 0x4a, 0x25, 0xad, 0x65, 0x6c, 0xe2, 0x74, 0xc5, 0x18, + 0x56, 0xc1, 0x39, 0x29, 0x45, 0x27, 0x8e, 0x38, 0x27, 0x1f, 0xeb, 0x3e, 0xb2, 0x58, 0xe1, 0xbd, + 0xb2, 0x52, 0xc9, 0x68, 0xeb, 0x92, 0xd4, 0x0e, 0x29, 0xfb, 0xc8, 0x62, 0x37, 0x2a, 0x9f, 0x7d, + 0x59, 0x9a, 0xfb, 0xe2, 0xcb, 0xd2, 0xdc, 0x9f, 0xff, 0x70, 0x6d, 0x2b, 0xcc, 0xac, 0x03, 0xea, + 0x57, 0xc3, 0x4c, 0x5c, 0x6d, 0x50, 0x87, 0x63, 0x87, 0x17, 0x14, 0xf5, 0xaf, 0x0a, 0xb8, 0xd0, + 0x88, 0x5d, 0xc2, 0xa6, 0x3e, 0xb2, 0xde, 0x65, 0xea, 0xa9, 0x83, 0x2c, 0x13, 0x67, 0x22, 0x83, + 0x3d, 0xfd, 0x1a, 0xc1, 0x9e, 0x11, 0x6c, 0x82, 0x70, 0xa3, 0xfc, 0x4a, 0x9b, 0xfe, 0x3d, 0x0f, + 0xb6, 0x23, 0x9b, 0x1e, 0x52, 0x93, 0x1c, 0x10, 0x03, 0xbd, 0xeb, 0x9c, 0x1a, 0xfb, 0x5a, 0x7a, + 0x06, 0x5f, 0x5b, 0x78, 0x3d, 0x5f, 0x5b, 0x9c, 0xc1, 0xd7, 0x96, 0xce, 0xf2, 0xb5, 0xcc, 0x59, + 0xbe, 0x96, 0x9d, 0xcd, 0xd7, 0xc0, 0x69, 0xbe, 0x36, 0x5f, 0x50, 0xd4, 0x5f, 0x2b, 0xe0, 0x7c, + 0xeb, 0xe9, 0x88, 0xf8, 0xf4, 0x2d, 0xed, 0xf4, 0x7d, 0xb0, 0x82, 0x13, 0xf2, 0x58, 0x21, 0x55, + 0x4e, 0x55, 0x72, 0xbb, 0x97, 0xab, 0xe1, 0xc1, 0xc7, 0xad, 0x44, 0x74, 0xfa, 0xc9, 0xd5, 0xb5, + 0x69, 0x5e, 0xa9, 0xe1, 0x1f, 0x15, 0xb0, 0x25, 0xf2, 0xc2, 0x00, 0x6b, 0xf8, 0x19, 0xf2, 0xcc, + 0x26, 0x76, 0xa8, 0xcd, 0xde, 0x58, 0x4f, 0x15, 0xac, 0x98, 0x52, 0x92, 0xce, 0xa9, 0x8e, 0x4c, + 0x53, 0xea, 0x29, 0x31, 0x62, 0xb2, 0x47, 0xeb, 0xa6, 0x09, 0x2b, 0x20, 0x3f, 0xc1, 0x78, 0x22, + 0xc6, 0x84, 0xeb, 0x0b, 0xd8, 0x6a, 0x04, 0x93, 0x91, 0x87, 0x6f, 0x14, 0xcf, 0x76, 0x6d, 0xf5, + 0x9f, 0x0a, 0xc8, 0xdf, 0xb1, 0x68, 0x1f, 0x59, 0x5d, 0x0b, 0xb1, 0xa1, 0xc8, 0x99, 0x63, 0x11, + 0x52, 0x1e, 0x0e, 0x8b, 0x95, 0x54, 0x7f, 0xe6, 0x90, 0x12, 0x6c, 0xb2, 0x7c, 0xde, 0x04, 0xeb, + 0x71, 0xf9, 0x88, 0x1d, 0x5c, 0x5a, 0x7b, 0xeb, 0xdc, 0x8b, 0x6f, 0x4b, 0x6b, 0x51, 0x30, 0x35, + 0xa4, 0xb3, 0x37, 0xb5, 0x35, 0x63, 0x6a, 0xc2, 0x84, 0x45, 0x90, 0x23, 0x7d, 0x43, 0x67, 0xf8, + 0xa9, 0xee, 0x8c, 0x6c, 0x19, 0x1b, 0x69, 0x2d, 0x4b, 0xfa, 0x46, 0x17, 0x3f, 0xdd, 0x1b, 0xd9, + 0xf0, 0x63, 0xb0, 0x11, 0x35, 0x95, 0xc2, 0x9b, 0x74, 0xc1, 0x2f, 0xb6, 0xcb, 0x93, 0xe1, 0xb2, + 0xac, 0x9d, 0x8b, 0xa8, 0xfb, 0xc8, 0x12, 0x8b, 0xd5, 0x4d, 0xd3, 0x53, 0xff, 0xb5, 0x00, 0x16, + 0x3b, 0xc8, 0x43, 0x36, 0x83, 0x3d, 0xb0, 0xc6, 0xb1, 0xed, 0x5a, 0x88, 0x63, 0x3d, 0x68, 0x4d, + 0x42, 0x4b, 0xaf, 0xca, 0x96, 0x25, 0xd9, 0xb1, 0x55, 0x13, 0x3d, 0x9a, 0xbf, 0x53, 0x6d, 0xc8, + 0xd9, 0x2e, 0x47, 0x1c, 0x6b, 0xab, 0x91, 0x8c, 0x60, 0x12, 0x5e, 0x07, 0x05, 0xee, 0x8d, 0x18, + 0x9f, 0x34, 0x0d, 0x93, 0x6a, 0x19, 0x9c, 0xf5, 0x46, 0x44, 0x0f, 0xea, 0x6c, 0x5c, 0x25, 0x4f, + 0xee, 0x0f, 0x52, 0x6f, 0xd2, 0x1f, 0x98, 0x60, 0x9b, 0x89, 0x43, 0xd5, 0x6d, 0xcc, 0x65, 0x15, + 0x77, 0x2d, 0xec, 0x10, 0x36, 0x8c, 0x84, 0x2f, 0xce, 0x2e, 0x7c, 0x53, 0x0a, 0x7a, 0x28, 0xe4, + 0x68, 0x91, 0x98, 0x70, 0x95, 0x06, 0x28, 0x9e, 0xbc, 0x4a, 0x6c, 0xf8, 0x92, 0x34, 0xfc, 0xe2, + 0x09, 0x22, 0x62, 0xeb, 0x19, 0xf8, 0x30, 0xd1, 0x6d, 0x88, 0x68, 0xd2, 0xa5, 0x23, 0xeb, 0x1e, + 0x1e, 0x88, 0x92, 0x8c, 0x82, 0xc6, 0x03, 0xe3, 0xb8, 0x63, 0x0a, 0x7d, 0x5a, 0xdc, 0x18, 0x12, + 0x4e, 0x4d, 0x9c, 0xb0, 0xad, 0x54, 0x27, 0x4d, 0x49, 0x1c, 0x9b, 0x5a, 0x42, 0xd6, 0x6d, 0x8c, + 0x45, 0x14, 0x25, 0x1a, 0x13, 0xec, 0x52, 0x63, 0x28, 0x73, 0x52, 0x4a, 0x5b, 0x8d, 0x9b, 0x90, + 0x96, 0x98, 0x85, 0x4f, 0xc0, 0x55, 0x67, 0x64, 0xf7, 0xb1, 0xa7, 0xd3, 0x83, 0x00, 0x28, 0x23, + 0x8f, 0x71, 0xe4, 0x71, 0xdd, 0xc3, 0x06, 0x26, 0xbe, 0x38, 0xf1, 0x40, 0x73, 0x26, 0xfb, 0xa2, + 0x94, 0x76, 0x39, 0x60, 0x79, 0x74, 0x20, 0x65, 0xb0, 0x1e, 0xed, 0x0a, 0xb8, 0x16, 0xa1, 0x03, + 0xc5, 0x18, 0x6c, 0x83, 0x4b, 0x36, 0x7a, 0xae, 0xc7, 0xce, 0x2c, 0x14, 0xc7, 0x0e, 0x1b, 0x31, + 0x7d, 0x92, 0xcc, 0xc3, 0xde, 0xa8, 0x68, 0xa3, 0xe7, 0x9d, 0x10, 0xd7, 0x88, 0x60, 0xfb, 0x31, + 0xea, 0x5e, 0x3a, 0x93, 0xce, 0x2f, 0xdc, 0x4b, 0x67, 0x16, 0xf2, 0x8b, 0xf7, 0xd2, 0x99, 0x4c, + 0x3e, 0xab, 0xfe, 0x3f, 0xc8, 0xca, 0xb8, 0xae, 0x1b, 0x87, 0x4c, 0x66, 0x77, 0xd3, 0xf4, 0x30, + 0x63, 0x98, 0x15, 0x94, 0x30, 0xbb, 0x47, 0x13, 0x2a, 0x07, 0x9b, 0xa7, 0xdd, 0x18, 0x18, 0xfc, + 0x14, 0x2c, 0xb9, 0x58, 0xb6, 0xb3, 0x92, 0x31, 0xb7, 0xfb, 0x49, 0x75, 0x86, 0xab, 0x5e, 0xf5, + 0x34, 0x81, 0x5a, 0x24, 0x4d, 0xf5, 0x26, 0xf7, 0x94, 0x23, 0xbd, 0x02, 0x83, 0xfb, 0x47, 0x17, + 0xfd, 0xe1, 0x6b, 0x2d, 0x7a, 0x44, 0xde, 0x64, 0xcd, 0xab, 0x20, 0x57, 0x0f, 0xcc, 0x7e, 0x20, + 0x4a, 0xd7, 0xb1, 0x6d, 0x59, 0x4e, 0x6e, 0xcb, 0x1e, 0x58, 0x0d, 0x9b, 0xbf, 0x1e, 0x95, 0xb9, + 0x09, 0xbe, 0x0f, 0x40, 0xd8, 0x35, 0x8a, 0x9c, 0x16, 0x64, 0xf7, 0x6c, 0x38, 0xd3, 0x36, 0xa7, + 0x2a, 0xfa, 0xfc, 0x54, 0x45, 0x97, 0x55, 0x83, 0x82, 0xcd, 0xfd, 0x64, 0xd5, 0x95, 0x05, 0xa4, + 0x83, 0x8c, 0x43, 0xcc, 0x19, 0xd4, 0x40, 0x5a, 0x56, 0xd7, 0xc0, 0xdc, 0xeb, 0xa7, 0x9a, 0xeb, + 0xef, 0x54, 0x4f, 0x13, 0xd2, 0x44, 0x1c, 0x85, 0x31, 0x20, 0x65, 0xa9, 0xbf, 0x54, 0x40, 0xe1, + 0x3e, 0x1e, 0xd7, 0x19, 0x23, 0x03, 0xc7, 0xc6, 0x0e, 0x17, 0xd1, 0x87, 0x0c, 0x2c, 0x3e, 0xe1, + 0x07, 0x60, 0x25, 0x76, 0x3c, 0x99, 0x3c, 0x15, 0x99, 0x3c, 0x97, 0xa3, 0x49, 0xb1, 0x4f, 0xf0, + 0x06, 0x00, 0xae, 0x87, 0x7d, 0xdd, 0xd0, 0x0f, 0xf1, 0x58, 0xda, 0x94, 0xdb, 0xdd, 0x4e, 0x26, + 0xc5, 0xe0, 0xfe, 0x59, 0xed, 0x8c, 0xfa, 0x16, 0x31, 0xee, 0xe3, 0xb1, 0x96, 0x11, 0xf8, 0xc6, + 0x7d, 0x3c, 0x16, 0x55, 0x50, 0x36, 0x29, 0x32, 0x93, 0xa5, 0xb4, 0x60, 0xa0, 0xfe, 0x4a, 0x01, + 0x17, 0x62, 0x03, 0xa2, 0xf3, 0xea, 0x8c, 0xfa, 0x82, 0x23, 0xb9, 0x7f, 0xca, 0x74, 0x47, 0x74, + 0x4c, 0xdb, 0xf9, 0x13, 0xb4, 0xbd, 0x09, 0x96, 0xe3, 0x54, 0x22, 0xf4, 0x4d, 0xcd, 0xa0, 0x6f, + 0x2e, 0xe2, 0xb8, 0x8f, 0xc7, 0xea, 0xcf, 0x12, 0xba, 0xdd, 0x1a, 0x27, 0x5c, 0xd8, 0x7b, 0x85, + 0x6e, 0xf1, 0xb2, 0x49, 0xdd, 0x8c, 0x24, 0xff, 0x31, 0x03, 0x52, 0xc7, 0x0d, 0x50, 0xff, 0xa2, + 0x80, 0x8d, 0xe4, 0xaa, 0xac, 0x47, 0x3b, 0xde, 0xc8, 0xc1, 0xfb, 0xbb, 0x67, 0xad, 0x7f, 0x13, + 0x64, 0x5c, 0x81, 0xd2, 0x39, 0x0b, 0x8f, 0x68, 0xb6, 0x92, 0xbd, 0x24, 0xb9, 0x7a, 0x22, 0xc4, + 0x57, 0xa7, 0x0c, 0x60, 0xe1, 0xce, 0x7d, 0x34, 0x53, 0xd0, 0x25, 0x02, 0x4a, 0x5b, 0x49, 0xda, + 0xcc, 0xd4, 0xaf, 0x14, 0x00, 0x8f, 0x67, 0x2b, 0xf8, 0x3d, 0x00, 0xa7, 0x72, 0x5e, 0xd2, 0xff, + 0xf2, 0x6e, 0x22, 0xcb, 0xc9, 0x9d, 0x8b, 0xfd, 0x68, 0x3e, 0xe1, 0x47, 0xf0, 0x07, 0x00, 0xb8, + 0xf2, 0x10, 0x67, 0x3e, 0xe9, 0xac, 0x1b, 0x7d, 0xc2, 0x12, 0xc8, 0xfd, 0x84, 0x12, 0x27, 0xf9, + 0x60, 0x91, 0xd2, 0x80, 0x98, 0x0a, 0xde, 0x22, 0xd4, 0x5f, 0x28, 0x93, 0x94, 0x18, 0x66, 0xeb, + 0xba, 0x65, 0x85, 0x3d, 0x20, 0x74, 0xc1, 0x52, 0x94, 0xef, 0x83, 0x70, 0xdd, 0x3e, 0xb1, 0x26, + 0x35, 0xb1, 0x21, 0xcb, 0xd2, 0x75, 0xb1, 0xe3, 0xbf, 0xfb, 0xae, 0x74, 0x75, 0x40, 0xf8, 0x70, + 0xd4, 0xaf, 0x1a, 0xd4, 0x0e, 0x1f, 0xa8, 0xc2, 0x7f, 0xd7, 0x98, 0x79, 0x58, 0xe3, 0x63, 0x17, + 0xb3, 0x88, 0x87, 0xfd, 0xf6, 0x1f, 0xbf, 0xbf, 0xa2, 0x68, 0xd1, 0x32, 0xaa, 0x09, 0xf2, 0xf1, + 0x1d, 0x04, 0x73, 0x64, 0x22, 0x8e, 0x20, 0x04, 0x69, 0x07, 0xd9, 0x51, 0x93, 0x29, 0xbf, 0x67, + 0xe8, 0x31, 0xb7, 0x40, 0xc6, 0x0e, 0x25, 0x84, 0xb7, 0x8e, 0x78, 0xac, 0xfe, 0x7c, 0x11, 0x94, + 0xa3, 0x65, 0xda, 0xc1, 0xdb, 0x0c, 0xf9, 0x69, 0xd0, 0x82, 0x8b, 0xce, 0x49, 0xd4, 0x6f, 0x76, + 0xc2, 0x7b, 0x8f, 0xf2, 0x76, 0xde, 0x7b, 0xe6, 0x5f, 0xf9, 0xde, 0x93, 0x7a, 0xc5, 0x7b, 0x4f, + 0xfa, 0xed, 0xbd, 0xf7, 0x2c, 0xbc, 0xf5, 0xf7, 0x9e, 0xc5, 0x77, 0xf4, 0xde, 0xb3, 0xf4, 0x3f, + 0x79, 0xef, 0xc9, 0xbc, 0xd5, 0xf7, 0x9e, 0xec, 0x9b, 0xbd, 0xf7, 0x80, 0x37, 0x7a, 0xef, 0xc9, + 0xcd, 0xf4, 0xde, 0xa3, 0x7e, 0x35, 0x0f, 0x36, 0xe4, 0x4d, 0xba, 0x3b, 0x44, 0xae, 0x38, 0xdc, + 0x49, 0x08, 0xc4, 0xd7, 0x73, 0x65, 0x86, 0xeb, 0xf9, 0xfc, 0xeb, 0x5d, 0xcf, 0x53, 0x33, 0x5c, + 0xcf, 0xd3, 0x67, 0x5d, 0xcf, 0x17, 0xce, 0xba, 0x9e, 0x2f, 0xce, 0x76, 0x3d, 0x5f, 0x3a, 0xe5, + 0x7a, 0x0e, 0x55, 0xb0, 0xec, 0x7a, 0x84, 0x8a, 0x3a, 0x90, 0x78, 0x0b, 0x98, 0x9a, 0x53, 0x4b, + 0x20, 0x17, 0x27, 0x11, 0x93, 0xc1, 0x3c, 0x48, 0x11, 0x33, 0x6a, 0x3a, 0xc5, 0xa7, 0xba, 0x03, + 0x2e, 0xd4, 0x23, 0xd5, 0xb1, 0x99, 0xbc, 0x41, 0xc3, 0x0d, 0xb0, 0x18, 0xdc, 0x62, 0x43, 0x7c, + 0x38, 0xba, 0xf2, 0x27, 0x05, 0xac, 0xc4, 0xcd, 0xc2, 0x10, 0x31, 0x0c, 0x8b, 0x60, 0xab, 0xf1, + 0x68, 0xaf, 0xfb, 0xf8, 0x61, 0x4b, 0xd3, 0x3b, 0x77, 0xeb, 0xdd, 0x96, 0xfe, 0x78, 0xaf, 0xdb, + 0x69, 0x35, 0xda, 0xb7, 0xdb, 0xad, 0x66, 0x7e, 0x0e, 0xbe, 0x0f, 0x36, 0x8f, 0xd0, 0xb5, 0xd6, + 0x9d, 0x76, 0xb7, 0xd7, 0xd2, 0x5a, 0xcd, 0xbc, 0x72, 0x02, 0x7b, 0x7b, 0xaf, 0xdd, 0x6b, 0xd7, + 0x1f, 0xb4, 0x9f, 0xb4, 0x9a, 0xf9, 0x79, 0x78, 0x11, 0x5c, 0x38, 0x42, 0x7f, 0x50, 0x7f, 0xbc, + 0xd7, 0xb8, 0xdb, 0x6a, 0xe6, 0x53, 0x70, 0x0b, 0x6c, 0x1c, 0x21, 0x76, 0x7b, 0x8f, 0x3a, 0x9d, + 0x56, 0x33, 0x9f, 0x3e, 0x81, 0xd6, 0x6c, 0x3d, 0x68, 0xf5, 0x5a, 0xcd, 0xfc, 0xc2, 0x56, 0xfa, + 0xb3, 0xdf, 0x14, 0xe7, 0x6e, 0x7d, 0xfa, 0xf5, 0x8b, 0xa2, 0xf2, 0xcd, 0x8b, 0xa2, 0xf2, 0xf7, + 0x17, 0x45, 0xe5, 0xf3, 0x97, 0xc5, 0xb9, 0x6f, 0x5e, 0x16, 0xe7, 0xfe, 0xf6, 0xb2, 0x38, 0xf7, + 0xe4, 0x93, 0xe3, 0x05, 0x62, 0x52, 0x80, 0xaf, 0xc5, 0xbf, 0x08, 0xf8, 0xdf, 0xaf, 0x3d, 0x9f, + 0xfe, 0x39, 0x46, 0xd6, 0x8e, 0xfe, 0xa2, 0x8c, 0xfd, 0x8f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, + 0x15, 0xc3, 0x5a, 0xbf, 0xbf, 0x19, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { @@ -3284,6 +3297,15 @@ func (m *PowerShapingParameters) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if len(m.Prioritylist) > 0 { + for iNdEx := len(m.Prioritylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Prioritylist[iNdEx]) + copy(dAtA[i:], m.Prioritylist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Prioritylist[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } if m.AllowInactiveVals { i-- if m.AllowInactiveVals { @@ -3977,6 +3999,12 @@ func (m *PowerShapingParameters) Size() (n int) { if m.AllowInactiveVals { n += 2 } + if len(m.Prioritylist) > 0 { + for _, s := range m.Prioritylist { + l = len(s) + n += 1 + l + sovProvider(uint64(l)) + } + } return n } @@ -8026,6 +8054,38 @@ func (m *PowerShapingParameters) Unmarshal(dAtA []byte) error { } } m.AllowInactiveVals = bool(v != 0) + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prioritylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prioritylist = append(m.Prioritylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:]) diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go index 578c12598e..f486a07b57 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -261,6 +261,11 @@ type Chain struct { ConsumerId string `protobuf:"bytes,13,opt,name=consumer_id,json=consumerId,proto3" json:"consumer_id,omitempty"` // the reward denoms allowlisted by this consumer chain AllowlistedRewardDenoms *AllowlistedRewardDenoms `protobuf:"bytes,14,opt,name=allowlisted_reward_denoms,json=allowlistedRewardDenoms,proto3" json:"allowlisted_reward_denoms,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that should have PRIORITY to validate on the consumer chain, + // meaning as long as they are eligible/opted in to validate on the consumer chain, the validator set will be + // filled with these validators first, and other validators will be added to the validator set only if there are + // not enough eligible priority validators. + Prioritylist []string `protobuf:"bytes,15,rep,name=prioritylist,proto3" json:"prioritylist,omitempty"` } func (m *Chain) Reset() { *m = Chain{} } @@ -394,6 +399,13 @@ func (m *Chain) GetAllowlistedRewardDenoms() *AllowlistedRewardDenoms { return nil } +func (m *Chain) GetPrioritylist() []string { + if m != nil { + return m.Prioritylist + } + return nil +} + type QueryValidatorConsumerAddrRequest struct { // The consensus address of the validator on the provider chain ProviderAddress string `protobuf:"bytes,1,opt,name=provider_address,json=providerAddress,proto3" json:"provider_address,omitempty" yaml:"address"` @@ -1857,161 +1869,162 @@ func init() { } var fileDescriptor_422512d7b7586cd7 = []byte{ - // 2450 bytes of a gzipped FileDescriptorProto + // 2465 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x5a, 0xcd, 0x6f, 0xdc, 0xc6, 0x15, 0x17, 0x57, 0x1f, 0x5e, 0x8d, 0x2c, 0x39, 0x1e, 0xcb, 0xd6, 0x7a, 0x65, 0x6b, 0x65, 0x3a, 0x6e, 0x15, 0x39, 0x5e, 0x4a, 0x2a, 0xf2, 0xe5, 0xc4, 0x1f, 0x5a, 0x59, 0xb2, 0x05, 0xc7, 0xb6, 0x42, 0x29, 0x0e, 0xe0, 0xd4, 0x65, 0x47, 0xe4, 0x64, 0x35, 0x15, 0x97, 0xa4, 0x39, 0xa3, 0xb5, - 0xb7, 0x86, 0x2f, 0x3d, 0xe5, 0xd0, 0x02, 0x09, 0x8a, 0x9e, 0x9b, 0x73, 0x0f, 0x45, 0x51, 0x04, - 0xfd, 0x07, 0x7a, 0xc9, 0xad, 0x69, 0x7a, 0x29, 0x5a, 0xd4, 0x6d, 0xed, 0x16, 0xe8, 0xa5, 0x28, - 0x9a, 0xf6, 0x0f, 0x08, 0x66, 0x38, 0xe4, 0x2e, 0x69, 0x4a, 0x4b, 0x6a, 0x75, 0x13, 0x67, 0xde, - 0xfb, 0xbd, 0x8f, 0x79, 0xf3, 0xe6, 0xbd, 0xb7, 0x02, 0x1a, 0x71, 0x18, 0xf6, 0xcd, 0x2d, 0x44, - 0x1c, 0x83, 0x62, 0x73, 0xc7, 0x27, 0xac, 0xa5, 0x99, 0x66, 0x53, 0xf3, 0x7c, 0xb7, 0x49, 0x2c, - 0xec, 0x6b, 0xcd, 0x79, 0xed, 0xc1, 0x0e, 0xf6, 0x5b, 0x55, 0xcf, 0x77, 0x99, 0x0b, 0xcf, 0xa6, - 0x30, 0x54, 0x4d, 0xb3, 0x59, 0x0d, 0x19, 0xaa, 0xcd, 0xf9, 0xf2, 0xa9, 0xba, 0xeb, 0xd6, 0x6d, - 0xac, 0x21, 0x8f, 0x68, 0xc8, 0x71, 0x5c, 0x86, 0x18, 0x71, 0x1d, 0x1a, 0x40, 0x94, 0xc7, 0xeb, - 0x6e, 0xdd, 0x15, 0x7f, 0x6a, 0xfc, 0x2f, 0xb9, 0x5a, 0x91, 0x3c, 0xe2, 0x6b, 0x73, 0xe7, 0x23, - 0x8d, 0x91, 0x06, 0xa6, 0x0c, 0x35, 0x3c, 0x49, 0xb0, 0x90, 0x45, 0xd5, 0x48, 0x8b, 0x80, 0x67, - 0x6e, 0x37, 0x9e, 0xe6, 0xbc, 0x46, 0xb7, 0x90, 0x8f, 0x2d, 0xc3, 0x74, 0x1d, 0xba, 0xd3, 0x88, - 0x38, 0xce, 0xed, 0xc1, 0xf1, 0x90, 0xf8, 0x58, 0x92, 0x9d, 0x62, 0xd8, 0xb1, 0xb0, 0xdf, 0x20, - 0x0e, 0xd3, 0x4c, 0xbf, 0xe5, 0x31, 0x57, 0xdb, 0xc6, 0xad, 0xd0, 0xc2, 0x93, 0xa6, 0x4b, 0x1b, - 0x2e, 0x35, 0x02, 0x23, 0x83, 0x0f, 0xb9, 0xf5, 0x72, 0xf0, 0xa5, 0x51, 0x86, 0xb6, 0x89, 0x53, - 0xd7, 0x9a, 0xf3, 0x9b, 0x98, 0xa1, 0xf9, 0xf0, 0x5b, 0x52, 0xcd, 0x4a, 0xaa, 0x4d, 0x44, 0x71, - 0xe0, 0xfe, 0x88, 0xd0, 0x43, 0x75, 0xe2, 0x08, 0x7f, 0x06, 0xb4, 0xea, 0x65, 0x30, 0xf9, 0x1e, - 0xa7, 0x58, 0x92, 0x86, 0x5c, 0xc7, 0x0e, 0xa6, 0x84, 0xea, 0xf8, 0xc1, 0x0e, 0xa6, 0x0c, 0x56, - 0xc0, 0x48, 0x68, 0xa2, 0x41, 0xac, 0x92, 0x32, 0xad, 0xcc, 0x0c, 0xeb, 0x20, 0x5c, 0x5a, 0xb5, - 0xd4, 0xc7, 0xe0, 0x54, 0x3a, 0x3f, 0xf5, 0x5c, 0x87, 0x62, 0xf8, 0x21, 0x18, 0xad, 0x07, 0x4b, - 0x06, 0x65, 0x88, 0x61, 0x01, 0x31, 0xb2, 0x30, 0x57, 0xdd, 0x2d, 0x12, 0x9a, 0xf3, 0xd5, 0x04, - 0xd6, 0x3a, 0xe7, 0xab, 0x0d, 0x7c, 0xf1, 0xb4, 0xd2, 0xa7, 0x1f, 0xae, 0x77, 0xac, 0xa9, 0xbf, - 0x54, 0x40, 0x39, 0x26, 0x7d, 0x89, 0xe3, 0x45, 0xca, 0xdf, 0x00, 0x83, 0xde, 0x16, 0xa2, 0x81, - 0xcc, 0xb1, 0x85, 0x85, 0x6a, 0x86, 0xe8, 0x8b, 0x84, 0xaf, 0x71, 0x4e, 0x3d, 0x00, 0x80, 0x2b, - 0x00, 0xb4, 0x3d, 0x57, 0x2a, 0x08, 0x13, 0xbe, 0x55, 0x95, 0x47, 0xc3, 0xdd, 0x5c, 0x0d, 0xa2, - 0x5c, 0xba, 0xb9, 0xba, 0x86, 0xea, 0x58, 0x6a, 0xa1, 0x77, 0x70, 0xaa, 0xbf, 0x50, 0x12, 0xee, - 0x0e, 0x15, 0x96, 0xde, 0xaa, 0x81, 0x21, 0xa1, 0x1e, 0x2d, 0x29, 0xd3, 0xfd, 0x33, 0x23, 0x0b, - 0xb3, 0xd9, 0x54, 0xe6, 0xdb, 0xba, 0xe4, 0x84, 0xd7, 0x53, 0x74, 0xfd, 0x76, 0x57, 0x5d, 0x03, - 0x05, 0x62, 0xca, 0xfe, 0x67, 0x00, 0x0c, 0x0a, 0x68, 0x78, 0x12, 0x14, 0x03, 0x15, 0xa2, 0x10, - 0x38, 0x24, 0xbe, 0x57, 0x2d, 0x38, 0x09, 0x86, 0x4d, 0x9b, 0x60, 0x87, 0xf1, 0xbd, 0x82, 0xd8, - 0x2b, 0x06, 0x0b, 0xab, 0x16, 0x3c, 0x06, 0x06, 0x99, 0xeb, 0x19, 0xb7, 0x4b, 0xfd, 0xd3, 0xca, - 0xcc, 0xa8, 0x3e, 0xc0, 0x5c, 0xef, 0x36, 0x9c, 0x05, 0xb0, 0x41, 0x1c, 0xc3, 0x73, 0x1f, 0xf2, - 0x98, 0x72, 0x8c, 0x80, 0x62, 0x60, 0x5a, 0x99, 0xe9, 0xd7, 0xc7, 0x1a, 0xc4, 0x59, 0xe3, 0x1b, - 0xab, 0xce, 0x06, 0xa7, 0x9d, 0x03, 0xe3, 0x4d, 0x64, 0x13, 0x0b, 0x31, 0xd7, 0xa7, 0x92, 0xc5, - 0x44, 0x5e, 0x69, 0x50, 0xe0, 0xc1, 0xf6, 0x9e, 0x60, 0x5a, 0x42, 0x1e, 0x9c, 0x05, 0x47, 0xa3, - 0x55, 0x83, 0x62, 0x26, 0xc8, 0x87, 0x04, 0xf9, 0x91, 0x68, 0x63, 0x1d, 0x33, 0x4e, 0x7b, 0x0a, - 0x0c, 0x23, 0xdb, 0x76, 0x1f, 0xda, 0x84, 0xb2, 0xd2, 0xa1, 0xe9, 0xfe, 0x99, 0x61, 0xbd, 0xbd, - 0x00, 0xcb, 0xa0, 0x68, 0x61, 0xa7, 0x25, 0x36, 0x8b, 0x62, 0x33, 0xfa, 0x86, 0xe3, 0x61, 0x64, - 0x0d, 0x0b, 0x8b, 0x65, 0x94, 0x7c, 0x00, 0x8a, 0x0d, 0xcc, 0x90, 0x85, 0x18, 0x2a, 0x01, 0xe1, - 0xf7, 0xd7, 0x72, 0x85, 0xdc, 0x2d, 0xc9, 0x2c, 0x63, 0x3d, 0x02, 0xe3, 0x4e, 0xe6, 0x2e, 0xe3, - 0xb7, 0x1c, 0x97, 0x46, 0xa6, 0x95, 0x99, 0x01, 0xbd, 0xd8, 0x20, 0xce, 0x3a, 0xff, 0x86, 0x55, - 0x70, 0x4c, 0x28, 0x6d, 0x10, 0x07, 0x99, 0x8c, 0x34, 0xb1, 0xd1, 0x44, 0x36, 0x2d, 0x1d, 0x9e, - 0x56, 0x66, 0x8a, 0xfa, 0x51, 0xb1, 0xb5, 0x2a, 0x77, 0xee, 0x22, 0x9b, 0x26, 0xaf, 0xf4, 0x68, - 0xf2, 0x4a, 0xc3, 0x47, 0xe0, 0x64, 0xe4, 0x05, 0x6c, 0x19, 0x3e, 0x7e, 0x88, 0x7c, 0xcb, 0xb0, - 0xb0, 0xe3, 0x36, 0x68, 0x69, 0x4c, 0xd8, 0xf5, 0x4e, 0x26, 0xbb, 0x16, 0xdb, 0x28, 0xba, 0x00, - 0xb9, 0x26, 0x30, 0xf4, 0x09, 0x94, 0xbe, 0xa1, 0xfe, 0x44, 0x01, 0x67, 0xc4, 0xf5, 0xb8, 0x1b, - 0x9e, 0x54, 0xe8, 0x9a, 0x45, 0xcb, 0xf2, 0xc3, 0x6b, 0x7d, 0x09, 0xbc, 0x14, 0x4a, 0x31, 0x90, - 0x65, 0xf9, 0x98, 0xd2, 0x20, 0x2a, 0x6b, 0xf0, 0xeb, 0xa7, 0x95, 0xb1, 0x16, 0x6a, 0xd8, 0x17, - 0x55, 0xb9, 0xa1, 0xea, 0x47, 0x42, 0xda, 0xc5, 0x60, 0x25, 0x69, 0x7f, 0x21, 0x69, 0xff, 0xc5, - 0xe2, 0xc7, 0x9f, 0x55, 0xfa, 0xfe, 0xf5, 0x59, 0xa5, 0x4f, 0xbd, 0x03, 0xd4, 0xbd, 0xd4, 0x91, - 0x97, 0xf6, 0x15, 0xf0, 0x52, 0x04, 0x18, 0xd3, 0x47, 0x3f, 0x62, 0x76, 0xd0, 0x73, 0x6d, 0x5e, - 0x34, 0x70, 0xad, 0x43, 0xbb, 0x0e, 0x03, 0xd3, 0x01, 0xd3, 0x0d, 0x4c, 0x08, 0xe9, 0xc9, 0xc0, - 0xb8, 0x3a, 0x6d, 0x03, 0xd3, 0x1d, 0xfe, 0x82, 0x73, 0xd5, 0x49, 0x70, 0x52, 0x00, 0x6e, 0x6c, - 0xf9, 0x2e, 0x63, 0x36, 0x16, 0x79, 0x5a, 0xda, 0xa5, 0xfe, 0x3e, 0x4c, 0xd7, 0x89, 0x5d, 0x29, - 0xa6, 0x02, 0x46, 0xa8, 0x8d, 0xe8, 0x96, 0xd1, 0xc0, 0x0c, 0xfb, 0x42, 0x42, 0xbf, 0x0e, 0xc4, - 0xd2, 0x2d, 0xbe, 0x02, 0x17, 0xc0, 0xf1, 0x0e, 0x02, 0x43, 0x44, 0x11, 0x72, 0x4c, 0x2c, 0x4c, - 0xec, 0xd7, 0x8f, 0xb5, 0x49, 0x17, 0xc3, 0x2d, 0xf8, 0x3d, 0x50, 0x72, 0xf0, 0x23, 0x66, 0xf8, - 0xd8, 0xb3, 0xb1, 0x43, 0xe8, 0x96, 0x61, 0x22, 0xc7, 0xe2, 0xc6, 0x62, 0x91, 0x95, 0x46, 0x16, - 0xca, 0xd5, 0xa0, 0x76, 0xa8, 0x86, 0xb5, 0x43, 0x75, 0x23, 0xac, 0x1d, 0x6a, 0x45, 0x7e, 0x11, - 0x3f, 0xf9, 0x6b, 0x45, 0xd1, 0x4f, 0x70, 0x14, 0x3d, 0x04, 0x59, 0x0a, 0x31, 0xd4, 0x57, 0xc1, - 0xac, 0x30, 0x49, 0xc7, 0x75, 0x1e, 0xcf, 0x3e, 0xb6, 0xc2, 0x18, 0x89, 0x85, 0xbc, 0xf4, 0xc0, - 0x32, 0x38, 0x9f, 0x89, 0x5a, 0x7a, 0xe4, 0x04, 0x18, 0x92, 0xd7, 0x4e, 0x11, 0x09, 0x48, 0x7e, - 0xa9, 0xef, 0x82, 0x57, 0x04, 0xcc, 0xa2, 0x6d, 0xaf, 0x21, 0xe2, 0xd3, 0xbb, 0xc8, 0xe6, 0x38, - 0xfc, 0x10, 0x6a, 0xad, 0x36, 0x62, 0xc6, 0x27, 0xfc, 0xe7, 0x8a, 0xb4, 0xa1, 0x0b, 0x9c, 0x54, - 0xea, 0x01, 0x38, 0xea, 0x21, 0xe2, 0xf3, 0x2c, 0xc3, 0xcb, 0x1f, 0x11, 0x11, 0xf2, 0xb9, 0x5a, - 0xc9, 0x94, 0x16, 0xb8, 0x8c, 0x40, 0x04, 0x97, 0x10, 0x45, 0x9c, 0xd3, 0xf6, 0xc5, 0x98, 0x17, - 0x23, 0x51, 0xff, 0xaf, 0x80, 0x33, 0x5d, 0xb9, 0xe0, 0xca, 0xae, 0x79, 0x61, 0xf2, 0xeb, 0xa7, - 0x95, 0x89, 0xe0, 0xda, 0x24, 0x29, 0x52, 0x12, 0xc4, 0x4a, 0xca, 0xf5, 0x2b, 0x24, 0x71, 0x92, - 0x14, 0x29, 0xf7, 0xf0, 0x0a, 0x38, 0x1c, 0x51, 0x6d, 0xe3, 0x96, 0x0c, 0xb7, 0x53, 0xd5, 0x76, - 0xf1, 0x57, 0x0d, 0x8a, 0xbf, 0xea, 0xda, 0xce, 0xa6, 0x4d, 0xcc, 0x9b, 0xb8, 0xa5, 0x47, 0x47, - 0x75, 0x13, 0xb7, 0xd4, 0x71, 0x00, 0xc5, 0xb9, 0xac, 0x21, 0x1f, 0xb5, 0x63, 0xe8, 0xfb, 0xe0, - 0x58, 0x6c, 0x55, 0x1e, 0xcb, 0x2a, 0x18, 0xf2, 0xc4, 0x8a, 0xac, 0xb0, 0xce, 0x67, 0x3c, 0x0b, - 0xce, 0x22, 0x1f, 0x1c, 0x09, 0xa0, 0xde, 0x92, 0xf1, 0x10, 0x2b, 0x52, 0xee, 0x78, 0x0c, 0x5b, - 0xab, 0x4e, 0x94, 0x29, 0xb2, 0x97, 0x88, 0x0f, 0x64, 0xd0, 0x77, 0x83, 0x8b, 0x6a, 0xa0, 0xd3, - 0x9d, 0x6f, 0x7e, 0xe2, 0xbc, 0x70, 0x78, 0x17, 0x26, 0x3b, 0x1e, 0xff, 0xf8, 0x01, 0x62, 0xaa, - 0x2e, 0x82, 0xa9, 0x98, 0xc8, 0x7d, 0x68, 0xfd, 0xe9, 0x21, 0x30, 0xbd, 0x0b, 0x46, 0xf4, 0x57, - 0xaf, 0x4f, 0x51, 0x32, 0x42, 0x0a, 0x39, 0x23, 0x04, 0x96, 0xc0, 0xa0, 0x28, 0x8a, 0x44, 0x6c, - 0xf5, 0xd7, 0x0a, 0x25, 0x45, 0x0f, 0x16, 0xe0, 0x5b, 0x60, 0xc0, 0xe7, 0x39, 0x6e, 0x40, 0x68, - 0x73, 0x8e, 0x9f, 0xef, 0x9f, 0x9e, 0x56, 0x26, 0x83, 0x32, 0x90, 0x5a, 0xdb, 0x55, 0xe2, 0x6a, - 0x0d, 0xc4, 0xb6, 0xaa, 0xef, 0xe2, 0x3a, 0x32, 0x5b, 0xd7, 0xb0, 0x59, 0x52, 0x74, 0xc1, 0x02, - 0xcf, 0x81, 0xb1, 0x48, 0xab, 0x00, 0x7d, 0x50, 0xe4, 0xd7, 0xd1, 0x70, 0x55, 0x14, 0x5b, 0xf0, - 0x3e, 0x28, 0x45, 0x64, 0xa6, 0xdb, 0x68, 0x10, 0x4a, 0x89, 0xeb, 0x18, 0x42, 0xea, 0x90, 0x90, - 0x7a, 0x36, 0x83, 0x54, 0xfd, 0x44, 0x08, 0xb2, 0x14, 0x61, 0xe8, 0x5c, 0x8b, 0xfb, 0xa0, 0x14, - 0xb9, 0x36, 0x09, 0x7f, 0x28, 0x07, 0x7c, 0x08, 0x92, 0x80, 0xbf, 0x09, 0x46, 0x2c, 0x4c, 0x4d, - 0x9f, 0x78, 0xa2, 0x4c, 0x2e, 0x0a, 0xcf, 0x9f, 0x0d, 0xcb, 0xe4, 0xb0, 0x9f, 0x0a, 0x6b, 0xe4, - 0x6b, 0x6d, 0x52, 0x79, 0x57, 0x3a, 0xb9, 0xe1, 0x7d, 0x70, 0x32, 0xd2, 0xd5, 0xf5, 0xb0, 0x2f, - 0x8a, 0xcf, 0x30, 0x1e, 0x44, 0x89, 0x58, 0x3b, 0xf3, 0xd5, 0xe7, 0x17, 0x4e, 0x4b, 0xf4, 0x28, - 0x7e, 0x64, 0x1c, 0xac, 0x33, 0x9f, 0x38, 0x75, 0x7d, 0x22, 0xc4, 0xb8, 0x23, 0x21, 0xc2, 0x30, - 0x39, 0x01, 0x86, 0x7e, 0x80, 0x88, 0x8d, 0x2d, 0x51, 0x55, 0x16, 0x75, 0xf9, 0x05, 0x2f, 0x82, - 0x21, 0xde, 0x53, 0xed, 0x50, 0x51, 0x13, 0x8e, 0x2d, 0xa8, 0xbb, 0xa9, 0x5f, 0x73, 0x1d, 0x6b, - 0x5d, 0x50, 0xea, 0x92, 0x03, 0x6e, 0x80, 0x28, 0x1a, 0x0d, 0xe6, 0x6e, 0x63, 0x27, 0xa8, 0x18, - 0x87, 0x6b, 0xe7, 0xa5, 0x57, 0x8f, 0xbf, 0xe8, 0xd5, 0x55, 0x87, 0x7d, 0xf5, 0xf9, 0x05, 0x20, - 0x85, 0xac, 0x3a, 0x4c, 0x1f, 0x0b, 0x31, 0x36, 0x04, 0x04, 0x0f, 0x9d, 0x08, 0x35, 0x08, 0x9d, - 0xd1, 0x20, 0x74, 0xc2, 0xd5, 0x20, 0x74, 0x5e, 0x07, 0x13, 0xf2, 0xf6, 0x62, 0x6a, 0x98, 0x3b, - 0xbe, 0xcf, 0xfb, 0x07, 0xec, 0xb9, 0xe6, 0x96, 0xa8, 0x2f, 0x8b, 0xfa, 0xf1, 0x68, 0x7b, 0x29, - 0xd8, 0x5d, 0xe6, 0x9b, 0xea, 0xc7, 0x0a, 0xa8, 0xec, 0x7a, 0xaf, 0x65, 0xfa, 0xc0, 0x00, 0xb4, - 0x33, 0x83, 0x7c, 0x97, 0x96, 0x33, 0xe5, 0xc2, 0x6e, 0xb7, 0x5d, 0xef, 0x00, 0x56, 0x1f, 0x80, - 0xb9, 0x94, 0x46, 0x2e, 0xa2, 0xbd, 0x81, 0xe8, 0x86, 0x2b, 0xbf, 0xf0, 0xc1, 0x14, 0xae, 0xea, - 0x5d, 0x30, 0x9f, 0x43, 0xa4, 0x74, 0xc7, 0x99, 0x8e, 0x14, 0x43, 0xac, 0x30, 0x79, 0x8e, 0xb4, - 0x13, 0x9d, 0x28, 0x4a, 0xcf, 0xa7, 0x97, 0xb9, 0xf1, 0x3b, 0x93, 0x35, 0x75, 0xa6, 0xda, 0x59, - 0xc8, 0x6e, 0x67, 0x1d, 0xbc, 0x9a, 0x4d, 0x1d, 0x69, 0xe2, 0x1b, 0x32, 0xd5, 0x29, 0xd9, 0xb3, - 0x82, 0x60, 0x50, 0x55, 0x99, 0xe1, 0x6b, 0xb6, 0x6b, 0x6e, 0xd3, 0xf7, 0x1d, 0x46, 0xec, 0xdb, - 0xf8, 0x51, 0x10, 0x6b, 0xe1, 0x6b, 0x7b, 0x4f, 0x16, 0xec, 0xe9, 0x34, 0x52, 0x83, 0xd7, 0xc0, - 0xc4, 0xa6, 0xd8, 0x37, 0x76, 0x38, 0x81, 0x21, 0x2a, 0xce, 0x20, 0x9e, 0x15, 0xd1, 0xad, 0x8d, - 0x6f, 0xa6, 0xb0, 0xab, 0x8b, 0xb2, 0xfa, 0x5e, 0x8a, 0x5c, 0xb7, 0xe2, 0xbb, 0x8d, 0x25, 0xd9, - 0x3d, 0x87, 0xee, 0x8e, 0x75, 0xd8, 0x4a, 0xbc, 0xc3, 0x56, 0x57, 0xc0, 0xd9, 0x3d, 0x21, 0xda, - 0xa5, 0xf5, 0xde, 0xaf, 0xdd, 0x3b, 0xb2, 0x6e, 0x8f, 0xc5, 0x56, 0xe6, 0xb7, 0xf2, 0xb7, 0xfd, - 0x69, 0x73, 0x98, 0xcc, 0xd2, 0x63, 0xf3, 0x85, 0x42, 0x7c, 0xbe, 0x70, 0x16, 0x8c, 0xba, 0x0f, - 0x9d, 0x8e, 0x40, 0xea, 0x17, 0xfb, 0x87, 0xc5, 0x62, 0x98, 0x20, 0xa3, 0x76, 0x7c, 0x60, 0xb7, - 0x76, 0x7c, 0xf0, 0x20, 0xdb, 0xf1, 0x8f, 0xc0, 0x08, 0x71, 0x08, 0x33, 0x64, 0xbd, 0x35, 0x24, - 0xb0, 0x97, 0x73, 0x61, 0xaf, 0x3a, 0x84, 0x11, 0x64, 0x93, 0x1f, 0x8a, 0x51, 0x8b, 0xa8, 0xc2, - 0x78, 0xdf, 0x42, 0x75, 0xc0, 0x91, 0x83, 0xaa, 0x0c, 0x36, 0xc0, 0x78, 0x30, 0xf2, 0xa0, 0x5b, - 0xc8, 0x23, 0x4e, 0x3d, 0x14, 0x78, 0x48, 0x08, 0x7c, 0x3b, 0x5b, 0x81, 0xc7, 0x01, 0xd6, 0x03, - 0xfe, 0x0e, 0x31, 0xd0, 0x4b, 0xae, 0xd3, 0x85, 0xbf, 0x9f, 0x06, 0x83, 0xe2, 0x14, 0xe1, 0x3f, - 0x15, 0x30, 0x9e, 0x36, 0xd5, 0x83, 0x57, 0xf3, 0x27, 0xd2, 0xf8, 0x40, 0xb1, 0xbc, 0xd8, 0x03, - 0x42, 0x10, 0x4e, 0xea, 0x8d, 0x1f, 0xfd, 0xe1, 0x1f, 0x3f, 0x2d, 0xd4, 0xe0, 0xd5, 0xee, 0xe3, - 0xe7, 0x28, 0xec, 0xe4, 0xd8, 0x50, 0x7b, 0xdc, 0x11, 0x88, 0x4f, 0xe0, 0x9f, 0x15, 0x59, 0x4b, - 0xc7, 0x53, 0x2a, 0xbc, 0x92, 0x5f, 0xc9, 0xd8, 0xe4, 0xb1, 0x7c, 0x75, 0xff, 0x00, 0xd2, 0xc8, - 0x45, 0x61, 0xe4, 0xdb, 0xf0, 0xad, 0x1c, 0x46, 0x06, 0x03, 0x40, 0xed, 0xb1, 0x08, 0xff, 0x27, - 0xf0, 0xd3, 0x82, 0xbc, 0x95, 0xa9, 0xe3, 0x0b, 0xb8, 0x92, 0x5d, 0xc7, 0xbd, 0xc6, 0x31, 0xe5, - 0xeb, 0x3d, 0xe3, 0x48, 0x93, 0x37, 0x85, 0xc9, 0xdf, 0x85, 0xf7, 0x32, 0xfc, 0xac, 0x10, 0x8d, - 0xf8, 0x62, 0x7d, 0x58, 0xfc, 0x78, 0xb5, 0xc7, 0xc9, 0x57, 0x28, 0xcd, 0x27, 0x9d, 0xcd, 0xc3, - 0xbe, 0x7c, 0x92, 0x32, 0xc1, 0xd9, 0x97, 0x4f, 0xd2, 0x46, 0x2f, 0xfb, 0xf3, 0x49, 0xcc, 0xec, - 0xa4, 0x4f, 0x92, 0x8d, 0xeb, 0x13, 0xf8, 0x3b, 0x45, 0xf6, 0x99, 0xb1, 0xb1, 0x0c, 0xbc, 0x9c, - 0xdd, 0x86, 0xb4, 0x69, 0x4f, 0xf9, 0xca, 0xbe, 0xf9, 0xa5, 0xed, 0x6f, 0x0a, 0xdb, 0x17, 0xe0, - 0x5c, 0x77, 0xdb, 0x99, 0x04, 0x08, 0x7e, 0x63, 0x80, 0x3f, 0x2b, 0xc8, 0x67, 0x71, 0xef, 0x39, - 0x0b, 0xbc, 0x93, 0x5d, 0xc5, 0x4c, 0xf3, 0x9d, 0xf2, 0xda, 0xc1, 0x01, 0x4a, 0x27, 0xdc, 0x14, - 0x4e, 0x58, 0x86, 0x4b, 0xdd, 0x9d, 0xe0, 0x47, 0x88, 0xed, 0x5b, 0x11, 0x1b, 0xde, 0xc2, 0x1f, - 0x17, 0x64, 0xc5, 0xb1, 0xe7, 0xa4, 0x07, 0xde, 0xce, 0x6e, 0x45, 0x96, 0x09, 0x54, 0xf9, 0xce, - 0x81, 0xe1, 0x49, 0xa7, 0x2c, 0x0b, 0xa7, 0x5c, 0x81, 0x97, 0xba, 0x3b, 0x45, 0x46, 0xb9, 0xe1, - 0x71, 0xd4, 0x44, 0xfa, 0xff, 0xb5, 0x02, 0x46, 0x3a, 0x46, 0x29, 0xf0, 0x8d, 0xec, 0x7a, 0xc6, - 0x46, 0x32, 0xe5, 0x37, 0xf3, 0x33, 0x4a, 0x4b, 0xe6, 0x84, 0x25, 0xb3, 0x70, 0xa6, 0xbb, 0x25, - 0xc1, 0xe3, 0xdf, 0x8e, 0xed, 0xbd, 0xc7, 0x29, 0x79, 0x62, 0x3b, 0xd3, 0x9c, 0x27, 0x4f, 0x6c, - 0x67, 0x9b, 0xf4, 0xe4, 0x89, 0x6d, 0x97, 0x83, 0x18, 0xc4, 0x31, 0xda, 0x2d, 0x58, 0xe2, 0x30, - 0x7f, 0x53, 0x90, 0x43, 0xd1, 0x2c, 0xed, 0x11, 0x7c, 0x7f, 0xbf, 0x0f, 0xf4, 0x9e, 0x1d, 0x5e, - 0xf9, 0xee, 0x41, 0xc3, 0x4a, 0x4f, 0xdd, 0x13, 0x9e, 0xda, 0x80, 0x7a, 0xee, 0x6a, 0xc0, 0xf0, - 0xb0, 0xdf, 0x76, 0x5a, 0xda, 0x93, 0xf8, 0xab, 0x02, 0x78, 0x39, 0x4b, 0xbf, 0x05, 0xd7, 0x7a, - 0x78, 0xe8, 0x53, 0x3b, 0xc9, 0xf2, 0x7b, 0x07, 0x88, 0x28, 0x3d, 0x65, 0x0a, 0x4f, 0xdd, 0x87, - 0x1f, 0xe6, 0xf1, 0x54, 0x7c, 0xbc, 0xd4, 0xbd, 0x8a, 0xf8, 0xaf, 0x02, 0x26, 0x76, 0x99, 0x16, - 0xc0, 0xa5, 0x5e, 0x66, 0x0d, 0xa1, 0x63, 0xae, 0xf5, 0x06, 0x92, 0xff, 0x7e, 0x45, 0x16, 0xef, - 0x7a, 0xbf, 0xfe, 0xad, 0xc8, 0x16, 0x31, 0xad, 0x13, 0x86, 0x39, 0x26, 0x2c, 0x7b, 0x74, 0xdb, - 0xe5, 0x95, 0x5e, 0x61, 0xf2, 0x57, 0xcf, 0xbb, 0x34, 0xee, 0xf0, 0x7f, 0xc9, 0x9f, 0xea, 0xe3, - 0xad, 0x35, 0xbc, 0x9e, 0xff, 0x88, 0x52, 0xfb, 0xfb, 0xf2, 0x8d, 0xde, 0x81, 0x7a, 0xe8, 0x19, - 0x88, 0xa5, 0x3d, 0x8e, 0xc6, 0x0b, 0x4f, 0xe0, 0x5f, 0xc2, 0x5a, 0x30, 0x96, 0x9e, 0xf2, 0xd4, - 0x82, 0x69, 0x13, 0x84, 0xf2, 0x95, 0x7d, 0xf3, 0x4b, 0xd3, 0x56, 0x84, 0x69, 0x57, 0xe1, 0xe5, - 0xbc, 0x09, 0x30, 0x1e, 0xc5, 0xb5, 0x0f, 0xbe, 0x78, 0x36, 0xa5, 0x7c, 0xf9, 0x6c, 0x4a, 0xf9, - 0xdb, 0xb3, 0x29, 0xe5, 0x93, 0xe7, 0x53, 0x7d, 0x5f, 0x3e, 0x9f, 0xea, 0xfb, 0xe3, 0xf3, 0xa9, - 0xbe, 0x7b, 0x97, 0xea, 0x84, 0x6d, 0xed, 0x6c, 0x56, 0x4d, 0xb7, 0x21, 0xff, 0xe7, 0xa6, 0x43, - 0xd4, 0x85, 0x48, 0x54, 0xf3, 0x75, 0xed, 0x51, 0xa2, 0xf6, 0x6c, 0x79, 0x98, 0x6e, 0x0e, 0x89, - 0x5f, 0x0f, 0xbf, 0xf3, 0x4d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x98, 0xe8, 0xa5, 0x6b, 0x13, 0x25, - 0x00, 0x00, + 0xb7, 0x86, 0x2f, 0x3d, 0xe5, 0xd0, 0x02, 0x09, 0x82, 0x9e, 0x9b, 0x73, 0x0f, 0x45, 0x51, 0x04, + 0xfd, 0x07, 0x7a, 0xc9, 0xad, 0x69, 0x7a, 0x29, 0x5a, 0xd4, 0x6d, 0xed, 0x16, 0xe8, 0xa5, 0x87, + 0xa6, 0xfd, 0x03, 0x82, 0x19, 0x0e, 0xb9, 0x4b, 0x9a, 0xd2, 0x92, 0x5a, 0xdd, 0xc4, 0x99, 0xf7, + 0x7e, 0xf3, 0xde, 0x9b, 0xf7, 0xde, 0xbc, 0xf7, 0x56, 0x40, 0x23, 0x0e, 0xc3, 0xbe, 0xb9, 0x85, + 0x88, 0x63, 0x50, 0x6c, 0xee, 0xf8, 0x84, 0xb5, 0x34, 0xd3, 0x6c, 0x6a, 0x9e, 0xef, 0x36, 0x89, + 0x85, 0x7d, 0xad, 0x39, 0xaf, 0x3d, 0xd8, 0xc1, 0x7e, 0xab, 0xea, 0xf9, 0x2e, 0x73, 0xe1, 0xd9, + 0x14, 0x86, 0xaa, 0x69, 0x36, 0xab, 0x21, 0x43, 0xb5, 0x39, 0x5f, 0x3e, 0x55, 0x77, 0xdd, 0xba, + 0x8d, 0x35, 0xe4, 0x11, 0x0d, 0x39, 0x8e, 0xcb, 0x10, 0x23, 0xae, 0x43, 0x03, 0x88, 0xf2, 0x78, + 0xdd, 0xad, 0xbb, 0xe2, 0x4f, 0x8d, 0xff, 0x25, 0x57, 0x2b, 0x92, 0x47, 0x7c, 0x6d, 0xee, 0x7c, + 0xa4, 0x31, 0xd2, 0xc0, 0x94, 0xa1, 0x86, 0x27, 0x09, 0x16, 0xb2, 0x88, 0x1a, 0x49, 0x11, 0xf0, + 0xcc, 0xed, 0xc6, 0xd3, 0x9c, 0xd7, 0xe8, 0x16, 0xf2, 0xb1, 0x65, 0x98, 0xae, 0x43, 0x77, 0x1a, + 0x11, 0xc7, 0xb9, 0x3d, 0x38, 0x1e, 0x12, 0x1f, 0x4b, 0xb2, 0x53, 0x0c, 0x3b, 0x16, 0xf6, 0x1b, + 0xc4, 0x61, 0x9a, 0xe9, 0xb7, 0x3c, 0xe6, 0x6a, 0xdb, 0xb8, 0x15, 0x6a, 0x78, 0xd2, 0x74, 0x69, + 0xc3, 0xa5, 0x46, 0xa0, 0x64, 0xf0, 0x21, 0xb7, 0x5e, 0x0e, 0xbe, 0x34, 0xca, 0xd0, 0x36, 0x71, + 0xea, 0x5a, 0x73, 0x7e, 0x13, 0x33, 0x34, 0x1f, 0x7e, 0x4b, 0xaa, 0x59, 0x49, 0xb5, 0x89, 0x28, + 0x0e, 0xcc, 0x1f, 0x11, 0x7a, 0xa8, 0x4e, 0x1c, 0x61, 0xcf, 0x80, 0x56, 0xbd, 0x0c, 0x26, 0xdf, + 0xe3, 0x14, 0x4b, 0x52, 0x91, 0xeb, 0xd8, 0xc1, 0x94, 0x50, 0x1d, 0x3f, 0xd8, 0xc1, 0x94, 0xc1, + 0x0a, 0x18, 0x09, 0x55, 0x34, 0x88, 0x55, 0x52, 0xa6, 0x95, 0x99, 0x61, 0x1d, 0x84, 0x4b, 0xab, + 0x96, 0xfa, 0x18, 0x9c, 0x4a, 0xe7, 0xa7, 0x9e, 0xeb, 0x50, 0x0c, 0x3f, 0x04, 0xa3, 0xf5, 0x60, + 0xc9, 0xa0, 0x0c, 0x31, 0x2c, 0x20, 0x46, 0x16, 0xe6, 0xaa, 0xbb, 0x79, 0x42, 0x73, 0xbe, 0x9a, + 0xc0, 0x5a, 0xe7, 0x7c, 0xb5, 0x81, 0x2f, 0x9f, 0x56, 0xfa, 0xf4, 0xc3, 0xf5, 0x8e, 0x35, 0xf5, + 0x57, 0x0a, 0x28, 0xc7, 0x4e, 0x5f, 0xe2, 0x78, 0x91, 0xf0, 0x37, 0xc0, 0xa0, 0xb7, 0x85, 0x68, + 0x70, 0xe6, 0xd8, 0xc2, 0x42, 0x35, 0x83, 0xf7, 0x45, 0x87, 0xaf, 0x71, 0x4e, 0x3d, 0x00, 0x80, + 0x2b, 0x00, 0xb4, 0x2d, 0x57, 0x2a, 0x08, 0x15, 0xbe, 0x53, 0x95, 0x57, 0xc3, 0xcd, 0x5c, 0x0d, + 0xbc, 0x5c, 0x9a, 0xb9, 0xba, 0x86, 0xea, 0x58, 0x4a, 0xa1, 0x77, 0x70, 0xaa, 0xbf, 0x54, 0x12, + 0xe6, 0x0e, 0x05, 0x96, 0xd6, 0xaa, 0x81, 0x21, 0x21, 0x1e, 0x2d, 0x29, 0xd3, 0xfd, 0x33, 0x23, + 0x0b, 0xb3, 0xd9, 0x44, 0xe6, 0xdb, 0xba, 0xe4, 0x84, 0xd7, 0x53, 0x64, 0xfd, 0x6e, 0x57, 0x59, + 0x03, 0x01, 0x62, 0xc2, 0x7e, 0x36, 0x08, 0x06, 0x05, 0x34, 0x3c, 0x09, 0x8a, 0x81, 0x08, 0x91, + 0x0b, 0x1c, 0x12, 0xdf, 0xab, 0x16, 0x9c, 0x04, 0xc3, 0xa6, 0x4d, 0xb0, 0xc3, 0xf8, 0x5e, 0x41, + 0xec, 0x15, 0x83, 0x85, 0x55, 0x0b, 0x1e, 0x03, 0x83, 0xcc, 0xf5, 0x8c, 0xdb, 0xa5, 0xfe, 0x69, + 0x65, 0x66, 0x54, 0x1f, 0x60, 0xae, 0x77, 0x1b, 0xce, 0x02, 0xd8, 0x20, 0x8e, 0xe1, 0xb9, 0x0f, + 0xb9, 0x4f, 0x39, 0x46, 0x40, 0x31, 0x30, 0xad, 0xcc, 0xf4, 0xeb, 0x63, 0x0d, 0xe2, 0xac, 0xf1, + 0x8d, 0x55, 0x67, 0x83, 0xd3, 0xce, 0x81, 0xf1, 0x26, 0xb2, 0x89, 0x85, 0x98, 0xeb, 0x53, 0xc9, + 0x62, 0x22, 0xaf, 0x34, 0x28, 0xf0, 0x60, 0x7b, 0x4f, 0x30, 0x2d, 0x21, 0x0f, 0xce, 0x82, 0xa3, + 0xd1, 0xaa, 0x41, 0x31, 0x13, 0xe4, 0x43, 0x82, 0xfc, 0x48, 0xb4, 0xb1, 0x8e, 0x19, 0xa7, 0x3d, + 0x05, 0x86, 0x91, 0x6d, 0xbb, 0x0f, 0x6d, 0x42, 0x59, 0xe9, 0xd0, 0x74, 0xff, 0xcc, 0xb0, 0xde, + 0x5e, 0x80, 0x65, 0x50, 0xb4, 0xb0, 0xd3, 0x12, 0x9b, 0x45, 0xb1, 0x19, 0x7d, 0xc3, 0xf1, 0xd0, + 0xb3, 0x86, 0x85, 0xc6, 0xd2, 0x4b, 0x3e, 0x00, 0xc5, 0x06, 0x66, 0xc8, 0x42, 0x0c, 0x95, 0x80, + 0xb0, 0xfb, 0x6b, 0xb9, 0x5c, 0xee, 0x96, 0x64, 0x96, 0xbe, 0x1e, 0x81, 0x71, 0x23, 0x73, 0x93, + 0xf1, 0x28, 0xc7, 0xa5, 0x91, 0x69, 0x65, 0x66, 0x40, 0x2f, 0x36, 0x88, 0xb3, 0xce, 0xbf, 0x61, + 0x15, 0x1c, 0x13, 0x42, 0x1b, 0xc4, 0x41, 0x26, 0x23, 0x4d, 0x6c, 0x34, 0x91, 0x4d, 0x4b, 0x87, + 0xa7, 0x95, 0x99, 0xa2, 0x7e, 0x54, 0x6c, 0xad, 0xca, 0x9d, 0xbb, 0xc8, 0xa6, 0xc9, 0x90, 0x1e, + 0x4d, 0x86, 0x34, 0x7c, 0x04, 0x4e, 0x46, 0x56, 0xc0, 0x96, 0xe1, 0xe3, 0x87, 0xc8, 0xb7, 0x0c, + 0x0b, 0x3b, 0x6e, 0x83, 0x96, 0xc6, 0x84, 0x5e, 0xef, 0x64, 0xd2, 0x6b, 0xb1, 0x8d, 0xa2, 0x0b, + 0x90, 0x6b, 0x02, 0x43, 0x9f, 0x40, 0xe9, 0x1b, 0x50, 0x05, 0x87, 0x3d, 0x9f, 0xb8, 0x1c, 0x4c, + 0x98, 0xfd, 0x88, 0x30, 0x7b, 0x6c, 0x4d, 0xfd, 0x99, 0x02, 0xce, 0x88, 0x10, 0xba, 0x1b, 0xde, + 0x66, 0x68, 0xbe, 0x45, 0xcb, 0xf2, 0xc3, 0xd0, 0xbf, 0x04, 0x5e, 0x0a, 0x25, 0x31, 0x90, 0x65, + 0xf9, 0x98, 0xd2, 0xc0, 0x73, 0x6b, 0xf0, 0x9b, 0xa7, 0x95, 0xb1, 0x16, 0x6a, 0xd8, 0x17, 0x55, + 0xb9, 0xa1, 0xea, 0x47, 0x42, 0xda, 0xc5, 0x60, 0x25, 0x69, 0xa3, 0x42, 0xd2, 0x46, 0x17, 0x8b, + 0x1f, 0x7f, 0x5e, 0xe9, 0xfb, 0xf7, 0xe7, 0x95, 0x3e, 0xf5, 0x0e, 0x50, 0xf7, 0x12, 0x47, 0x06, + 0xf6, 0x2b, 0xe0, 0xa5, 0x08, 0x30, 0x26, 0x8f, 0x7e, 0xc4, 0xec, 0xa0, 0xe7, 0xd2, 0xbc, 0xa8, + 0xe0, 0x5a, 0x87, 0x74, 0x1d, 0x0a, 0xa6, 0x03, 0xa6, 0x2b, 0x98, 0x38, 0xa4, 0x27, 0x05, 0xe3, + 0xe2, 0xb4, 0x15, 0x4c, 0x37, 0xf8, 0x0b, 0xc6, 0x55, 0x27, 0xc1, 0x49, 0x01, 0xb8, 0xb1, 0xe5, + 0xbb, 0x8c, 0xd9, 0x58, 0xe4, 0x72, 0xa9, 0x97, 0xfa, 0x87, 0x30, 0xa5, 0x27, 0x76, 0xe5, 0x31, + 0x15, 0x30, 0x42, 0x6d, 0x44, 0xb7, 0x8c, 0x06, 0x66, 0xd8, 0x17, 0x27, 0xf4, 0xeb, 0x40, 0x2c, + 0xdd, 0xe2, 0x2b, 0x70, 0x01, 0x1c, 0xef, 0x20, 0x30, 0x84, 0xa7, 0x21, 0xc7, 0xc4, 0x42, 0xc5, + 0x7e, 0xfd, 0x58, 0x9b, 0x74, 0x31, 0xdc, 0x82, 0x3f, 0x00, 0x25, 0x07, 0x3f, 0x62, 0x86, 0x8f, + 0x3d, 0x1b, 0x3b, 0x84, 0x6e, 0x19, 0x26, 0x72, 0x2c, 0xae, 0x2c, 0x16, 0x99, 0x6b, 0x64, 0xa1, + 0x5c, 0x0d, 0xea, 0x8b, 0x6a, 0x58, 0x5f, 0x54, 0x37, 0xc2, 0xfa, 0xa2, 0x56, 0xe4, 0xc1, 0xfa, + 0xc9, 0xdf, 0x2a, 0x8a, 0x7e, 0x82, 0xa3, 0xe8, 0x21, 0xc8, 0x52, 0x88, 0xa1, 0xbe, 0x0a, 0x66, + 0x85, 0x4a, 0x3a, 0xae, 0x73, 0x9f, 0xf7, 0xb1, 0x15, 0xfa, 0x48, 0x2c, 0x2c, 0xa4, 0x05, 0x96, + 0xc1, 0xf9, 0x4c, 0xd4, 0xd2, 0x22, 0x27, 0xc0, 0x90, 0x0c, 0x4d, 0x45, 0x44, 0x8b, 0xfc, 0x52, + 0xdf, 0x05, 0xaf, 0x08, 0x98, 0x45, 0xdb, 0x5e, 0x43, 0xc4, 0xa7, 0x77, 0x91, 0xcd, 0x71, 0xf8, + 0x25, 0xd4, 0x5a, 0x6d, 0xc4, 0x8c, 0xcf, 0xfc, 0x2f, 0x14, 0xa9, 0x43, 0x17, 0x38, 0x29, 0xd4, + 0x03, 0x70, 0xd4, 0x43, 0xc4, 0xe7, 0x99, 0x88, 0x97, 0x48, 0xc2, 0x23, 0xe4, 0x93, 0xb6, 0x92, + 0x29, 0x75, 0xf0, 0x33, 0x82, 0x23, 0xf8, 0x09, 0x91, 0xc7, 0x39, 0x6d, 0x5b, 0x8c, 0x79, 0x31, + 0x12, 0xf5, 0xff, 0x0a, 0x38, 0xd3, 0x95, 0x0b, 0xae, 0xec, 0x9a, 0x17, 0x26, 0xbf, 0x79, 0x5a, + 0x99, 0x08, 0xc2, 0x26, 0x49, 0x91, 0x92, 0x20, 0x56, 0x52, 0xc2, 0xaf, 0x90, 0xc4, 0x49, 0x52, + 0xa4, 0xc4, 0xe1, 0x15, 0x70, 0x38, 0xa2, 0xda, 0xc6, 0x2d, 0xe9, 0x6e, 0xa7, 0xaa, 0xed, 0x02, + 0xb1, 0x1a, 0x14, 0x88, 0xd5, 0xb5, 0x9d, 0x4d, 0x9b, 0x98, 0x37, 0x71, 0x4b, 0x8f, 0xae, 0xea, + 0x26, 0x6e, 0xa9, 0xe3, 0x00, 0x8a, 0x7b, 0x59, 0x43, 0x3e, 0x6a, 0xfb, 0xd0, 0x0f, 0xc1, 0xb1, + 0xd8, 0xaa, 0xbc, 0x96, 0x55, 0x30, 0xe4, 0x89, 0x15, 0x59, 0x85, 0x9d, 0xcf, 0x78, 0x17, 0x9c, + 0x45, 0x3e, 0x4a, 0x12, 0x40, 0xbd, 0x25, 0xfd, 0x21, 0x56, 0xc8, 0xdc, 0xf1, 0x18, 0xb6, 0x56, + 0x9d, 0x28, 0x53, 0x64, 0x2f, 0x23, 0x1f, 0x48, 0xa7, 0xef, 0x06, 0x17, 0xd5, 0x49, 0xa7, 0x3b, + 0xeb, 0x82, 0xc4, 0x7d, 0xe1, 0x30, 0x16, 0x26, 0x3b, 0x0a, 0x84, 0xf8, 0x05, 0x62, 0xaa, 0x2e, + 0x82, 0xa9, 0xd8, 0x91, 0xfb, 0x90, 0xfa, 0xd3, 0x43, 0x60, 0x7a, 0x17, 0x8c, 0xe8, 0xaf, 0x5e, + 0x9f, 0xa2, 0xa4, 0x87, 0x14, 0x72, 0x7a, 0x08, 0x2c, 0x81, 0x41, 0x51, 0x38, 0x09, 0xdf, 0xea, + 0xaf, 0x15, 0x4a, 0x8a, 0x1e, 0x2c, 0xc0, 0xb7, 0xc0, 0x80, 0xcf, 0x73, 0xdc, 0x80, 0x90, 0xe6, + 0x1c, 0xbf, 0xdf, 0x3f, 0x3f, 0xad, 0x4c, 0x06, 0xa5, 0x22, 0xb5, 0xb6, 0xab, 0xc4, 0xd5, 0x1a, + 0x88, 0x6d, 0x55, 0xdf, 0xc5, 0x75, 0x64, 0xb6, 0xae, 0x61, 0xb3, 0xa4, 0xe8, 0x82, 0x05, 0x9e, + 0x03, 0x63, 0x91, 0x54, 0x01, 0xfa, 0xa0, 0xc8, 0xaf, 0xa3, 0xe1, 0xaa, 0x28, 0xc8, 0xe0, 0x7d, + 0x50, 0x8a, 0xc8, 0x4c, 0xb7, 0xd1, 0x20, 0x94, 0x12, 0xd7, 0x31, 0xc4, 0xa9, 0x43, 0xe2, 0xd4, + 0xb3, 0x19, 0x4e, 0xd5, 0x4f, 0x84, 0x20, 0x4b, 0x11, 0x86, 0xce, 0xa5, 0xb8, 0x0f, 0x4a, 0x91, + 0x69, 0x93, 0xf0, 0x87, 0x72, 0xc0, 0x87, 0x20, 0x09, 0xf8, 0x9b, 0x60, 0xc4, 0xc2, 0xd4, 0xf4, + 0x89, 0x27, 0x4a, 0xe9, 0xa2, 0xb0, 0xfc, 0xd9, 0xb0, 0x94, 0x0e, 0x7b, 0xae, 0xb0, 0x8e, 0xbe, + 0xd6, 0x26, 0x95, 0xb1, 0xd2, 0xc9, 0x0d, 0xef, 0x83, 0x93, 0x91, 0xac, 0xae, 0x87, 0x7d, 0x51, + 0xa0, 0x86, 0xfe, 0x20, 0xca, 0xc8, 0xda, 0x99, 0xaf, 0xbf, 0xb8, 0x70, 0x5a, 0xa2, 0x47, 0xfe, + 0x23, 0xfd, 0x60, 0x9d, 0xf9, 0xc4, 0xa9, 0xeb, 0x13, 0x21, 0xc6, 0x1d, 0x09, 0x11, 0xba, 0xc9, + 0x09, 0x30, 0xf4, 0x23, 0x44, 0x6c, 0x6c, 0x89, 0xca, 0xb3, 0xa8, 0xcb, 0x2f, 0x78, 0x11, 0x0c, + 0xf1, 0xbe, 0x6b, 0x87, 0x8a, 0xba, 0x71, 0x6c, 0x41, 0xdd, 0x4d, 0xfc, 0x9a, 0xeb, 0x58, 0xeb, + 0x82, 0x52, 0x97, 0x1c, 0x70, 0x03, 0x44, 0xde, 0x68, 0x30, 0x77, 0x1b, 0x3b, 0x41, 0x55, 0x39, + 0x5c, 0x3b, 0x2f, 0xad, 0x7a, 0xfc, 0x45, 0xab, 0xae, 0x3a, 0xec, 0xeb, 0x2f, 0x2e, 0x00, 0x79, + 0xc8, 0xaa, 0xc3, 0xf4, 0xb1, 0x10, 0x63, 0x43, 0x40, 0x70, 0xd7, 0x89, 0x50, 0x03, 0xd7, 0x19, + 0x0d, 0x5c, 0x27, 0x5c, 0x0d, 0x5c, 0xe7, 0x75, 0x30, 0x21, 0xa3, 0x17, 0x53, 0xc3, 0xdc, 0xf1, + 0x7d, 0xde, 0x63, 0x60, 0xcf, 0x35, 0xb7, 0x44, 0x0d, 0x5a, 0xd4, 0x8f, 0x47, 0xdb, 0x4b, 0xc1, + 0xee, 0x32, 0xdf, 0x54, 0x3f, 0x56, 0x40, 0x65, 0xd7, 0xb8, 0x96, 0xe9, 0x03, 0x03, 0xd0, 0xce, + 0x0c, 0xf2, 0x5d, 0x5a, 0xce, 0x94, 0x0b, 0xbb, 0x45, 0xbb, 0xde, 0x01, 0xac, 0x3e, 0x00, 0x73, + 0x29, 0xcd, 0x5e, 0x44, 0x7b, 0x03, 0xd1, 0x0d, 0x57, 0x7e, 0xe1, 0x83, 0x29, 0x5c, 0xd5, 0xbb, + 0x60, 0x3e, 0xc7, 0x91, 0xd2, 0x1c, 0x67, 0x3a, 0x52, 0x0c, 0xb1, 0xc2, 0xe4, 0x39, 0xd2, 0x4e, + 0x74, 0xa2, 0x28, 0x3d, 0x9f, 0x5e, 0xe6, 0xc6, 0x63, 0x26, 0x6b, 0xea, 0x4c, 0xd5, 0xb3, 0x90, + 0x5d, 0xcf, 0x3a, 0x78, 0x35, 0x9b, 0x38, 0x52, 0xc5, 0x37, 0x64, 0xaa, 0x53, 0xb2, 0x67, 0x05, + 0xc1, 0xa0, 0xaa, 0x32, 0xc3, 0xd7, 0x6c, 0xd7, 0xdc, 0xa6, 0xef, 0x3b, 0x8c, 0xd8, 0xb7, 0xf1, + 0xa3, 0xc0, 0xd7, 0xc2, 0xd7, 0xf6, 0x9e, 0x2c, 0xd8, 0xd3, 0x69, 0xa4, 0x04, 0xaf, 0x81, 0x89, + 0x4d, 0xb1, 0x6f, 0xec, 0x70, 0x02, 0x43, 0x54, 0x9c, 0x81, 0x3f, 0x2b, 0xa2, 0xa3, 0x1b, 0xdf, + 0x4c, 0x61, 0x57, 0x17, 0x65, 0xf5, 0xbd, 0x14, 0x99, 0x6e, 0xc5, 0x77, 0x1b, 0x4b, 0xb2, 0xc3, + 0x0e, 0xcd, 0x1d, 0xeb, 0xc2, 0x95, 0x78, 0x17, 0xae, 0xae, 0x80, 0xb3, 0x7b, 0x42, 0xb4, 0x4b, + 0xeb, 0xbd, 0x5f, 0xbb, 0x77, 0x64, 0xdd, 0x1e, 0xf3, 0xad, 0xcc, 0x6f, 0xe5, 0xef, 0xfa, 0xd3, + 0x66, 0x35, 0x99, 0x4f, 0x8f, 0xcd, 0x20, 0x0a, 0xf1, 0x19, 0xc4, 0x59, 0x30, 0xea, 0x3e, 0x74, + 0x3a, 0x1c, 0xa9, 0x5f, 0xec, 0x1f, 0x16, 0x8b, 0x61, 0x82, 0x8c, 0x5a, 0xf6, 0x81, 0xdd, 0x5a, + 0xf6, 0xc1, 0x83, 0x6c, 0xd9, 0x3f, 0x02, 0x23, 0xc4, 0x21, 0xcc, 0x90, 0xf5, 0xd6, 0x90, 0xc0, + 0x5e, 0xce, 0x85, 0xbd, 0xea, 0x10, 0x46, 0x90, 0x4d, 0x7e, 0x2c, 0xc6, 0x31, 0xa2, 0x0a, 0xe3, + 0x7d, 0x0b, 0xd5, 0x01, 0x47, 0x0e, 0xaa, 0x32, 0xd8, 0x00, 0xe3, 0xc1, 0x58, 0x84, 0x6e, 0x21, + 0x8f, 0x38, 0xf5, 0xf0, 0xc0, 0x43, 0xe2, 0xc0, 0xb7, 0xb3, 0x15, 0x78, 0x1c, 0x60, 0x3d, 0xe0, + 0xef, 0x38, 0x06, 0x7a, 0xc9, 0x75, 0xba, 0xf0, 0x8f, 0xd3, 0x60, 0x50, 0xdc, 0x22, 0xfc, 0x97, + 0x02, 0xc6, 0xd3, 0x26, 0x7f, 0xf0, 0x6a, 0xfe, 0x44, 0x1a, 0x1f, 0x3a, 0x96, 0x17, 0x7b, 0x40, + 0x08, 0xdc, 0x49, 0xbd, 0xf1, 0x93, 0x3f, 0xfe, 0xf3, 0xb3, 0x42, 0x0d, 0x5e, 0xed, 0x3e, 0xa2, + 0x8e, 0xdc, 0x4e, 0x8e, 0x16, 0xb5, 0xc7, 0x1d, 0x8e, 0xf8, 0x04, 0xfe, 0x45, 0x91, 0xb5, 0x74, + 0x3c, 0xa5, 0xc2, 0x2b, 0xf9, 0x85, 0x8c, 0x4d, 0x27, 0xcb, 0x57, 0xf7, 0x0f, 0x20, 0x95, 0x5c, + 0x14, 0x4a, 0xbe, 0x0d, 0xdf, 0xca, 0xa1, 0x64, 0x30, 0x24, 0xd4, 0x1e, 0x0b, 0xf7, 0x7f, 0x02, + 0x3f, 0x2d, 0xc8, 0xa8, 0x4c, 0x1d, 0x5f, 0xc0, 0x95, 0xec, 0x32, 0xee, 0x35, 0x8e, 0x29, 0x5f, + 0xef, 0x19, 0x47, 0xaa, 0xbc, 0x29, 0x54, 0xfe, 0x3e, 0xbc, 0x97, 0xe1, 0xa7, 0x87, 0x68, 0x0c, + 0x18, 0xeb, 0xc3, 0xe2, 0xd7, 0xab, 0x3d, 0x4e, 0xbe, 0x42, 0x69, 0x36, 0xe9, 0x6c, 0x1e, 0xf6, + 0x65, 0x93, 0x94, 0x09, 0xce, 0xbe, 0x6c, 0x92, 0x36, 0x7a, 0xd9, 0x9f, 0x4d, 0x62, 0x6a, 0x27, + 0x6d, 0x92, 0x6c, 0x5c, 0x9f, 0xc0, 0xdf, 0x2b, 0xb2, 0xcf, 0x8c, 0x8d, 0x65, 0xe0, 0xe5, 0xec, + 0x3a, 0xa4, 0x4d, 0x7b, 0xca, 0x57, 0xf6, 0xcd, 0x2f, 0x75, 0x7f, 0x53, 0xe8, 0xbe, 0x00, 0xe7, + 0xba, 0xeb, 0xce, 0x24, 0x40, 0xf0, 0x3b, 0x04, 0xfc, 0x79, 0x41, 0x3e, 0x8b, 0x7b, 0xcf, 0x59, + 0xe0, 0x9d, 0xec, 0x22, 0x66, 0x9a, 0xef, 0x94, 0xd7, 0x0e, 0x0e, 0x50, 0x1a, 0xe1, 0xa6, 0x30, + 0xc2, 0x32, 0x5c, 0xea, 0x6e, 0x04, 0x3f, 0x42, 0x6c, 0x47, 0x45, 0x6c, 0xc0, 0x0b, 0x7f, 0x5a, + 0x90, 0x15, 0xc7, 0x9e, 0x93, 0x1e, 0x78, 0x3b, 0xbb, 0x16, 0x59, 0x26, 0x50, 0xe5, 0x3b, 0x07, + 0x86, 0x27, 0x8d, 0xb2, 0x2c, 0x8c, 0x72, 0x05, 0x5e, 0xea, 0x6e, 0x14, 0xe9, 0xe5, 0x86, 0xc7, + 0x51, 0x13, 0xe9, 0xff, 0x37, 0x0a, 0x18, 0xe9, 0x18, 0xa5, 0xc0, 0x37, 0xb2, 0xcb, 0x19, 0x1b, + 0xc9, 0x94, 0xdf, 0xcc, 0xcf, 0x28, 0x35, 0x99, 0x13, 0x9a, 0xcc, 0xc2, 0x99, 0xee, 0x9a, 0x04, + 0x8f, 0x7f, 0xdb, 0xb7, 0xf7, 0x1e, 0xa7, 0xe4, 0xf1, 0xed, 0x4c, 0x73, 0x9e, 0x3c, 0xbe, 0x9d, + 0x6d, 0xd2, 0x93, 0xc7, 0xb7, 0x5d, 0x0e, 0x62, 0x10, 0xc7, 0x68, 0xb7, 0x60, 0x89, 0xcb, 0xfc, + 0x6d, 0x41, 0x0e, 0x45, 0xb3, 0xb4, 0x47, 0xf0, 0xfd, 0xfd, 0x3e, 0xd0, 0x7b, 0x76, 0x78, 0xe5, + 0xbb, 0x07, 0x0d, 0x2b, 0x2d, 0x75, 0x4f, 0x58, 0x6a, 0x03, 0xea, 0xb9, 0xab, 0x01, 0xc3, 0xc3, + 0x7e, 0xdb, 0x68, 0x69, 0x4f, 0xe2, 0xaf, 0x0b, 0xe0, 0xe5, 0x2c, 0xfd, 0x16, 0x5c, 0xeb, 0xe1, + 0xa1, 0x4f, 0xed, 0x24, 0xcb, 0xef, 0x1d, 0x20, 0xa2, 0xb4, 0x94, 0x29, 0x2c, 0x75, 0x1f, 0x7e, + 0x98, 0xc7, 0x52, 0xf1, 0xf1, 0x52, 0xf7, 0x2a, 0xe2, 0xbf, 0x0a, 0x98, 0xd8, 0x65, 0x5a, 0x00, + 0x97, 0x7a, 0x99, 0x35, 0x84, 0x86, 0xb9, 0xd6, 0x1b, 0x48, 0xfe, 0xf8, 0x8a, 0x34, 0xde, 0x35, + 0xbe, 0xfe, 0xa3, 0xc8, 0x16, 0x31, 0xad, 0x13, 0x86, 0x39, 0x26, 0x2c, 0x7b, 0x74, 0xdb, 0xe5, + 0x95, 0x5e, 0x61, 0xf2, 0x57, 0xcf, 0xbb, 0x34, 0xee, 0xf0, 0x7f, 0xc9, 0x9f, 0xf3, 0xe3, 0xad, + 0x35, 0xbc, 0x9e, 0xff, 0x8a, 0x52, 0xfb, 0xfb, 0xf2, 0x8d, 0xde, 0x81, 0x7a, 0xe8, 0x19, 0x88, + 0xa5, 0x3d, 0x8e, 0xc6, 0x0b, 0x4f, 0xe0, 0x5f, 0xc3, 0x5a, 0x30, 0x96, 0x9e, 0xf2, 0xd4, 0x82, + 0x69, 0x13, 0x84, 0xf2, 0x95, 0x7d, 0xf3, 0x4b, 0xd5, 0x56, 0x84, 0x6a, 0x57, 0xe1, 0xe5, 0xbc, + 0x09, 0x30, 0xee, 0xc5, 0xb5, 0x0f, 0xbe, 0x7c, 0x36, 0xa5, 0x7c, 0xf5, 0x6c, 0x4a, 0xf9, 0xfb, + 0xb3, 0x29, 0xe5, 0x93, 0xe7, 0x53, 0x7d, 0x5f, 0x3d, 0x9f, 0xea, 0xfb, 0xd3, 0xf3, 0xa9, 0xbe, + 0x7b, 0x97, 0xea, 0x84, 0x6d, 0xed, 0x6c, 0x56, 0x4d, 0xb7, 0x21, 0xff, 0x2f, 0xa7, 0xe3, 0xa8, + 0x0b, 0xd1, 0x51, 0xcd, 0xd7, 0xb5, 0x47, 0x89, 0xda, 0xb3, 0xe5, 0x61, 0xba, 0x39, 0x24, 0x7e, + 0x3d, 0xfc, 0xde, 0xb7, 0x01, 0x00, 0x00, 0xff, 0xff, 0x19, 0x33, 0x42, 0x36, 0x37, 0x25, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2830,6 +2843,15 @@ func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Prioritylist) > 0 { + for iNdEx := len(m.Prioritylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Prioritylist[iNdEx]) + copy(dAtA[i:], m.Prioritylist[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Prioritylist[iNdEx]))) + i-- + dAtA[i] = 0x7a + } + } if m.AllowlistedRewardDenoms != nil { { size, err := m.AllowlistedRewardDenoms.MarshalToSizedBuffer(dAtA[:i]) @@ -4115,6 +4137,12 @@ func (m *Chain) Size() (n int) { l = m.AllowlistedRewardDenoms.Size() n += 1 + l + sovQuery(uint64(l)) } + if len(m.Prioritylist) > 0 { + for _, s := range m.Prioritylist { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } return n } @@ -5354,6 +5382,38 @@ func (m *Chain) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prioritylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prioritylist = append(m.Prioritylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:])