diff --git a/proto/interchain_security/ccv/consumer/v1/genesis.proto b/proto/interchain_security/ccv/consumer/v1/genesis.proto index 38fc96510d..d22102ae1e 100644 --- a/proto/interchain_security/ccv/consumer/v1/genesis.proto +++ b/proto/interchain_security/ccv/consumer/v1/genesis.proto @@ -81,86 +81,3 @@ message ConsumerPacketDataList { repeated interchain_security.ccv.v1.ConsumerPacketData list = 1 [ (gogoproto.nullable) = false ]; } -syntax = "proto3"; - -package interchain_security.ccv.consumer.v1; - -option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types"; - -import "interchain_security/ccv/v1/shared_consumer.proto"; -import "ibc/lightclients/tendermint/v1/tendermint.proto"; - -import "gogoproto/gogo.proto"; -import "interchain_security/ccv/v1/wire.proto"; -import "google/protobuf/timestamp.proto"; -import "tendermint/abci/types.proto"; - -// GenesisState defines the CCV consumer genesis state -// -// Note: this type is only used on consumer side and references shared types -// with provider -message GenesisState { - // Reserve 5th slot for removed provider_client_state field - reserved 5; - - // Reserve 6th slot for removed provider_consensus_state field - reserved 6; - - // Reserve 7th slot for removed maturing_packets field - reserved 7; - - // Reserve 8th slot for removed initial_val_set field - reserved 8; - - // ConsumerParams is a shared type with provider module - interchain_security.ccv.v1.ConsumerParams params = 1 - [ (gogoproto.nullable) = false ]; - // Client ID of the provider. Empty for a new chain, filled in on restart. - string provider_client_id = 2; - // Channel ID of the provider. Empty for a new chain, filled in on restart. - string provider_channel_id = 3; - // true for new chain, false for chain restart. - bool new_chain = 4; - // HeightToValsetUpdateId nil on new chain, filled in on restart. - repeated HeightToValsetUpdateID height_to_valset_update_id = 9 - [ (gogoproto.nullable) = false ]; - // OutstandingDowntimes nil on new chain, filled in on restart. - repeated OutstandingDowntime outstanding_downtime_slashing = 10 - [ (gogoproto.nullable) = false ]; - // PendingConsumerPackets nil on new chain, filled in on restart. - ConsumerPacketDataList pending_consumer_packets = 11 - [ (gogoproto.nullable) = false ]; - // LastTransmissionBlockHeight nil on new chain, filled in on restart. - LastTransmissionBlockHeight last_transmission_block_height = 12 - [ (gogoproto.nullable) = false ]; - // flag indicating whether the consumer CCV module starts in pre-CCV state - bool preCCV = 13; - interchain_security.ccv.v1.ProviderInfo provider = 14 - [ (gogoproto.nullable) = false ]; -} - -// HeightValsetUpdateID represents a mapping internal to the consumer CCV module -// which links a block height to each recv valset update id. -message HeightToValsetUpdateID { - uint64 height = 1; - uint64 valset_update_id = 2; -} - -// OutstandingDowntime defines the type used internally to the consumer CCV -// module and is used in order to not send multiple slashing requests for -// the same downtime infraction. -message OutstandingDowntime { string validator_consensus_address = 1; } - -// LastTransmissionBlockHeight is the last time validator holding -// pools were transmitted to the provider chain. This type is used internally -// to the consumer CCV module. -message LastTransmissionBlockHeight { int64 height = 1; } - -// ConsumerPacketDataList is a list of consumer packet data packets. -// -// Note this type is used internally to the consumer CCV module -// for exporting / importing state in InitGenesis and ExportGenesis. -message ConsumerPacketDataList { - repeated interchain_security.ccv.v1.ConsumerPacketData list = 1 - [ (gogoproto.nullable) = false ]; -} diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index 033c8fbc01..c13fde1cc3 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -88,6 +88,32 @@ message ConsumerAdditionProposal { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintain the existing ibc transfer channel string distribution_transmission_channel = 14; + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + uint32 top_N = 15; + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + uint32 validators_power_cap = 16; + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + uint32 validator_set_cap = 17; + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + repeated string allowlist = 18; + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + repeated string denylist = 19; } // ConsumerRemovalProposal is a governance proposal on the provider chain to @@ -120,6 +146,32 @@ message ConsumerModificationProposal { string description = 2; // the chain-id of the consumer chain to be modified string chain_id = 3; + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + uint32 top_N = 4; + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + uint32 validators_power_cap = 5; + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + uint32 validator_set_cap = 6; + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + repeated string allowlist = 7; + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + repeated string denylist = 8; } // EquivocationProposal is a governance proposal on the provider chain to diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto index b9bd98887c..8a1a9b8305 100644 --- a/proto/interchain_security/ccv/provider/v1/query.proto +++ b/proto/interchain_security/ccv/provider/v1/query.proto @@ -107,6 +107,15 @@ service Query { option (google.api.http).get = "/interchain_security/ccv/provider/consumer_validators/{chain_id}"; } + + // QueryConsumerChainOptedInValidators returns all opted-in validators for a + // given consumer chain + rpc QueryConsumerChainOptedInValidators( + QueryConsumerChainOptedInValidatorsRequest) + returns (QueryConsumerChainOptedInValidatorsResponse) { + option (google.api.http).get = + "/interchain_security/ccv/provider/opted_in_validators/{chain_id}"; + } } message QueryConsumerGenesisRequest { string chain_id = 1; } @@ -135,6 +144,12 @@ message QueryConsumerChainStopProposalsResponse { message Chain { string chain_id = 1; string client_id = 2; + // If chain with `chainID` is a Top-N chain, i.e., enforces at least one + // validator to validate chain `chainID` + uint32 top_N = 3; + // If the chain is a Top-N chain, this is the minimum power required to be in + // the top N. Otherwise, this is -1. + int64 min_power_in_top_N = 4; } message QueryValidatorConsumerAddrRequest { @@ -235,3 +250,12 @@ message QueryConsumerValidatorsValidator { message QueryConsumerValidatorsResponse { repeated QueryConsumerValidatorsValidator validators = 1; } + +message QueryConsumerChainOptedInValidatorsRequest { + string chain_id = 1; +} + +message QueryConsumerChainOptedInValidatorsResponse { + // The consensus addresses of opted-in validators on the provider chain + repeated string validators_provider_addresses = 1; +} diff --git a/proto/interchain_security/ccv/provider/v1/tx.proto b/proto/interchain_security/ccv/provider/v1/tx.proto index 7c0a0ee22b..dc2cbcce54 100644 --- a/proto/interchain_security/ccv/provider/v1/tx.proto +++ b/proto/interchain_security/ccv/provider/v1/tx.proto @@ -30,6 +30,8 @@ service Msg { returns (MsgConsumerAdditionResponse); rpc ConsumerRemoval(MsgConsumerRemoval) returns (MsgConsumerRemovalResponse); rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); + rpc OptIn(MsgOptIn) returns (MsgOptInResponse); + rpc OptOut(MsgOptOut) returns (MsgOptOutResponse); rpc ConsumerModification(MsgConsumerModification) returns (MsgConsumerModificationResponse); } @@ -161,8 +163,34 @@ message MsgConsumerAddition { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintan the existing ibc transfer channel string distribution_transmission_channel = 12; + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + uint32 top_N = 13; + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + uint32 validators_power_cap = 14; + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + uint32 validator_set_cap = 15; + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + repeated string allowlist = 16; + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + repeated string denylist = 17; // signer address - string authority = 13 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string authority = 18 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; } // MsgConsumerAdditionResponse defines response type for MsgConsumerAddition @@ -213,6 +241,42 @@ message MsgChangeRewardDenoms { // messages message MsgChangeRewardDenomsResponse {} +message MsgOptIn { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "signer"; + // the chain id of the consumer chain to opt in to + string chain_id = 1; + // the validator address on the provider + string provider_addr = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + // (optional) The consensus public key to use on the consumer in json string + // format corresponding to proto-any, for example + // `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`. + // This field is optional and can remain empty (i.e., `consumer_key = ""`). A + // validator can always change the consumer public key at a later stage by + // issuing a `MsgAssignConsumerKey` message. + string consumer_key = 3; + // signer address + string signer = 4 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; +} + +message MsgOptInResponse {} + +message MsgOptOut { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (cosmos.msg.v1.signer) = "signer"; + // the chain id of the consumer chain to opt out from + string chain_id = 1; + // the validator address on the provider + string provider_addr = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; + // signer address + string signer = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + +} + +message MsgOptOutResponse {} + // MsgConsumerModification message contains a governance proposal on the // provider chain to modify a running consumer chain. If it passes, the consumer // chain's parameters are updated. @@ -228,8 +292,34 @@ message MsgConsumerModification { string description = 2; // the chain-id of the consumer chain to be modified string chain_id = 3; + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + uint32 top_N = 4; + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + uint32 validators_power_cap = 5; + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + uint32 validator_set_cap = 6; + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + repeated string allowlist = 7; + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + repeated string denylist = 8; // signer address - string authority = 4 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + string authority = 9 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; } message MsgConsumerModificationResponse {} diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index 5a8ef04573..d73dd33056 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -62,6 +62,9 @@ message ConsumerParams { google.protobuf.Duration unbonding_period = 9 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // Reserved for previously used soft_opt_out_threshold field + reserved 10; + // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. repeated string reward_denoms = 11; diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 9096395fe1..ef43f969fc 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -260,6 +260,7 @@ type SubmitConsumerAdditionProposalAction struct { SpawnTime uint InitialHeight clienttypes.Height DistributionChannel string + TopN uint32 } func (tr Chain) submitConsumerAdditionProposal( @@ -284,6 +285,7 @@ func (tr Chain) submitConsumerAdditionProposal( UnbondingPeriod: params.UnbondingPeriod, Deposit: fmt.Sprint(action.Deposit) + `stake`, DistributionTransmissionChannel: action.DistributionChannel, + TopN: action.TopN, } bz, err := json.Marshal(prop) diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index c5ab1de9ad..acb29ca9fa 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -39,6 +39,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint ConsumerChain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 100, // All validators must validate (100% = Replicated Security) }, State: State{ ChainID("provi"): ChainState{ diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index b2076e2ab3..6b155da503 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -135,7 +135,8 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( prop := testkeeper.GetTestConsumerAdditionProp() prop.ChainId = chainID - // For Replicated Security, all validators participate (no TopN parameter) + // For Replicated Security with TopN restoration, set TopN to 100 (all validators participate) + prop.Top_N = 100 // NOTE: we cannot use the time.Now() because the coordinator chooses a hardcoded start time // using time.Now() could set the spawn time to be too far in the past or too far in the future @@ -150,9 +151,6 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( providerKeeper.SetPendingConsumerAdditionProp(providerChain.GetContext(), prop) props := providerKeeper.GetAllPendingConsumerAdditionProps(providerChain.GetContext()) s.Require().Len(props, 1, "unexpected len consumer addition proposals in AddConsumer") - - // For Replicated Security, all validators automatically participate - // No opt-in needed // commit the state on the provider chain // and create the client and genesis of consumer diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index ab53e6ce62..a14059be4d 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -280,6 +280,7 @@ func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal { types.DefaultCCVTimeoutPeriod, types.DefaultTransferTimeoutPeriod, types.DefaultConsumerUnbondingPeriod, + 0, // TopN = 0 for opt-in chain (doesn't require validators for testing) ).(*providertypes.ConsumerAdditionProposal) return prop diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go index 1776f0160f..1377fd7a2d 100644 --- a/x/ccv/provider/client/cli/query.go +++ b/x/ccv/provider/client/cli/query.go @@ -36,6 +36,7 @@ func NewQueryCmd() *cobra.Command { cmd.AddCommand(CmdAllPairsValConAddrByConsumerChainID()) cmd.AddCommand(CmdProviderParameters()) cmd.AddCommand(CmdConsumerValidators()) + cmd.AddCommand(CmdConsumerChainOptedInValidators()) return cmd } @@ -445,3 +446,37 @@ $ %s consumer-validators foochain return cmd } + +// CmdConsumerChainOptedInValidators queries opted-in validators for a given consumer chain +func CmdConsumerChainOptedInValidators() *cobra.Command { + cmd := &cobra.Command{ + Use: "consumer-opted-in-validators [chainid]", + Short: "Query opted-in validators for a given consumer chain", + Long: strings.TrimSpace( + fmt.Sprintf(`Query opted-in validators for a given consumer chain. +Example: +$ %s consumer-opted-in-validators foochain + `, version.AppName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.QueryConsumerChainOptedInValidators(cmd.Context(), + &types.QueryConsumerChainOptedInValidatorsRequest{ChainId: args[0]}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ccv/provider/client/legacy_proposal_handler.go b/x/ccv/provider/client/legacy_proposal_handler.go index 99eb8b3c98..41434c2fe6 100644 --- a/x/ccv/provider/client/legacy_proposal_handler.go +++ b/x/ccv/provider/client/legacy_proposal_handler.go @@ -83,7 +83,8 @@ Where proposal.json contains: proposal.GenesisHash, proposal.BinaryHash, proposal.SpawnTime, proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, proposal.DistributionTransmissionChannel, proposal.HistoricalEntries, - proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod) + proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod, + proposal.TopN) from := clientCtx.GetFromAddress() diff --git a/x/ccv/provider/client/legacy_proposals.go b/x/ccv/provider/client/legacy_proposals.go index 3e042de134..d688f8c628 100644 --- a/x/ccv/provider/client/legacy_proposals.go +++ b/x/ccv/provider/client/legacy_proposals.go @@ -35,6 +35,8 @@ type ConsumerAdditionProposalJSON struct { UnbondingPeriod time.Duration `json:"unbonding_period"` Deposit string `json:"deposit"` + + TopN uint32 `json:"top_N"` } type ConsumerAdditionProposalReq struct { diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go index efe661f5c5..f929663c4f 100644 --- a/x/ccv/provider/keeper/grpc_query.go +++ b/x/ccv/provider/keeper/grpc_query.go @@ -65,9 +65,24 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, chainID string) (types.Chain, return types.Chain{}, fmt.Errorf("cannot find clientID for consumer (%s)", chainID) } + topN, found := k.GetTopN(ctx, chainID) + if !found { + k.Logger(ctx).Error("failed to get top N, treating as 0", "chain", chainID) + topN = 0 + } + + // Get the minimal power in the top N for the consumer chain + minPowerInTopN, found := k.GetMinimumPowerInTopN(ctx, chainID) + if !found { + k.Logger(ctx).Error("failed to get minimum power in top N, treating as -1", "chain", chainID) + minPowerInTopN = -1 + } + return types.Chain{ - ChainId: chainID, - ClientId: clientID, + ChainId: chainID, + ClientId: clientID, + Top_N: topN, + MinPowerInTop_N: minPowerInTopN, }, nil } @@ -275,3 +290,30 @@ func (k Keeper) QueryConsumerValidators(goCtx context.Context, req *types.QueryC Validators: validators, }, nil } + +// QueryConsumerChainOptedInValidators returns all validators that opted-in to a given consumer chain +func (k Keeper) QueryConsumerChainOptedInValidators(goCtx context.Context, req *types.QueryConsumerChainOptedInValidatorsRequest) (*types.QueryConsumerChainOptedInValidatorsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + consumerChainID := req.ChainId + if consumerChainID == "" { + return nil, status.Error(codes.InvalidArgument, "empty chainId") + } + + optedInVals := []string{} + ctx := sdk.UnwrapSDKContext(goCtx) + + if !k.IsConsumerProposedOrRegistered(ctx, consumerChainID) { + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("unknown consumer chain: %s", consumerChainID)) + } + + for _, v := range k.GetAllOptedIn(ctx, consumerChainID) { + optedInVals = append(optedInVals, v.ToSdkConsAddr().String()) + } + + return &types.QueryConsumerChainOptedInValidatorsResponse{ + ValidatorsProviderAddresses: optedInVals, + }, nil +} diff --git a/x/ccv/provider/keeper/grpc_query_test.go b/x/ccv/provider/keeper/grpc_query_test.go index 81dfe6ce3c..6ccc6a782d 100644 --- a/x/ccv/provider/keeper/grpc_query_test.go +++ b/x/ccv/provider/keeper/grpc_query_test.go @@ -119,8 +119,10 @@ func TestGetConsumerChain(t *testing.T) { expectedGetAllOrder = append(expectedGetAllOrder, types.Chain{ - ChainId: chainID, - ClientId: clientID, + ChainId: chainID, + ClientId: clientID, + Top_N: 0, // default for non-set TopN + MinPowerInTop_N: -1, // default when not found }) } diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index 33b7122980..792511ead7 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -718,6 +718,343 @@ func (k Keeper) GetAllRegisteredAndProposedChainIDs(ctx sdk.Context) []string { return allConsumerChains } +// SetTopN stores the N value associated to chain with `chainID` +func (k Keeper) SetTopN( + ctx sdk.Context, + chainID string, + N uint32, +) { + store := ctx.KVStore(k.storeKey) + + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, N) + + store.Set(types.TopNKey(chainID), buf) +} + +// DeleteTopN removes the N value associated to chain with `chainID` +func (k Keeper) DeleteTopN( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.TopNKey(chainID)) +} + +// GetTopN returns (N, true) if chain `chainID` has a top N associated, and (0, false) otherwise. +func (k Keeper) GetTopN( + ctx sdk.Context, + chainID string, +) (uint32, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.TopNKey(chainID)) + if buf == nil { + return 0, false + } + return binary.BigEndian.Uint32(buf), true +} + +// IsTopN returns true if chain with `chainID` is a Top-N chain (i.e., enforces at least one validator to validate chain `chainID`) +func (k Keeper) IsTopN(ctx sdk.Context, chainID string) bool { + topN, found := k.GetTopN(ctx, chainID) + return found && topN > 0 +} + +// IsOptIn returns true if chain with `chainID` is an Opt-In chain (i.e., no validator is forced to validate chain `chainID`) +func (k Keeper) IsOptIn(ctx sdk.Context, chainID string) bool { + topN, found := k.GetTopN(ctx, chainID) + return !found || topN == 0 +} + +func (k Keeper) SetOptedIn( + ctx sdk.Context, + chainID string, + providerConsAddress types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.OptedInKey(chainID, providerConsAddress), []byte{}) +} + +func (k Keeper) DeleteOptedIn( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.OptedInKey(chainID, providerAddr)) +} + +func (k Keeper) IsOptedIn( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + return store.Get(types.OptedInKey(chainID, providerAddr)) != nil +} + +func (k Keeper) GetAllOptedIn( + ctx sdk.Context, + chainID string, +) (providerConsAddresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.OptedInBytePrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerConsAddresses = append(providerConsAddresses, types.NewProviderConsAddress(iterator.Key()[len(key):])) + } + + return providerConsAddresses +} + +func (k Keeper) DeleteAllOptedIn( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.OptedInBytePrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + + keysToDel := [][]byte{} + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + + for _, key := range keysToDel { + store.Delete(key) + } +} + +// SetMinimumPowerInTopN sets the minimum power required for a validator to be in the top N +// for a given consumer chain. +func (k Keeper) SetMinimumPowerInTopN( + ctx sdk.Context, + chainID string, + power int64, +) { + store := ctx.KVStore(k.storeKey) + + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, uint64(power)) + + store.Set(types.MinimumPowerInTopNKey(chainID), buf) +} + +// GetMinimumPowerInTopN returns the minimum power required for a validator to be in the top N +// for a given consumer chain. +func (k Keeper) GetMinimumPowerInTopN( + ctx sdk.Context, + chainID string, +) (int64, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.MinimumPowerInTopNKey(chainID)) + if buf == nil { + return 0, false + } + return int64(binary.BigEndian.Uint64(buf)), true +} + +// DeleteMinimumPowerInTopN removes the minimum power required for a validator to be in the top N +// for a given consumer chain. +func (k Keeper) DeleteMinimumPowerInTopN( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.MinimumPowerInTopNKey(chainID)) +} + +// SetValidatorSetCap stores the validator-set cap for chain `chainID` +func (k Keeper) SetValidatorSetCap( + ctx sdk.Context, + chainID string, + cap uint32, +) { + store := ctx.KVStore(k.storeKey) + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, cap) + store.Set(types.ValidatorSetCapKey(chainID), buf) +} + +// DeleteValidatorSetCap deletes the validator-set cap for chain `chainID` +func (k Keeper) DeleteValidatorSetCap(ctx sdk.Context, chainID string) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ValidatorSetCapKey(chainID)) +} + +// GetValidatorSetCap returns `(c, true)` if chain `chainID` has validator-set cap `c` associated with it, and (0, false) otherwise +func (k Keeper) GetValidatorSetCap( + ctx sdk.Context, + chainID string, +) (uint32, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.ValidatorSetCapKey(chainID)) + if buf == nil { + return 0, false + } + return binary.BigEndian.Uint32(buf), true +} + +// SetValidatorsPowerCap stores the power cap for chain `chainID` +func (k Keeper) SetValidatorsPowerCap( + ctx sdk.Context, + chainID string, + cap uint32, +) { + store := ctx.KVStore(k.storeKey) + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, cap) + store.Set(types.ValidatorsPowerCapKey(chainID), buf) +} + +// DeleteValidatorsPowerCap deletes the power cap for chain `chainID` +func (k Keeper) DeleteValidatorsPowerCap(ctx sdk.Context, chainID string) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ValidatorsPowerCapKey(chainID)) +} + +// GetValidatorsPowerCap returns `(p, true)` if chain `chainID` has power cap `p` associated with it, and (0, false) otherwise +func (k Keeper) GetValidatorsPowerCap( + ctx sdk.Context, + chainID string, +) (uint32, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.ValidatorsPowerCapKey(chainID)) + if buf == nil { + return 0, false + } + return binary.BigEndian.Uint32(buf), true +} + +// SetAllowlist allowlists validator with `providerAddr` address on chain `chainID` +func (k Keeper) SetAllowlist( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.AllowlistCapKey(chainID, providerAddr), []byte{}) +} + +// GetAllowList returns all allowlisted validators +func (k Keeper) GetAllowList( + ctx sdk.Context, + chainID string, +) (providerConsAddresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.AllowlistPrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerConsAddresses = append(providerConsAddresses, types.NewProviderConsAddress(iterator.Key()[len(key):])) + } + + return providerConsAddresses +} + +// IsAllowlisted returns `true` if validator with `providerAddr` has been allowlisted on chain `chainID` +func (k Keeper) IsAllowlisted( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.AllowlistCapKey(chainID, providerAddr)) + return bz != nil +} + +// DeleteAllowlist deletes all allowlisted validators +func (k Keeper) DeleteAllowlist(ctx sdk.Context, chainID string) { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.AllowlistPrefix, chainID)) + defer iterator.Close() + + keysToDel := [][]byte{} + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + + for _, key := range keysToDel { + store.Delete(key) + } +} + +// IsAllowlistEmpty returns `true` if no validator is allowlisted on chain `chainID` +func (k Keeper) IsAllowlistEmpty(ctx sdk.Context, chainID string) bool { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.AllowlistPrefix, chainID)) + defer iterator.Close() + + return !iterator.Valid() +} + +// SetDenylist denylists validator with `providerAddr` address on chain `chainID` +func (k Keeper) SetDenylist( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.DenylistCapKey(chainID, providerAddr), []byte{}) +} + +// GetDenyList returns all denylisted validators +func (k Keeper) GetDenyList( + ctx sdk.Context, + chainID string, +) (providerConsAddresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.DenylistPrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerConsAddresses = append(providerConsAddresses, types.NewProviderConsAddress(iterator.Key()[len(key):])) + } + + return providerConsAddresses +} + +// IsDenylisted returns `true` if validator with `providerAddr` has been denylisted on chain `chainID` +func (k Keeper) IsDenylisted( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.DenylistCapKey(chainID, providerAddr)) + return bz != nil +} + +// DeleteDenylist deletes all denylisted validators +func (k Keeper) DeleteDenylist(ctx sdk.Context, chainID string) { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.DenylistPrefix, chainID)) + defer iterator.Close() + + keysToDel := [][]byte{} + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + + for _, key := range keysToDel { + store.Delete(key) + } +} + +// IsDenylistEmpty returns `true` if no validator is denylisted on chain `chainID` +func (k Keeper) IsDenylistEmpty(ctx sdk.Context, chainID string) bool { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.DenylistPrefix, chainID)) + defer iterator.Close() + + return !iterator.Valid() +} + func (k Keeper) UnbondingCanComplete(ctx sdk.Context, id uint64) error { return k.stakingKeeper.UnbondingCanComplete(ctx, id) } diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index c8a62dc9b2..3797f26535 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -346,3 +346,131 @@ func TestGetAllProposedConsumerChainIDs(t *testing.T) { } } } + +// TestTopNState tests the TopN state management functions +func TestTopNState(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "testchain" + + // Test GetTopN when not set + topN, found := providerKeeper.GetTopN(ctx, chainID) + require.False(t, found) + require.Zero(t, topN) + + // Test IsTopN when not set + require.False(t, providerKeeper.IsTopN(ctx, chainID)) + + // Test IsOptIn when not set (should return true when TopN not set) + require.True(t, providerKeeper.IsOptIn(ctx, chainID)) + + // Test SetTopN + providerKeeper.SetTopN(ctx, chainID, 50) + topN, found = providerKeeper.GetTopN(ctx, chainID) + require.True(t, found) + require.Equal(t, uint32(50), topN) + + // Test IsTopN with value set + require.True(t, providerKeeper.IsTopN(ctx, chainID)) + + // Test IsOptIn with 0 < TopN < 100 (should return false) + require.False(t, providerKeeper.IsOptIn(ctx, chainID)) + + // Test with TopN = 100 + providerKeeper.SetTopN(ctx, chainID, 100) + require.True(t, providerKeeper.IsTopN(ctx, chainID)) + require.False(t, providerKeeper.IsOptIn(ctx, chainID)) + + // Test DeleteTopN + providerKeeper.DeleteTopN(ctx, chainID) + topN, found = providerKeeper.GetTopN(ctx, chainID) + require.False(t, found) + require.Zero(t, topN) + require.False(t, providerKeeper.IsTopN(ctx, chainID)) +} + +// TestOptedInValidators tests opted-in validator state management +func TestOptedInValidators(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "testchain" + + // Create test provider addresses + provAddr1 := types.NewProviderConsAddress([]byte("addr1")) + provAddr2 := types.NewProviderConsAddress([]byte("addr2")) + provAddr3 := types.NewProviderConsAddress([]byte("addr3")) + + // Test IsOptedIn when not set + require.False(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr1)) + + // Test SetOptedIn + providerKeeper.SetOptedIn(ctx, chainID, provAddr1) + require.True(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr1)) + require.False(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr2)) + + // Set multiple validators + providerKeeper.SetOptedIn(ctx, chainID, provAddr2) + providerKeeper.SetOptedIn(ctx, chainID, provAddr3) + require.True(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr2)) + require.True(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr3)) + + // Test GetAllOptedIn + allOptedIn := providerKeeper.GetAllOptedIn(ctx, chainID) + require.Len(t, allOptedIn, 3) + // Sort for consistent comparison + sort.Slice(allOptedIn, func(i, j int) bool { + return string(allOptedIn[i].ToSdkConsAddr()) < string(allOptedIn[j].ToSdkConsAddr()) + }) + require.Equal(t, provAddr1.ToSdkConsAddr(), allOptedIn[0].ToSdkConsAddr()) + require.Equal(t, provAddr2.ToSdkConsAddr(), allOptedIn[1].ToSdkConsAddr()) + require.Equal(t, provAddr3.ToSdkConsAddr(), allOptedIn[2].ToSdkConsAddr()) + + // Test DeleteOptedIn + providerKeeper.DeleteOptedIn(ctx, chainID, provAddr2) + require.False(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr2)) + require.True(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr1)) + require.True(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr3)) + + allOptedIn = providerKeeper.GetAllOptedIn(ctx, chainID) + require.Len(t, allOptedIn, 2) + + // Test DeleteAllOptedIn + providerKeeper.DeleteAllOptedIn(ctx, chainID) + allOptedIn = providerKeeper.GetAllOptedIn(ctx, chainID) + require.Len(t, allOptedIn, 0) + require.False(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr1)) + require.False(t, providerKeeper.IsOptedIn(ctx, chainID, provAddr3)) +} + +// TestMinimumPowerInTopN tests minimum power threshold state management +func TestMinimumPowerInTopN(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "testchain" + + // Test GetMinimumPowerInTopN when not set + power, found := providerKeeper.GetMinimumPowerInTopN(ctx, chainID) + require.False(t, found) + require.Zero(t, power) + + // Test SetMinimumPowerInTopN + providerKeeper.SetMinimumPowerInTopN(ctx, chainID, 1000) + power, found = providerKeeper.GetMinimumPowerInTopN(ctx, chainID) + require.True(t, found) + require.Equal(t, int64(1000), power) + + // Update power + providerKeeper.SetMinimumPowerInTopN(ctx, chainID, 5000) + power, found = providerKeeper.GetMinimumPowerInTopN(ctx, chainID) + require.True(t, found) + require.Equal(t, int64(5000), power) + + // Test DeleteMinimumPowerInTopN + providerKeeper.DeleteMinimumPowerInTopN(ctx, chainID) + power, found = providerKeeper.GetMinimumPowerInTopN(ctx, chainID) + require.False(t, found) + require.Zero(t, power) +} diff --git a/x/ccv/provider/keeper/legacy_proposal_test.go b/x/ccv/provider/keeper/legacy_proposal_test.go index 64a0e619f3..db11d87858 100644 --- a/x/ccv/provider/keeper/legacy_proposal_test.go +++ b/x/ccv/provider/keeper/legacy_proposal_test.go @@ -57,6 +57,7 @@ func TestHandleLegacyConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, // Opt-in chain - doesn't require validators at startup ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: true, @@ -82,6 +83,7 @@ func TestHandleLegacyConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, // Opt-in chain - doesn't require validators at startup ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: false, diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index 40187ec00f..97e2294b4a 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -216,3 +216,74 @@ func (k msgServer) ConsumerModification(goCtx context.Context, msg *types.MsgCon return &types.MsgConsumerModificationResponse{}, nil } + +func (k msgServer) OptIn(goCtx context.Context, msg *types.MsgOptIn) (*types.MsgOptInResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + valAddress, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return nil, err + } + + // validator must already be registered + validator, err := k.stakingKeeper.GetValidator(ctx, valAddress) + if err != nil { + return nil, err + } + + consAddrTmp, err := validator.GetConsAddr() + if err != nil { + return nil, err + } + providerConsAddr := types.NewProviderConsAddress(consAddrTmp) + + err = k.Keeper.HandleOptIn(ctx, msg.ChainId, providerConsAddr, msg.ConsumerKey) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeOptIn, + sdk.NewAttribute(types.AttributeProviderValidatorAddress, msg.ProviderAddr), + sdk.NewAttribute(types.AttributeConsumerConsensusPubKey, msg.ConsumerKey), + ), + }) + + return &types.MsgOptInResponse{}, nil +} + +func (k msgServer) OptOut(goCtx context.Context, msg *types.MsgOptOut) (*types.MsgOptOutResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + valAddress, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return nil, err + } + + // validator must already be registered + validator, err := k.stakingKeeper.GetValidator(ctx, valAddress) + if err != nil { + return nil, err + } + + consAddrTmp, err := validator.GetConsAddr() + if err != nil { + return nil, err + } + providerConsAddr := types.NewProviderConsAddress(consAddrTmp) + + err = k.Keeper.HandleOptOut(ctx, msg.ChainId, providerConsAddr) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeOptOut, + sdk.NewAttribute(types.AttributeProviderValidatorAddress, msg.ProviderAddr), + ), + }) + + return &types.MsgOptOutResponse{}, nil +} diff --git a/x/ccv/provider/keeper/partial_set_security.go b/x/ccv/provider/keeper/partial_set_security.go new file mode 100644 index 0000000000..069eb219dc --- /dev/null +++ b/x/ccv/provider/keeper/partial_set_security.go @@ -0,0 +1,320 @@ +package keeper + +import ( + "fmt" + "sort" + + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +// HandleOptIn prepares validator `providerAddr` to opt in to `chainID` with an optional `consumerKey` consumer public key. +// Note that the validator only opts in at the end of an epoch. +func (k Keeper) HandleOptIn(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress, consumerKey string) error { + if !k.IsConsumerProposedOrRegistered(ctx, chainID) { + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, + "opting in to an unknown consumer chain, with id: %s", chainID) + } + + k.SetOptedIn(ctx, chainID, providerAddr) + + if consumerKey != "" { + consumerTMPublicKey, err := k.ParseConsumerKey(consumerKey) + if err != nil { + return err + } + + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.Address) + if err != nil { + return err + } + + err = k.AssignConsumerKey(ctx, chainID, validator, consumerTMPublicKey) + if err != nil { + return err + } + } + + return nil +} + +// HandleOptOut prepares validator `providerAddr` to opt out from running `chainID`. +// Note that the validator only opts out at the end of an epoch. +func (k Keeper) HandleOptOut(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress) error { + if _, found := k.GetConsumerClientId(ctx, chainID); !found { + // A validator can only opt out from a running chain. We check this by checking the consumer client id, because + // `SetConsumerClientId` is set when the chain starts in `CreateConsumerClientInCachedCtx` of `BeginBlockInit`. + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, + "opting out of an unknown or not running consumer chain, with id: %s", chainID) + } + + if topN, found := k.GetTopN(ctx, chainID); found && topN > 0 { + // a validator cannot opt out from a Top N chain if the validator is in the Top N validators + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()) + if err != nil { + return err + } + valAddr, err := sdk.ValAddressFromBech32(validator.GetOperator()) + if err != nil { + return err + } + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + return err + } + minPowerInTopN, found := k.GetMinimumPowerInTopN(ctx, chainID) + if !found { + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, + "Could not find minimum power in top N for chain with id: %s", chainID) + } + + if power >= minPowerInTopN { + return errorsmod.Wrapf( + types.ErrCannotOptOutFromTopN, + "validator with power (%d) cannot opt out from Top N chain (%s) because all validators"+ + " with at least %d power have to validate", power, chainID, minPowerInTopN) + } + } + + k.DeleteOptedIn(ctx, chainID, providerAddr) + return nil +} + +// OptInTopNValidators opts in to `chainID` all the `bondedValidators` that have at least `minPowerToOptIn` power +func (k Keeper) OptInTopNValidators(ctx sdk.Context, chainID string, bondedValidators []stakingtypes.Validator, minPowerToOptIn int64) { + for _, val := range bondedValidators { + valAddr, err := sdk.ValAddressFromBech32(val.GetOperator()) + if err != nil { + k.Logger(ctx).Error("could not retrieve validator address: %s: %s", + val.GetOperator(), err) + continue + } + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + k.Logger(ctx).Error("could not retrieve last power of validator address: %s: %s", + val.GetOperator(), err) + continue + } + if power >= minPowerToOptIn { + consAddr, err := val.GetConsAddr() + if err != nil { + k.Logger(ctx).Error("could not retrieve validators consensus address: %s: %s", + val, err) + continue + } + + // if validator already exists it gets overwritten + k.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(consAddr)) + } // else validators that do not belong to the top N validators but were opted in, remain opted in + } +} + +// ComputeMinPowerInTopN returns the minimum power needed for a validator (from the bonded validators) +// to belong to the `topN`% of validators for a Top N chain. +func (k Keeper) ComputeMinPowerInTopN(ctx sdk.Context, bondedValidators []stakingtypes.Validator, topN uint32) (int64, error) { + if topN == 0 || topN > 100 { + // Note that Top N chains have a lower limit on `topN`, namely that topN cannot be less than 50. + // However, we can envision that this method could be used for other (future) reasons where this might not + // be the case. For this, this method operates for `topN`s in (0, 100]. + return 0, fmt.Errorf("trying to compute minimum power with an incorrect"+ + " topN value (%d). topN has to be in (0, 100]", topN) + } + + totalPower := math.LegacyZeroDec() + var powers []int64 + + for _, val := range bondedValidators { + valAddr, err := sdk.ValAddressFromBech32(val.GetOperator()) + if err != nil { + return 0, err + } + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + return 0, err + } + powers = append(powers, power) + totalPower = totalPower.Add(math.LegacyNewDec(power)) + } + + // sort by powers descending + sort.Slice(powers, func(i, j int) bool { + return powers[i] > powers[j] + }) + + topNThreshold := math.LegacyNewDec(int64(topN)).QuoInt64(int64(100)) + powerSum := math.LegacyZeroDec() + for _, power := range powers { + powerSum = powerSum.Add(math.LegacyNewDec(power)) + if powerSum.Quo(totalPower).GTE(topNThreshold) { + return power, nil + } + } + + // We should never reach this point because the topN can be up to 1.0 (100%) and in the above `for` loop we + // perform an equal comparison as well (`GTE`). + return 0, fmt.Errorf("should never reach this point with topN (%d), totalPower (%d), and powerSum (%d)", topN, totalPower, powerSum) +} + +// CapValidatorSet caps the provided `validators` if chain `chainID` 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. +func (k Keeper) CapValidatorSet(ctx sdk.Context, chainID string, validators []types.ConsumerValidator) []types.ConsumerValidator { + if topN, found := k.GetTopN(ctx, chainID); found && topN > 0 { + // is a no-op if the chain is a Top N chain + return validators + } + + if validatorSetCap, found := k.GetValidatorSetCap(ctx, chainID); found && validatorSetCap != 0 && int(validatorSetCap) < len(validators) { + sort.Slice(validators, func(i, j int) bool { + return validators[i].Power > validators[j].Power + }) + + return validators[:int(validatorSetCap)] + } else { + return validators + } +} + +// CapValidatorsPower caps the power of the validators on chain `chainID` and returns an updated slice of validators +// with their new powers. Works on a best-basis effort because there are cases where we cannot guarantee that all validators +// on the consumer chain have less power than the set validators-power cap. For example, if we have 10 validators and +// the power cap is set to 5%, we need at least one validator to have more than 10% of the voting power on the consumer chain. +func (k Keeper) CapValidatorsPower(ctx sdk.Context, chainID string, validators []types.ConsumerValidator) []types.ConsumerValidator { + if p, found := k.GetValidatorsPowerCap(ctx, chainID); found && p > 0 { + return NoMoreThanPercentOfTheSum(validators, p) + } else { + // is a no-op if power cap is not set for `chainID` + return validators + } +} + +// sum is a helper function to sum all the validators' power +func sum(validators []types.ConsumerValidator) int64 { + s := int64(0) + for _, v := range validators { + s = s + v.Power + } + return s +} + +// NoMoreThanPercentOfTheSum returns a set of validators with updated powers such that no validator has more than the +// provided `percent` of the sum of all validators' powers. Operates on a best-effort basis. +func NoMoreThanPercentOfTheSum(validators []types.ConsumerValidator, percent uint32) []types.ConsumerValidator { + // Algorithm's idea + // ---------------- + // Consider the validators' powers to be `a_1, a_2, ... a_n` and `p` to be the percent in [1, 100]. Now, consider + // the sum `s = a_1 + a_2 + ... + a_n`. Then `maxPower = s * p / 100 <=> 100 * maxPower = s * p`. + // The problem of capping the validators' powers to be no more than `p` has no solution if `(100 / n) > p`. For example, + // for n = 10 and p = 5 we do not have a solution. We would need at least one validator with power greater than 10% + // for a solution to exist. + // So, if `(100 / n) > p` there's no solution. We know that `100 * maxPower = s * p` and so `(100 / n) > (100 * maxPower) / s` + // `100 * s > 100 * maxPower * n <=> s > maxPower * n`. Thus, we do not have a solution if `s > n * maxPower`. + + // If `s <= n * maxPower` the idea of the algorithm is rather simple. + // - Compute the `maxPower` a validator must have so that it does not have more than `percent` of the voting power. + // - If a validator `v` has power `p`, then: + // - if `p > maxPower` we set `v`'s power to `maxPower` and distribute the `p - maxPower` to validators that + // have less than `maxPower` power. This way, the total sum remains the same and no validator has more than + // `maxPower` and so the power capping is satisfied. + // - Note that in order to avoid setting multiple validators to `maxPower`, we first compute all the `remainingPower` + // we have to distribute and then attempt to add `remainingPower / validatorsWithPowerLessThanMaxPower` to each validator. + // To guarantee that the sum remains the same after the distribution of powers, we sort the powers in descending + // order. This way, we first attempt to add `remainingPower / validatorsWithPowerLessThanMaxPower` to validators + // with greater power and if we cannot add the `remainingPower / validatorsWithPowerLessThanMaxPower` without + // exceeding `maxPower`, we just add enough to reach `maxPower` and add the remaining power to validators with smaller + // power. + + // If `s > n * maxPower` there's no solution and the algorithm would set everything to `maxPower`. + // ---------------- + + // Computes `floor((sum(validators) * percent) / 100)` + maxPower := math.LegacyNewDec(sum(validators)).Mul(math.LegacyNewDec(int64(percent))).QuoInt64(100).TruncateInt64() + + if maxPower == 0 { + // edge case: set `maxPower` to 1 to avoid setting the power of a validator to 0 + maxPower = 1 + } + + // Sort by `.Power` in decreasing order. Sorting in descending order is needed because otherwise we would have cases + // like this `powers =[60, 138, 559]` and `p = 35%` where sum is `757` and `maxValue = 264`. + // Because `559 - 264 = 295` we have to distribute 295 to the first 2 numbers (`295/2 = 147` to each number). However, + // note that `138 + 147 > 264`. If we were to add 147 to 60 first, then we cannot give the remaining 147 to 138. + // So, the idea is to first give `126 (= 264 - 138)` to 138, so it becomes 264, and then add `21 (=147 - 26) + 147` to 60. + sort.Slice(validators, func(i, j int) bool { + return validators[i].Power > validators[j].Power + }) + + // `remainingPower` is to be distributed to validators that have power less than `maxPower` + remainingPower := int64(0) + validatorsWithPowerLessThanMaxPower := 0 + for _, v := range validators { + if v.Power >= maxPower { + remainingPower = remainingPower + (v.Power - maxPower) + } else { + validatorsWithPowerLessThanMaxPower++ + } + } + + updatedValidators := make([]types.ConsumerValidator, len(validators)) + + powerPerValidator := int64(0) + remainingValidators := int64(validatorsWithPowerLessThanMaxPower) + if remainingValidators != 0 { + // power to give to each validator in order to distribute the `remainingPower` + powerPerValidator = remainingPower / remainingValidators + } + + for i, v := range validators { + if v.Power >= maxPower { + updatedValidators[i] = validators[i] + updatedValidators[i].Power = maxPower + } else if v.Power+powerPerValidator >= maxPower { + updatedValidators[i] = validators[i] + updatedValidators[i].Power = maxPower + remainingPower = remainingPower - (maxPower - v.Power) + remainingValidators-- + } else { + updatedValidators[i] = validators[i] + updatedValidators[i].Power = v.Power + powerPerValidator + remainingPower = remainingPower - (updatedValidators[i].Power - validators[i].Power) + remainingValidators-- + } + if remainingValidators == 0 { + continue + } + powerPerValidator = remainingPower / remainingValidators + } + + return updatedValidators +} + +// CanValidateChain returns true if the validator `providerAddr` is opted-in to chain `chainID` and the allowlist and +// denylist do not prevent the validator from validating the chain. +func (k Keeper) CanValidateChain(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress) bool { + // only consider opted-in validators + return k.IsOptedIn(ctx, chainID, providerAddr) && + // if an allowlist is declared, only consider allowlisted validators + (k.IsAllowlistEmpty(ctx, chainID) || + k.IsAllowlisted(ctx, chainID, providerAddr)) && + // if a denylist is declared, only consider denylisted validators + (k.IsDenylistEmpty(ctx, chainID) || + !k.IsDenylisted(ctx, chainID, providerAddr)) +} + +// ComputeNextValidators computes the validators for the upcoming epoch based on the currently `bondedValidators`. +func (k Keeper) ComputeNextValidators(ctx sdk.Context, chainID string, bondedValidators []stakingtypes.Validator) []types.ConsumerValidator { + nextValidators := k.FilterValidators(ctx, chainID, bondedValidators, + func(providerAddr types.ProviderConsAddress) bool { + return k.CanValidateChain(ctx, chainID, providerAddr) + }) + + nextValidators = k.CapValidatorSet(ctx, chainID, nextValidators) + return k.CapValidatorsPower(ctx, chainID, nextValidators) +} diff --git a/x/ccv/provider/keeper/partial_set_security_test.go b/x/ccv/provider/keeper/partial_set_security_test.go new file mode 100644 index 0000000000..623cf3377e --- /dev/null +++ b/x/ccv/provider/keeper/partial_set_security_test.go @@ -0,0 +1,636 @@ +package keeper_test + +import ( + "bytes" + "sort" + "testing" + + gomath "math" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "pgregory.net/rapid" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cometbft/cometbft/proto/tendermint/crypto" + + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" +) + +func TestHandleOptIn(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr := types.NewProviderConsAddress([]byte("providerAddr")) + + // trying to opt in to a non-proposed and non-registered chain returns an error + require.Error(t, providerKeeper.HandleOptIn(ctx, "unknownChainID", providerAddr, "")) + + providerKeeper.SetProposedConsumerChain(ctx, "chainID", 1) + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) + providerKeeper.HandleOptIn(ctx, "chainID", providerAddr, "") + require.True(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) +} + +func TestHandleOptInWithConsumerKey(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // generate a consensus public key for the provider + providerConsPubKey := ed25519.GenPrivKeyFromSecret([]byte{1}).PubKey() + consAddr := sdk.ConsAddress(providerConsPubKey.Address()) + providerAddr := types.NewProviderConsAddress(consAddr) + + calls := []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT(). + GetValidatorByConsAddr(gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx sdk.Context, addr sdk.ConsAddress) (stakingtypes.Validator, error) { + if addr.Equals(providerAddr.Address) { + // Given `providerAddr`, `GetValidatorByConsAddr` returns a validator with the + // exact same `ConsensusPubkey` + pkAny, _ := codectypes.NewAnyWithValue(providerConsPubKey) + return stakingtypes.Validator{ConsensusPubkey: pkAny}, nil + } else { + // for any other consensus address, we cannot find a validator + return stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound + } + }).Times(2), + } + + gomock.InOrder(calls...) + providerKeeper.SetProposedConsumerChain(ctx, "chainID", 1) + + // create a sample consumer key to assign to the `providerAddr` validator + // on the consumer chain with id `chainID` + consumerKey := "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}" + expectedConsumerPubKey, err := providerKeeper.ParseConsumerKey(consumerKey) + require.NoError(t, err) + + err = providerKeeper.HandleOptIn(ctx, "chainID", providerAddr, consumerKey) + require.NoError(t, err) + + // assert that the consumeKey was assigned to `providerAddr` validator on chain with id `chainID` + actualConsumerPubKey, found := providerKeeper.GetValidatorConsumerPubKey(ctx, "chainID", providerAddr) + require.True(t, found) + require.Equal(t, expectedConsumerPubKey, actualConsumerPubKey) + + // assert that the `consumerAddr` to `providerAddr` association was set as well + consumerAddr, _ := ccvtypes.TMCryptoPublicKeyToConsAddr(actualConsumerPubKey) + actualProviderConsAddr, found := providerKeeper.GetValidatorByConsumerAddr(ctx, "chainID", types.NewConsumerConsAddress(consumerAddr)) + require.Equal(t, providerAddr, actualProviderConsAddr) +} + +func TestHandleOptOut(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr := types.NewProviderConsAddress([]byte("providerAddr")) + + // trying to opt out from a not running chain returns an error + require.Error(t, providerKeeper.HandleOptOut(ctx, "unknownChainID", providerAddr)) + + // set a consumer client so that the chain is considered running + providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") + + // if validator (`providerAddr`) is already opted in, then an opt-out would remove this validator + providerKeeper.SetOptedIn(ctx, "chainID", providerAddr) + require.True(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) + providerKeeper.HandleOptOut(ctx, "chainID", providerAddr) + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) +} + +func TestHandleOptOutFromTopNChain(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // set a consumer client so that the chain is considered running + providerKeeper.SetConsumerClientId(ctx, chainID, "clientID") + + // set the chain as Top 50 and create 4 validators with 10%, 20%, 30%, and 40% of the total voting power + // respectively + providerKeeper.SetTopN(ctx, "chainID", 50) + valA := createStakingValidator(ctx, mocks, 1, 1, 1) // 10% of the total voting power (can opt out) + valAConsAddr, _ := valA.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valAConsAddr).Return(valA, nil).AnyTimes() + valB := createStakingValidator(ctx, mocks, 2, 2, 2) // 20% of the total voting power (can opt out) + valBConsAddr, _ := valB.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valBConsAddr).Return(valB, nil).AnyTimes() + valC := createStakingValidator(ctx, mocks, 3, 3, 3) // 30% of the total voting power (cannot opt out) + valCConsAddr, _ := valC.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valCConsAddr).Return(valC, nil).AnyTimes() + valD := createStakingValidator(ctx, mocks, 4, 4, 4) // 40% of the total voting power (cannot opt out) + valDConsAddr, _ := valD.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valDConsAddr).Return(valD, nil).AnyTimes() + + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 4, []stakingtypes.Validator{valA, valB, valC, valD}, []int64{1, 2, 3, 4}, -1) // -1 to allow mocks AnyTimes + + // initialize the minPowerInTopN correctly + minPowerInTopN, err := providerKeeper.ComputeMinPowerInTopN(ctx, []stakingtypes.Validator{valA, valB, valC, valD}, 50) + require.NoError(t, err) + providerKeeper.SetMinimumPowerInTopN(ctx, chainID, minPowerInTopN) + + // opt in all validators + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valDConsAddr)) + + // validators A and B can opt out because they belong the bottom 30% of validators + require.NoError(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valAConsAddr))) + require.NoError(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valBConsAddr))) + + // validators C and D cannot opt out because C has 30% of the voting power and D has 40% of the voting power + // and hence both are needed to keep validating a Top 50 chain + require.Error(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valCConsAddr))) + require.Error(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valDConsAddr))) + + // opting out a validator that cannot be found from a Top N chain should also return an error + notFoundValidator := createStakingValidator(ctx, mocks, 5, 5, 5) + notFoundValidatorConsAddr, _ := notFoundValidator.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, notFoundValidatorConsAddr). + Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound) + require.Error(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(notFoundValidatorConsAddr))) +} + +func TestOptInTopNValidators(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // create 4 validators with powers 1, 2, 3, and 1 respectively + valA := createStakingValidator(ctx, mocks, 1, 1, 1) + valAConsAddr, _ := valA.GetConsAddr() + valB := createStakingValidator(ctx, mocks, 2, 2, 2) + valBConsAddr, _ := valB.GetConsAddr() + valC := createStakingValidator(ctx, mocks, 3, 3, 3) + valCConsAddr, _ := valC.GetConsAddr() + valD := createStakingValidator(ctx, mocks, 4, 1, 4) + valDConsAddr, _ := valD.GetConsAddr() + + // Start Test 1: opt in all validators with power >= 0 + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 0) + expectedOptedInValidators := []types.ProviderConsAddress{ + types.NewProviderConsAddress(valAConsAddr), + types.NewProviderConsAddress(valBConsAddr), + types.NewProviderConsAddress(valCConsAddr), + types.NewProviderConsAddress(valDConsAddr), + } + actualOptedInValidators := providerKeeper.GetAllOptedIn(ctx, "chainID") + + // sort validators first to be able to compare + sortUpdates := func(addresses []types.ProviderConsAddress) { + sort.Slice(addresses, func(i, j int) bool { + return bytes.Compare(addresses[i].ToSdkConsAddr(), addresses[j].ToSdkConsAddr()) < 0 + }) + } + + sortUpdates(expectedOptedInValidators) + sortUpdates(actualOptedInValidators) + require.Equal(t, expectedOptedInValidators, actualOptedInValidators) + + // reset state for the upcoming checks + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valDConsAddr)) + + // Start Test 2: opt in all validators with power >= 1 + // We expect the same `expectedOptedInValidators` as when we opted in all validators with power >= 0 because the + // validators with the smallest power have power == 1 + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 0) + actualOptedInValidators = providerKeeper.GetAllOptedIn(ctx, "chainID") + sortUpdates(actualOptedInValidators) + require.Equal(t, expectedOptedInValidators, actualOptedInValidators) + + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valDConsAddr)) + + // Start Test 3: opt in all validators with power >= 2 and hence we do not expect to opt in validator A + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 2) + expectedOptedInValidators = []types.ProviderConsAddress{ + types.NewProviderConsAddress(valBConsAddr), + types.NewProviderConsAddress(valCConsAddr), + } + actualOptedInValidators = providerKeeper.GetAllOptedIn(ctx, "chainID") + + // sort validators first to be able to compare + sortUpdates(expectedOptedInValidators) + sortUpdates(actualOptedInValidators) + require.Equal(t, expectedOptedInValidators, actualOptedInValidators) + + // reset state for the upcoming checks + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valDConsAddr)) + + // Start Test 4: opt in all validators with power >= 4 and hence we do not expect any opted-in validators + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 4) + require.Empty(t, providerKeeper.GetAllOptedIn(ctx, "chainID")) +} + +func TestComputeMinPowerInTopN(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // create 5 validators with powers 1, 3, 5, 6, 10 (not in that order) with total power of 25 (= 1 + 3 + 5 + 6 + 10) + // such that: + // validator power => cumulative share + // 10 => 40% + // 6 => 64% + // 5 => 84% + // 3 => 96% + // 1 => 100% + + bondedValidators := []stakingtypes.Validator{ + createStakingValidator(ctx, mocks, 1, 5, 1), + createStakingValidator(ctx, mocks, 2, 10, 2), + createStakingValidator(ctx, mocks, 3, 3, 3), + createStakingValidator(ctx, mocks, 4, 1, 4), + createStakingValidator(ctx, mocks, 5, 6, 5), + } + + m, err := providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 100) + require.NoError(t, err) + require.Equal(t, int64(1), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 97) + require.NoError(t, err) + require.Equal(t, int64(1), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 96) + require.NoError(t, err) + require.Equal(t, int64(3), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 85) + require.NoError(t, err) + require.Equal(t, int64(3), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 84) + require.NoError(t, err) + require.Equal(t, int64(5), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 65) + require.NoError(t, err) + require.Equal(t, int64(5), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 64) + require.NoError(t, err) + require.Equal(t, int64(6), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 50) + require.NoError(t, err) + require.Equal(t, int64(6), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 40) + require.NoError(t, err) + require.Equal(t, int64(10), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 1) + require.NoError(t, err) + require.Equal(t, int64(10), m) + + _, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 0) + require.Error(t, err) + + _, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 101) + require.Error(t, err) +} + +// TestCanValidateChain returns true if `validator` is opted in, in `chainID. +func TestCanValidateChain(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + validator := createStakingValidator(ctx, mocks, 0, 1, 1) + consAddr, _ := validator.GetConsAddr() + providerAddr := types.NewProviderConsAddress(consAddr) + + // with no allowlist or denylist, the validator has to be opted in, in order to consider it + require.False(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + providerKeeper.SetOptedIn(ctx, "chainID", types.NewProviderConsAddress(consAddr)) + require.True(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + + // create an allow list but do not add the validator `providerAddr` to it + validatorA := createStakingValidator(ctx, mocks, 1, 1, 2) + consAddrA, _ := validatorA.GetConsAddr() + providerKeeper.SetAllowlist(ctx, "chainID", types.NewProviderConsAddress(consAddrA)) + require.False(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + providerKeeper.SetAllowlist(ctx, "chainID", types.NewProviderConsAddress(consAddr)) + require.True(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + + // create a denylist but do not add validator `providerAddr` to it + providerKeeper.SetDenylist(ctx, "chainID", types.NewProviderConsAddress(consAddrA)) + require.True(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + // add validator `providerAddr` to the denylist + providerKeeper.SetDenylist(ctx, "chainID", types.NewProviderConsAddress(consAddr)) + require.False(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) +} + +func TestCapValidatorSet(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + validatorA := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrA"), + Power: 1, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorB := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrB"), + Power: 2, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorC := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrC"), + Power: 3, + ConsumerPublicKey: &crypto.PublicKey{}, + } + validators := []types.ConsumerValidator{validatorA, validatorB, validatorC} + + consumerValidators := providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, validators, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 0) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, validators, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 100) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, validators, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 1) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, []types.ConsumerValidator{validatorC}, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 2) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, []types.ConsumerValidator{validatorC, validatorB}, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 3) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, []types.ConsumerValidator{validatorC, validatorB, validatorA}, consumerValidators) +} + +func TestCapValidatorsPower(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + validatorA := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrA"), + Power: 1, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorB := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrB"), + Power: 2, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorC := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrC"), + Power: 3, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorD := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrD"), + Power: 4, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validators := []types.ConsumerValidator{validatorA, validatorB, validatorC, validatorD} + + expectedValidators := make([]types.ConsumerValidator, len(validators)) + copy(expectedValidators, validators) + expectedValidators[0].Power = 2 + expectedValidators[1].Power = 2 + expectedValidators[2].Power = 3 + expectedValidators[3].Power = 3 + + sortValidators := func(validators []types.ConsumerValidator) { + sort.Slice(validators, func(i, j int) bool { + return bytes.Compare(validators[i].ProviderConsAddr, validators[j].ProviderConsAddr) < 0 + }) + } + + // no capping takes place because validators power-cap is not set + cappedValidators := providerKeeper.CapValidatorsPower(ctx, "chainID", validators) + sortValidators(validators) + sortValidators(cappedValidators) + require.Equal(t, validators, cappedValidators) + + providerKeeper.SetValidatorsPowerCap(ctx, "chainID", 33) + cappedValidators = providerKeeper.CapValidatorsPower(ctx, "chainID", validators) + sortValidators(expectedValidators) + sortValidators(cappedValidators) + require.Equal(t, expectedValidators, cappedValidators) +} + +func TestNoMoreThanPercentOfTheSum(t *testing.T) { + // **impossible** case where we only have 9 powers, and we want that no number has more than 10% of the total sum + powers := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9} + percent := uint32(10) + require.False(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 20 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 21 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 25 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 32 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 33 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 34 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 50 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) +} + +func createConsumerValidators(powers []int64) []types.ConsumerValidator { + var validators []types.ConsumerValidator + for _, p := range powers { + validators = append(validators, types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddr"), + Power: p, + ConsumerPublicKey: &crypto.PublicKey{}, + }) + } + return validators +} + +// returns `true` if no validator in `validators` corresponds to more than `percent` of the total sum of all +// validators' powers +func noMoreThanPercent(validators []types.ConsumerValidator, percent uint32) bool { + sum := int64(0) + for _, v := range validators { + sum = sum + v.Power + } + + for _, v := range validators { + if float64(v.Power)*100.0 > float64(percent)*float64(sum) { + return false + } + } + return true +} + +func sumPowers(vals []types.ConsumerValidator) int64 { + sum := int64(0) + for _, v := range vals { + sum += v.Power + } + return sum +} + +func CapSatisfiable(vals []types.ConsumerValidator, percent uint32) bool { + // 100 / len(vals) is what each validator gets if each has the same power. + // if this is more than the cap, it cannot be satisfied. + return float64(100)/float64(len(vals)) < float64(percent) +} + +func TestNoMoreThanPercentOfTheSumProps(t *testing.T) { + // define properties to test + + // capRespectedIfSatisfiable: if the cap can be respected, then it will be respected + capRespectedIfSatisfiable := func(valsBefore, valsAfter []types.ConsumerValidator, percent uint32) bool { + if CapSatisfiable(valsBefore, percent) { + return noMoreThanPercent(valsAfter, percent) + } + return true + } + + evenPowersIfCapCannotBeSatisfied := func(valsBefore, valsAfter []types.ConsumerValidator, percent uint32) bool { + if !CapSatisfiable(valsBefore, percent) { + // if the cap cannot be satisfied, each validator should have the same power + for _, valAfter := range valsAfter { + if valAfter.Power != valsAfter[0].Power { + return false + } + } + } + return true + } + + // fairness: if before, v1 has more power than v2, then afterwards v1 will not have less power than v2 + // (they might get the same power if they are both capped) + fairness := func(valsBefore, valsAfter []types.ConsumerValidator) bool { + for i, v := range valsBefore { + // find the validator after with the same address + vAfter := findConsumerValidator(t, v, valsAfter) + + // go through all other validators before (after this one, to avoid double checking) + for j := i + 1; j < len(valsBefore); j++ { + otherV := valsBefore[j] + otherVAfter := findConsumerValidator(t, otherV, valsAfter) + + // v has at least as much power before + if v.Power >= otherV.Power { + // then otherV should not have more power after + if vAfter.Power < otherVAfter.Power { + return false + } + } else { + // v has less power before + // then v should not have more power after + if vAfter.Power > otherVAfter.Power { + return false + } + } + } + } + return true + } + + // non-zero: v has non-zero power before IFF it has non-zero power after + nonZero := func(valsBefore, valsAfter []types.ConsumerValidator) bool { + for _, v := range valsBefore { + vAfter := findConsumerValidator(t, v, valsAfter) + if (v.Power == 0) != (vAfter.Power == 0) { + return false + } + } + return true + } + + // equalSumIfCapSatisfiable: the sum of the powers of the validators will not change if the cap can be satisfied + // (except for small changes by rounding errors) + equalSumIfCapSatisfiable := func(valsBefore, valsAfter []types.ConsumerValidator, percent uint32) bool { + if CapSatisfiable(valsBefore, percent) { + difference := gomath.Abs(float64(sumPowers(valsBefore) - sumPowers(valsAfter))) + if difference > 1 { + // if the difference is more than a rounding error, they are not equal + return false + } + } + return true + } + + // num validators: the number of validators will not change + equalNumVals := func(valsBefore, valsAfter []types.ConsumerValidator) bool { + return len(valsBefore) == len(valsAfter) + } + + // test setup for pbt + rapid.Check(t, func(t *rapid.T) { + powers := rapid.SliceOf(rapid.Int64Range(1, 1000000000000)).Draw(t, "powers") + percent := uint32(rapid.Int32Range(1, 100).Draw(t, "percent")) + + consumerValidators := createConsumerValidators(powers) + cappedValidators := keeper.NoMoreThanPercentOfTheSum(consumerValidators, percent) + + t.Log("can the cap be satisfied: ", CapSatisfiable(consumerValidators, percent)) + t.Log("before: ", consumerValidators) + t.Log("after: ", cappedValidators) + + // check properties + require.True(t, capRespectedIfSatisfiable(consumerValidators, cappedValidators, percent)) + require.True(t, evenPowersIfCapCannotBeSatisfied(consumerValidators, cappedValidators, percent)) + require.True(t, fairness(consumerValidators, cappedValidators)) + require.True(t, nonZero(consumerValidators, cappedValidators)) + require.True(t, equalSumIfCapSatisfiable(consumerValidators, cappedValidators, percent), "sum before: %v, sum after: %v", sumPowers(consumerValidators), sumPowers(cappedValidators)) + require.True(t, equalNumVals(consumerValidators, cappedValidators), "num before: %v, num after: %v", len(consumerValidators), len(cappedValidators)) + }) +} + +func findConsumerValidator(t *testing.T, v types.ConsumerValidator, valsAfter []types.ConsumerValidator) *types.ConsumerValidator { + var vAfter *types.ConsumerValidator + for _, vA := range valsAfter { + if bytes.Equal(v.ProviderConsAddr, vA.ProviderConsAddr) { + vAfter = &vA + break + } + } + if vAfter == nil { + t.Fatalf("could not find validator with address %v in validators after \n validators after capping: %v", v.ProviderConsAddr, valsAfter) + } + return vAfter +} \ No newline at end of file diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index 2b7a243baa..71f305cce0 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -40,6 +40,11 @@ func (k Keeper) HandleConsumerAdditionProposal(ctx sdk.Context, proposal *types. BlocksPerDistributionTransmission: proposal.BlocksPerDistributionTransmission, HistoricalEntries: proposal.HistoricalEntries, DistributionTransmissionChannel: proposal.DistributionTransmissionChannel, + Top_N: proposal.Top_N, + ValidatorsPowerCap: proposal.ValidatorsPowerCap, + ValidatorSetCap: proposal.ValidatorSetCap, + Allowlist: proposal.Allowlist, + Denylist: proposal.Denylist, } return k.HandleLegacyConsumerAdditionProposal(ctx, &p) @@ -70,9 +75,14 @@ func (k Keeper) HandleConsumerRewardDenomProposal(ctx sdk.Context, proposal *typ // HandleConsumerModificationProposal modifies a running consumer chain func (k Keeper) HandleConsumerModificationProposal(ctx sdk.Context, proposal *types.MsgConsumerModification) error { p := types.ConsumerModificationProposal{ - Title: proposal.Title, - Description: proposal.Description, - ChainId: proposal.ChainId, + Title: proposal.Title, + Description: proposal.Description, + ChainId: proposal.ChainId, + Top_N: proposal.Top_N, + ValidatorsPowerCap: proposal.ValidatorsPowerCap, + ValidatorSetCap: proposal.ValidatorSetCap, + Allowlist: proposal.Allowlist, + Denylist: proposal.Denylist, } return k.HandleLegacyConsumerModificationProposal(ctx, &p) @@ -173,6 +183,7 @@ func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan boo k.DeleteConsumerGenesis(ctx, chainID) // Note: this call panics if the key assignment state is invalid k.DeleteKeyAssignments(ctx, chainID) + k.DeleteMinimumPowerInTopN(ctx, chainID) k.DeleteEquivocationEvidenceMinHeight(ctx, chainID) // close channel and delete the mappings between chain ID and channel ID @@ -201,6 +212,13 @@ func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan boo k.DeleteSlashAcks(ctx, chainID) k.DeletePendingVSCPackets(ctx, chainID) + k.DeleteTopN(ctx, chainID) + k.DeleteValidatorsPowerCap(ctx, chainID) + k.DeleteValidatorSetCap(ctx, chainID) + k.DeleteAllowlist(ctx, chainID) + k.DeleteDenylist(ctx, chainID) + + k.DeleteAllOptedIn(ctx, chainID) k.DeleteConsumerValSet(ctx, chainID) k.Logger(ctx).Info("consumer chain removed from provider", "chainID", chainID) @@ -246,7 +264,15 @@ func (k Keeper) MakeConsumerGenesis( return gen, nil, errorsmod.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting last bonded validators: %s", err) } - // For Replicated Security, all bonded validators validate the consumer chain + if prop.Top_N > 0 { + // in a Top-N chain, we automatically opt in all validators that belong to the top N + minPower, err := k.ComputeMinPowerInTopN(ctx, bondedValidators, prop.Top_N) + if err != nil { + return gen, nil, err + } + k.OptInTopNValidators(ctx, chainID, bondedValidators, minPower) + k.SetMinimumPowerInTopN(ctx, chainID, minPower) + } nextValidators := k.ComputeNextValidators(ctx, chainID, bondedValidators) k.SetConsumerValSet(ctx, chainID, nextValidators) @@ -335,6 +361,28 @@ func (k Keeper) BeginBlockInit(ctx sdk.Context) { // create consumer client in a cached context to handle errors cachedCtx, writeFn := ctx.CacheContext() + k.SetTopN(cachedCtx, prop.ChainId, prop.Top_N) + k.SetValidatorSetCap(cachedCtx, prop.ChainId, prop.ValidatorSetCap) + k.SetValidatorsPowerCap(cachedCtx, prop.ChainId, prop.ValidatorsPowerCap) + + for _, address := range prop.Allowlist { + consAddr, err := sdk.ConsAddressFromBech32(address) + if err != nil { + continue + } + + k.SetAllowlist(cachedCtx, prop.ChainId, types.NewProviderConsAddress(consAddr)) + } + + for _, address := range prop.Denylist { + consAddr, err := sdk.ConsAddressFromBech32(address) + if err != nil { + continue + } + + k.SetDenylist(cachedCtx, prop.ChainId, types.NewProviderConsAddress(consAddr)) + } + err := k.CreateConsumerClient(cachedCtx, &propsToExecute[i]) if err != nil { // drop the proposal diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index 926c4fb26a..d35b0f54a3 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -67,6 +67,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, // Opt-in chain - doesn't require validators at startup ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: true, @@ -92,6 +93,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, // Opt-in chain - doesn't require validators at startup ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: false, @@ -788,72 +790,132 @@ func TestBeginBlockInit(t *testing.T) { ctx = ctx.WithBlockTime(now) pendingProps := []*providertypes.ConsumerAdditionProposal{ - providertypes.NewConsumerAdditionProposal( - "title", "spawn time passed", "chain1", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, - now.Add(-time.Hour*2).UTC(), - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), - providertypes.NewConsumerAdditionProposal( - "title", "spawn time passed", "chain2", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, - now.Add(-time.Hour*1).UTC(), - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), - providertypes.NewConsumerAdditionProposal( - "title", "spawn time not passed", "chain3", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, - now.Add(time.Hour).UTC(), - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), - providertypes.NewConsumerAdditionProposal( - "title", "invalid proposal: chain id already exists", "chain2", clienttypes.NewHeight(4, 5), []byte{}, []byte{}, - now.UTC(), - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), - providertypes.NewConsumerAdditionProposal( - "title", "opt-in chain with at least one validator opted in", "chain5", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, - now.Add(-time.Hour*1).UTC(), - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), - providertypes.NewConsumerAdditionProposal( - "title", "opt-in chain with no validator opted in", "chain6", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, - now.Add(-time.Minute).UTC(), - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), + { + Title: "title", + Description: "spawn time passed", + ChainId: "chain1", + InitialHeight: clienttypes.NewHeight(3, 4), + GenesisHash: []byte{}, + BinaryHash: []byte{}, + SpawnTime: now.Add(-time.Hour * 2).UTC(), + ConsumerRedistributionFraction: "0.75", + BlocksPerDistributionTransmission: 10, + DistributionTransmissionChannel: "", + HistoricalEntries: 10000, + CcvTimeoutPeriod: 100000000000, + TransferTimeoutPeriod: 100000000000, + UnbondingPeriod: 100000000000, + Top_N: 50, + ValidatorsPowerCap: 0, + ValidatorSetCap: 0, + Allowlist: nil, + Denylist: nil, + }, + { + Title: "title", + Description: "spawn time passed", + ChainId: "chain2", + InitialHeight: clienttypes.NewHeight(3, 4), + GenesisHash: []byte{}, + BinaryHash: []byte{}, + SpawnTime: now.Add(-time.Hour * 1).UTC(), + ConsumerRedistributionFraction: "0.75", + BlocksPerDistributionTransmission: 10, + DistributionTransmissionChannel: "", + HistoricalEntries: 10000, + CcvTimeoutPeriod: 100000000000, + TransferTimeoutPeriod: 100000000000, + UnbondingPeriod: 100000000000, + Top_N: 50, + ValidatorsPowerCap: 0, + ValidatorSetCap: 0, + Allowlist: nil, + Denylist: nil, + }, + { + Title: "title", + Description: "spawn time not passed", + ChainId: "chain3", + InitialHeight: clienttypes.NewHeight(3, 4), + GenesisHash: []byte{}, + BinaryHash: []byte{}, + SpawnTime: now.Add(time.Hour).UTC(), + ConsumerRedistributionFraction: "0.75", + BlocksPerDistributionTransmission: 10, + DistributionTransmissionChannel: "", + HistoricalEntries: 10000, + CcvTimeoutPeriod: 100000000000, + TransferTimeoutPeriod: 100000000000, + UnbondingPeriod: 100000000000, + Top_N: 50, + ValidatorsPowerCap: 0, + ValidatorSetCap: 0, + Allowlist: nil, + Denylist: nil, + }, + { + Title: "title", + Description: "invalid proposal: chain id already exists", + ChainId: "chain2", + InitialHeight: clienttypes.NewHeight(4, 5), + GenesisHash: []byte{}, + BinaryHash: []byte{}, + SpawnTime: now.UTC(), + ConsumerRedistributionFraction: "0.75", + BlocksPerDistributionTransmission: 10, + DistributionTransmissionChannel: "", + HistoricalEntries: 10000, + CcvTimeoutPeriod: 100000000000, + TransferTimeoutPeriod: 100000000000, + UnbondingPeriod: 100000000000, + Top_N: 50, + ValidatorsPowerCap: 0, + ValidatorSetCap: 0, + Allowlist: nil, + Denylist: nil, + }, + { + Title: "title", + Description: "opt-in chain with at least one validator opted in", + ChainId: "chain5", + InitialHeight: clienttypes.NewHeight(3, 4), + GenesisHash: []byte{}, + BinaryHash: []byte{}, + SpawnTime: now.Add(-time.Hour * 1).UTC(), + ConsumerRedistributionFraction: "0.75", + BlocksPerDistributionTransmission: 10, + DistributionTransmissionChannel: "", + HistoricalEntries: 10000, + CcvTimeoutPeriod: 100000000000, + TransferTimeoutPeriod: 100000000000, + UnbondingPeriod: 100000000000, + Top_N: 0, // Opt-in chain + ValidatorsPowerCap: 0, + ValidatorSetCap: 0, + Allowlist: nil, + Denylist: nil, + }, + { + Title: "title", + Description: "opt-in chain with no validator opted in", + ChainId: "chain6", + InitialHeight: clienttypes.NewHeight(3, 4), + GenesisHash: []byte{}, + BinaryHash: []byte{}, + SpawnTime: now.Add(-time.Minute).UTC(), + ConsumerRedistributionFraction: "0.75", + BlocksPerDistributionTransmission: 10, + DistributionTransmissionChannel: "", + HistoricalEntries: 10000, + CcvTimeoutPeriod: 100000000000, + TransferTimeoutPeriod: 100000000000, + UnbondingPeriod: 100000000000, + Top_N: 0, // Opt-in chain + ValidatorsPowerCap: 0, + ValidatorSetCap: 0, + Allowlist: nil, + Denylist: nil, + }, } // Expect client creation for only the first, second, and fifth proposals (spawn time already passed and valid) @@ -871,12 +933,14 @@ func TestBeginBlockInit(t *testing.T) { providerKeeper.SetPendingConsumerAdditionProp(ctx, prop) } - // For Replicated Security, all bonded validators participate - no opt-in needed + // opt in a sample validator so chain5's proposal can successfully execute validator := cryptotestutil.NewCryptoIdentityFromIntSeed(0).SDKStakingValidator() + consAddr, _ := validator.GetConsAddr() testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 1, []stakingtypes.Validator{validator}, []int64{0}, -1) // -1 to allow any number of calls valAddr, _ := sdk.ValAddressFromBech32(validator.GetOperator()) mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), valAddr).Return(int64(1), nil).AnyTimes() + providerKeeper.SetOptedIn(ctx, pendingProps[4].ChainId, providertypes.NewProviderConsAddress(consAddr)) providerKeeper.BeginBlockInit(ctx) @@ -911,7 +975,8 @@ func TestBeginBlockInit(t *testing.T) { // Note that we do not check that `GetConsumerGenesis(ctx, pendingProps[3].ChainId)` returns `false` here because // `pendingProps[3]` is an invalid proposal due to the chain id already existing so the consumer genesis also exists - // fifth proposal should be successfully executed (spawn time passed) + // fifth proposal corresponds to an Opt-In chain with one opted-in validator and hence the proposal gets + // successfully executed _, found = providerKeeper.GetPendingConsumerAdditionProp( ctx, pendingProps[4].SpawnTime, pendingProps[4].ChainId) require.False(t, found) @@ -919,13 +984,33 @@ func TestBeginBlockInit(t *testing.T) { _, found = providerKeeper.GetConsumerGenesis(ctx, pendingProps[4].ChainId) require.True(t, found) - // sixth proposal should also be successfully executed (spawn time passed) + // sixth proposal corresponds to an Opt-In chain with no opted-in validators and hence the + // proposal is not successful _, found = providerKeeper.GetPendingConsumerAdditionProp( ctx, pendingProps[5].SpawnTime, pendingProps[5].ChainId) + // the proposal was dropped and deleted require.False(t, found) - // sixth proposal was successfully executed and hence consumer genesis was created + // no consumer genesis is created _, found = providerKeeper.GetConsumerGenesis(ctx, pendingProps[5].ChainId) + require.False(t, found) + // no consumer client is associated with this chain + _, found = providerKeeper.GetConsumerClientId(ctx, pendingProps[5].ChainId) + require.False(t, found) + // no fields should be set for this (check some of them) + _, found = providerKeeper.GetTopN(ctx, pendingProps[5].ChainId) + require.False(t, found) + _, found = providerKeeper.GetValidatorsPowerCap(ctx, pendingProps[5].ChainId) + require.False(t, found) + _, found = providerKeeper.GetValidatorSetCap(ctx, pendingProps[5].ChainId) + require.False(t, found) + + // test that Top N is set correctly + require.True(t, providerKeeper.IsTopN(ctx, "chain1")) + topN, found := providerKeeper.GetTopN(ctx, "chain1") require.True(t, found) + require.Equal(t, uint32(50), topN) + + require.True(t, providerKeeper.IsOptIn(ctx, "chain5")) } // TestBeginBlockCCR tests BeginBlockCCR against the spec. diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index 81a68e5d89..8fa4fd783c 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -104,10 +104,21 @@ func TestQueueVSCPacketsDoesNotResetConsumerValidatorsHeights(t *testing.T) { mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valBConsAddr).Return(valB, nil).AnyTimes() testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 2, []stakingtypes.Validator{valA, valB}, []int64{1, 2}, -1) + // Set up GetLastValidatorPower mocks for CreateConsumerValidator + valAAddr, _ := sdk.ValAddressFromBech32(valA.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, valAAddr).Return(int64(1), nil).AnyTimes() + valBAddr, _ := sdk.ValAddressFromBech32(valB.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, valBAddr).Return(int64(2), nil).AnyTimes() + // set a consumer client, so we have a consumer chain (i.e., `k.GetAllConsumerChains(ctx)` is non empty) providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") - // For Replicated Security, all bonded validators participate + // For Replicated Security with TopN, validators need to be opted in + // We're not setting TopN here, so the chain behaves as opt-in (TopN=0) + // Opt in both validators since this test expects them to validate + providerKeeper.SetOptedIn(ctx, "chainID", types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.SetOptedIn(ctx, "chainID", types.NewProviderConsAddress(valBConsAddr)) + // Set validator A as a consumer validator consumerValidatorA := types.ConsumerValidator{ ProviderConsAddr: valAConsAddr, @@ -117,8 +128,7 @@ func TestQueueVSCPacketsDoesNotResetConsumerValidatorsHeights(t *testing.T) { } providerKeeper.SetConsumerValidator(ctx, "chainID", consumerValidatorA) - // Note: In Replicated Security, validator B will automatically be included - // since all bonded validators participate + // Note: Validator B is opted in but will be created fresh when QueueVSCPackets runs providerKeeper.QueueVSCPackets(ctx) @@ -584,7 +594,8 @@ func TestEndBlockVSU(t *testing.T) { chainID := "chainID" - // For replicated security, all validators participate (no TopN needed) + // Set TopN=100 for replicated security (all validators participate) + providerKeeper.SetTopN(ctx, chainID, 100) // 10 blocks constitute an epoch params := providertypes.DefaultParams() @@ -605,6 +616,12 @@ func TestEndBlockVSU(t *testing.T) { testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 5, lastValidators, powers, -1) + // Opt in validators for TopN=100 chain + minPower, err := providerKeeper.ComputeMinPowerInTopN(ctx, lastValidators, 100) + require.NoError(t, err) + providerKeeper.OptInTopNValidators(ctx, chainID, lastValidators, minPower) + providerKeeper.SetMinimumPowerInTopN(ctx, chainID, minPower) + // set a sample client for a consumer chain so that `GetAllConsumerChains` in `QueueVSCPackets` iterates at least once providerKeeper.SetConsumerClientId(ctx, chainID, "clientID") @@ -661,14 +678,48 @@ func TestQueueVSCPacketsForReplicatedSecurity(t *testing.T) { testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 5, []stakingtypes.Validator{valA, valB, valC, valD, valE}, []int64{1, 3, 4, 8, 16}, -1) + // Set up GetLastValidatorPower mocks for OptInTopNValidators + valAAddr, _ := sdk.ValAddressFromBech32(valA.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, valAAddr).Return(int64(1), nil).AnyTimes() + valBAddr, _ := sdk.ValAddressFromBech32(valB.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, valBAddr).Return(int64(3), nil).AnyTimes() + valCAddr, _ := sdk.ValAddressFromBech32(valC.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, valCAddr).Return(int64(4), nil).AnyTimes() + valDAddr, _ := sdk.ValAddressFromBech32(valD.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, valDAddr).Return(int64(8), nil).AnyTimes() + valEAddr, _ := sdk.ValAddressFromBech32(valE.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, valEAddr).Return(int64(16), nil).AnyTimes() + // add a consumer chain providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") // For replicated security, all validators participate - // No opt-in, denylist, or power capping needed + // Set TopN to 100 to indicate all validators must validate (top 100%) + providerKeeper.SetTopN(ctx, "chainID", 100) + + // Check if chain is registered + registeredChains := providerKeeper.GetAllRegisteredConsumerChainIDs(ctx) + require.Contains(t, registeredChains, "chainID", "chainID should be in registered chains") + + // Check that TopN is set correctly + topN, found := providerKeeper.GetTopN(ctx, "chainID") + require.True(t, found, "TopN should be found") + require.Equal(t, uint32(100), topN, "TopN should be 100") + + // For TopN chains, we need to opt in the validators + // When TopN=100, all validators should be opted in (this normally happens in MakeConsumerGenesis) + bondedValidators := []stakingtypes.Validator{valA, valB, valC, valD, valE} + minPower, err := providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 100) + require.NoError(t, err, "ComputeMinPowerInTopN should not error") + providerKeeper.OptInTopNValidators(ctx, "chainID", bondedValidators, minPower) + providerKeeper.SetMinimumPowerInTopN(ctx, "chainID", minPower) providerKeeper.QueueVSCPackets(ctx) + // Check if validators are opted in after QueueVSCPackets + optedInValsAfter := providerKeeper.GetAllOptedIn(ctx, "chainID") + require.Len(t, optedInValsAfter, 5, "Expected 5 opted in validators after QueueVSCPackets") + actualQueuedVSCPackets := providerKeeper.GetPendingVSCPackets(ctx, "chainID") expectedQueuedVSCPackets := []ccv.ValidatorSetChangePacketData{ ccv.NewValidatorSetChangePacketData( diff --git a/x/ccv/provider/keeper/validator_set_update.go b/x/ccv/provider/keeper/validator_set_update.go index 2a2fe2e8a8..056e24e3aa 100644 --- a/x/ccv/provider/keeper/validator_set_update.go +++ b/x/ccv/provider/keeper/validator_set_update.go @@ -231,16 +231,3 @@ func (k Keeper) GetLastBondedValidators(ctx sdk.Context) ([]stakingtypes.Validat return ccv.GetLastBondedValidatorsUtil(ctx, k.stakingKeeper, k.Logger(ctx)) } -// ComputeNextValidators computes the next validator set for a consumer chain. -// For Replicated Security, all bonded validators are included in the consumer validator set. -func (k Keeper) ComputeNextValidators( - ctx sdk.Context, - chainID string, - bondedValidators []stakingtypes.Validator, -) []types.ConsumerValidator { - // For Replicated Security, we include all bonded validators - // The predicate always returns true to include every validator - return k.FilterValidators(ctx, chainID, bondedValidators, func(providerAddr types.ProviderConsAddress) bool { - return true - }) -} diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index 16231fdc52..b32d0c8025 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -46,6 +46,7 @@ func TestProviderProposalHandler(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, // TopN = 0 for opt-in chain ), blockTime: hourFromNow, // ctx blocktime is after proposal's spawn time expValidConsumerAddition: true, diff --git a/x/ccv/provider/types/errors.go b/x/ccv/provider/types/errors.go index a10317667e..3c6fe2495b 100644 --- a/x/ccv/provider/types/errors.go +++ b/x/ccv/provider/types/errors.go @@ -24,6 +24,7 @@ var ( ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client") ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists") ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found") + ErrCannotOptOutFromTopN = errorsmod.Register(ModuleName, 20, "cannot opt out from a Top N chain") ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 21, "no unconfirmed vsc packet for this chain id") ErrInvalidConsumerModificationProposal = errorsmod.Register(ModuleName, 22, "invalid consumer modification proposal") ErrNoUnbondingTime = errorsmod.Register(ModuleName, 23, "provider unbonding time not found") diff --git a/x/ccv/provider/types/events.go b/x/ccv/provider/types/events.go index ed54157e78..1ac479526c 100644 --- a/x/ccv/provider/types/events.go +++ b/x/ccv/provider/types/events.go @@ -7,6 +7,8 @@ const ( EventTypeAddConsumerRewardDenom = "add_consumer_reward_denom" EventTypeRemoveConsumerRewardDenom = "remove_consumer_reward_denom" EventTypeExecuteConsumerChainSlash = "execute_consumer_chain_slash" + EventTypeOptIn = "opt_in" + EventTypeOptOut = "opt_out" AttributeInfractionHeight = "infraction_height" AttributeInitialHeight = "initial_height" AttributeTrustingPeriod = "trusting_period" diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index e8d2481de9..bef642bdcc 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -159,6 +159,30 @@ const ( // validators in this epoch that are validating the consumer chain ConsumerValidatorBytePrefix + // OptedInBytePrefix is the byte prefix for storing whether a validator is opted in to validate on a consumer chain + OptedInBytePrefix + + // TopNBytePrefix is the byte prefix storing the mapping from a consumer chain to the N value of this chain, + // that corresponds to the N% of the top validators that have to validate this consumer chain + TopNBytePrefix + + // ValidatorsPowerCapPrefix is the byte prefix storing the mapping from a consumer chain to the power-cap value of this chain, + // that corresponds to p% such that no validator can have more than p% of the voting power on the consumer chain. + // Operates on a best-effort basis. + ValidatorsPowerCapPrefix + + // ValidatorSetCapPrefix is the byte prefix storing the mapping from a consumer chain to the validator-set cap value + // of this chain. + ValidatorSetCapPrefix + + // AllowlistPrefix is the byte prefix storing the mapping from a consumer chain to the set of validators that are + // allowlisted. + AllowlistPrefix + + // DenylistPrefix is the byte prefix storing the mapping from a consumer chain to the set of validators that are + // denylisted. + DenylistPrefix + // ConsumerRewardsAllocationBytePrefix is the byte prefix for storing for each consumer the ICS rewards // allocated to the consumer rewards pool ConsumerRewardsAllocationBytePrefix @@ -166,6 +190,11 @@ const ( // ConsumerAddrsToPruneV2Key is the byte prefix for storing consumer validators addresses // that need to be pruned. ConsumerAddrsToPruneV2BytePrefix + + // MinimumPowerInTopNBytePrefix is the byte prefix for storing the + // minimum power required to be in the top N per consumer chain. + MinimumPowerInTopNBytePrefix + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -498,6 +527,18 @@ func ConsumerValidatorKey(chainID string, providerAddr []byte) []byte { return append(prefix, providerAddr...) } +// TopNKey returns the key used to store the Top N value per consumer chain. +// This value corresponds to the N% of the top validators that have to validate the consumer chain. +func TopNKey(chainID string) []byte { + return ChainIdWithLenKey(TopNBytePrefix, chainID) +} + +// OptedInKey returns the key used to store whether a validator is opted in on a consumer chain. +func OptedInKey(chainID string, providerAddr ProviderConsAddress) []byte { + prefix := ChainIdWithLenKey(OptedInBytePrefix, chainID) + return append(prefix, providerAddr.ToSdkConsAddr().Bytes()...) +} + // ConsumerRewardsAllocationKey returns the key used to store the ICS rewards per consumer chain func ConsumerRewardsAllocationKey(chainID string) []byte { return append([]byte{ConsumerRewardsAllocationBytePrefix}, []byte(chainID)...) @@ -509,6 +550,32 @@ func ConsumerAddrsToPruneV2Key(chainID string, pruneTs time.Time) []byte { return ChainIdAndTsKey(ConsumerAddrsToPruneV2BytePrefix, chainID, pruneTs) } +// MinimumPowerInTopNKey returns the key used to store the minimum power required +// to be in the top N for a given consumer chain. +func MinimumPowerInTopNKey(chainID string) []byte { + return ChainIdWithLenKey(MinimumPowerInTopNBytePrefix, chainID) +} + +// ValidatorSetCapKey returns the key used to store the validator set cap for a given consumer chain. +func ValidatorSetCapKey(chainID string) []byte { + return ChainIdWithLenKey(ValidatorSetCapPrefix, chainID) +} + +// ValidatorsPowerCapKey returns the key used to store the power cap for validators on a given consumer chain. +func ValidatorsPowerCapKey(chainID string) []byte { + return ChainIdWithLenKey(ValidatorsPowerCapPrefix, chainID) +} + +// AllowlistCapKey returns the key used to store the allowlist entry for a validator on a given consumer chain. +func AllowlistCapKey(chainID string, providerAddr ProviderConsAddress) []byte { + return append(ChainIdWithLenKey(AllowlistPrefix, chainID), providerAddr.ToSdkConsAddr().Bytes()...) +} + +// DenylistCapKey returns the key used to store the denylist entry for a validator on a given consumer chain. +func DenylistCapKey(chainID string, providerAddr ProviderConsAddress) []byte { + return append(ChainIdWithLenKey(DenylistPrefix, chainID), providerAddr.ToSdkConsAddr().Bytes()...) +} + // // End of generic helpers section // diff --git a/x/ccv/provider/types/legacy_proposal.go b/x/ccv/provider/types/legacy_proposal.go index 7030d209ab..801717debb 100644 --- a/x/ccv/provider/types/legacy_proposal.go +++ b/x/ccv/provider/types/legacy_proposal.go @@ -53,6 +53,7 @@ func NewConsumerAdditionProposal(title, description, chainID string, ccvTimeoutPeriod time.Duration, transferTimeoutPeriod time.Duration, unbondingPeriod time.Duration, + topN uint32, ) govv1beta1.Content { return &ConsumerAdditionProposal{ Title: title, @@ -69,6 +70,7 @@ func NewConsumerAdditionProposal(title, description, chainID string, CcvTimeoutPeriod: ccvTimeoutPeriod, TransferTimeoutPeriod: transferTimeoutPeriod, UnbondingPeriod: unbondingPeriod, + Top_N: topN, } } diff --git a/x/ccv/provider/types/legacy_proposal_test.go b/x/ccv/provider/types/legacy_proposal_test.go index 8010163e99..63869883d4 100644 --- a/x/ccv/provider/types/legacy_proposal_test.go +++ b/x/ccv/provider/types/legacy_proposal_test.go @@ -36,6 +36,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), true, }, @@ -49,6 +50,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), true, }, @@ -62,6 +64,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -75,6 +78,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -108,6 +112,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -120,7 +125,8 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 100), false, }, { @@ -133,6 +139,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -146,6 +153,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -159,6 +167,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -172,6 +181,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -185,6 +195,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 100, ), false, }, @@ -198,6 +209,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 0, 100000000000, 100000000000, + 100, ), false, }, @@ -211,6 +223,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 0, 100000000000, + 100, ), false, }, @@ -224,6 +237,7 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 0, + 100, ), false, }, @@ -248,7 +262,8 @@ func TestMarshalConsumerAdditionProposal(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000) + 100000000000, + 100) cccp, ok := content.(*types.ConsumerAdditionProposal) require.True(t, ok) @@ -290,7 +305,8 @@ func TestConsumerAdditionProposalString(t *testing.T) { 500000, 100000000000, 10000000000, - 100000000000) + 100000000000, + 100) expect := fmt.Sprintf(`CreateConsumerChain Proposal Title: title diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index 060426a048..6385ae2e41 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -94,6 +94,32 @@ type ConsumerAdditionProposal struct { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintain the existing ibc transfer channel DistributionTransmissionChannel string `protobuf:"bytes,14,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,15,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,16,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,17,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + Allowlist []string `protobuf:"bytes,18,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,19,rep,name=denylist,proto3" json:"denylist,omitempty"` } func (m *ConsumerAdditionProposal) Reset() { *m = ConsumerAdditionProposal{} } @@ -216,6 +242,32 @@ type ConsumerModificationProposal struct { Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // the chain-id of the consumer chain to be modified ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,4,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,5,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,6,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + Allowlist []string `protobuf:"bytes,7,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,8,rep,name=denylist,proto3" json:"denylist,omitempty"` } func (m *ConsumerModificationProposal) Reset() { *m = ConsumerModificationProposal{} } @@ -272,6 +324,41 @@ func (m *ConsumerModificationProposal) GetChainId() string { return "" } +func (m *ConsumerModificationProposal) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *ConsumerModificationProposal) GetValidatorsPowerCap() uint32 { + if m != nil { + return m.ValidatorsPowerCap + } + return 0 +} + +func (m *ConsumerModificationProposal) GetValidatorSetCap() uint32 { + if m != nil { + return m.ValidatorSetCap + } + return 0 +} + +func (m *ConsumerModificationProposal) GetAllowlist() []string { + if m != nil { + return m.Allowlist + } + return nil +} + +func (m *ConsumerModificationProposal) GetDenylist() []string { + if m != nil { + return m.Denylist + } + return nil +} + // EquivocationProposal is a governance proposal on the provider chain to // punish a validator for equivocation on a consumer chain. // @@ -1297,117 +1384,124 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 1753 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcd, 0x6f, 0xdb, 0xc8, - 0x15, 0x37, 0x2d, 0xd9, 0x96, 0x46, 0xb6, 0xe3, 0x30, 0x69, 0x22, 0xbb, 0xae, 0xe4, 0x68, 0x9b, - 0xc0, 0x6d, 0x1a, 0xb2, 0xf6, 0xa2, 0x40, 0x10, 0x74, 0x11, 0xd8, 0x72, 0x76, 0xb3, 0xf6, 0x7e, - 0xa8, 0xb4, 0x90, 0x05, 0xb6, 0x07, 0x62, 0x38, 0x1c, 0x4b, 0x53, 0x93, 0x1c, 0x66, 0x66, 0xc4, - 0x54, 0x97, 0x9e, 0x7b, 0x29, 0xb0, 0xbd, 0x2d, 0x7a, 0xe9, 0x02, 0xbd, 0x14, 0x3d, 0xf5, 0xd0, - 0xbf, 0xa0, 0x87, 0x62, 0x51, 0xa0, 0xe8, 0x1e, 0x7b, 0xda, 0x2d, 0x9c, 0x43, 0x0f, 0xfd, 0x1b, - 0x0a, 0x14, 0xf3, 0x41, 0x8a, 0xf2, 0x47, 0xa3, 0xc5, 0x36, 0x17, 0x9b, 0x7c, 0xf3, 0x7b, 0xbf, - 0xf7, 0xde, 0xcc, 0xfb, 0x18, 0x0a, 0xec, 0x92, 0x44, 0x60, 0x86, 0x86, 0x90, 0x24, 0x3e, 0xc7, - 0x68, 0xc4, 0x88, 0x18, 0xbb, 0x08, 0x65, 0x6e, 0xca, 0x68, 0x46, 0x42, 0xcc, 0xdc, 0x6c, 0xa7, - 0x78, 0x76, 0x52, 0x46, 0x05, 0xb5, 0xdf, 0xb8, 0x44, 0xc7, 0x41, 0x28, 0x73, 0x0a, 0x5c, 0xb6, - 0xb3, 0x71, 0xf7, 0x2a, 0xe2, 0x6c, 0xc7, 0x7d, 0x41, 0x18, 0xd6, 0x5c, 0x1b, 0x37, 0x07, 0x74, - 0x40, 0xd5, 0xa3, 0x2b, 0x9f, 0x8c, 0xb4, 0x3d, 0xa0, 0x74, 0x10, 0x61, 0x57, 0xbd, 0x05, 0xa3, - 0x13, 0x57, 0x90, 0x18, 0x73, 0x01, 0xe3, 0xd4, 0x00, 0x5a, 0xe7, 0x01, 0xe1, 0x88, 0x41, 0x41, - 0x68, 0x92, 0x13, 0x90, 0x00, 0xb9, 0x88, 0x32, 0xec, 0xa2, 0x88, 0xe0, 0x44, 0x48, 0xab, 0xfa, - 0xc9, 0x00, 0x5c, 0x09, 0x88, 0xc8, 0x60, 0x28, 0xb4, 0x98, 0xbb, 0x02, 0x27, 0x21, 0x66, 0x31, - 0xd1, 0xe0, 0xc9, 0x9b, 0x51, 0xd8, 0x2c, 0xad, 0x23, 0x36, 0x4e, 0x05, 0x75, 0x4f, 0xf1, 0x98, - 0x9b, 0xd5, 0x7b, 0x88, 0xf2, 0x98, 0x72, 0x17, 0xcb, 0xf8, 0x13, 0x84, 0xdd, 0x6c, 0x27, 0xc0, - 0x02, 0xee, 0x14, 0x82, 0xdc, 0x6f, 0x83, 0x0b, 0x20, 0x9f, 0x60, 0x10, 0x25, 0xb9, 0xdf, 0xeb, - 0x7a, 0xdd, 0xd7, 0x3b, 0xa2, 0x5f, 0xcc, 0xd2, 0x75, 0x18, 0x93, 0x84, 0xba, 0xea, 0xaf, 0x16, - 0x75, 0xfe, 0xb3, 0x08, 0x9a, 0x5d, 0x9a, 0xf0, 0x51, 0x8c, 0xd9, 0x5e, 0x18, 0x12, 0xb9, 0x01, - 0x3d, 0x46, 0x53, 0xca, 0x61, 0x64, 0xdf, 0x04, 0x0b, 0x82, 0x88, 0x08, 0x37, 0xad, 0x2d, 0x6b, - 0xbb, 0xee, 0xe9, 0x17, 0x7b, 0x0b, 0x34, 0x42, 0xcc, 0x11, 0x23, 0xa9, 0x04, 0x37, 0xe7, 0xd5, - 0x5a, 0x59, 0x64, 0xaf, 0x83, 0x9a, 0x3e, 0x35, 0x12, 0x36, 0x2b, 0x6a, 0x79, 0x49, 0xbd, 0xbf, - 0x1b, 0xda, 0xef, 0x80, 0x55, 0x92, 0x10, 0x41, 0x60, 0xe4, 0x0f, 0xb1, 0xdc, 0xbb, 0x66, 0x75, - 0xcb, 0xda, 0x6e, 0xec, 0x6e, 0x38, 0x24, 0x40, 0x8e, 0xdc, 0x6e, 0xc7, 0x6c, 0x72, 0xb6, 0xe3, - 0x3c, 0x55, 0x88, 0xfd, 0xea, 0xe7, 0x5f, 0xb6, 0xe7, 0xbc, 0x15, 0xa3, 0xa7, 0x85, 0xf6, 0x1d, - 0xb0, 0x3c, 0xc0, 0x09, 0xe6, 0x84, 0xfb, 0x43, 0xc8, 0x87, 0xcd, 0x85, 0x2d, 0x6b, 0x7b, 0xd9, - 0x6b, 0x18, 0xd9, 0x53, 0xc8, 0x87, 0x76, 0x1b, 0x34, 0x02, 0x92, 0x40, 0x36, 0xd6, 0x88, 0x45, - 0x85, 0x00, 0x5a, 0xa4, 0x00, 0x5d, 0x00, 0x78, 0x0a, 0x5f, 0x24, 0xbe, 0xcc, 0x8d, 0xe6, 0x92, - 0x71, 0x44, 0xe7, 0x85, 0x93, 0xe7, 0x85, 0xd3, 0xcf, 0x13, 0x67, 0xbf, 0x26, 0x1d, 0xf9, 0xe4, - 0xab, 0xb6, 0xe5, 0xd5, 0x95, 0x9e, 0x5c, 0xb1, 0x3f, 0x00, 0x6b, 0xa3, 0x24, 0xa0, 0x49, 0x48, - 0x92, 0x81, 0x9f, 0x62, 0x46, 0x68, 0xd8, 0xac, 0x29, 0xaa, 0xf5, 0x0b, 0x54, 0x07, 0x26, 0xc5, - 0x34, 0xd3, 0xa7, 0x92, 0xe9, 0x5a, 0xa1, 0xdc, 0x53, 0xba, 0xf6, 0x4f, 0x80, 0x8d, 0x50, 0xa6, - 0x5c, 0xa2, 0x23, 0x91, 0x33, 0xd6, 0x67, 0x67, 0x5c, 0x43, 0x28, 0xeb, 0x6b, 0x6d, 0x43, 0xf9, - 0x53, 0x70, 0x5b, 0x30, 0x98, 0xf0, 0x13, 0xcc, 0xce, 0xf3, 0x82, 0xd9, 0x79, 0xbf, 0x95, 0x73, - 0x4c, 0x93, 0x3f, 0x05, 0x5b, 0xc8, 0x24, 0x90, 0xcf, 0x70, 0x48, 0xb8, 0x60, 0x24, 0x18, 0x49, - 0x5d, 0xff, 0x84, 0x41, 0xa4, 0x72, 0xa4, 0xa1, 0x92, 0xa0, 0x95, 0xe3, 0xbc, 0x29, 0xd8, 0xdb, - 0x06, 0x65, 0x7f, 0x08, 0xbe, 0x1b, 0x44, 0x14, 0x9d, 0x72, 0xe9, 0x9c, 0x3f, 0xc5, 0xa4, 0x4c, - 0xc7, 0x84, 0x73, 0xc9, 0xb6, 0xbc, 0x65, 0x6d, 0x57, 0xbc, 0x3b, 0x1a, 0xdb, 0xc3, 0xec, 0xa0, - 0x84, 0xec, 0x97, 0x80, 0xf6, 0x03, 0x60, 0x0f, 0x09, 0x17, 0x94, 0x11, 0x04, 0x23, 0x1f, 0x27, - 0x82, 0x11, 0xcc, 0x9b, 0x2b, 0x4a, 0xfd, 0xfa, 0x64, 0xe5, 0x89, 0x5e, 0xb0, 0x0f, 0xc1, 0x9d, - 0x2b, 0x8d, 0xfa, 0x68, 0x08, 0x93, 0x04, 0x47, 0xcd, 0x55, 0x15, 0x4a, 0x3b, 0xbc, 0xc2, 0x66, - 0x57, 0xc3, 0x1e, 0xdd, 0xfb, 0xe5, 0x67, 0xed, 0xb9, 0x4f, 0x3f, 0x6b, 0xcf, 0xfd, 0xf5, 0x4f, - 0x0f, 0x36, 0x4c, 0x11, 0x0e, 0x68, 0xe6, 0x98, 0x82, 0x75, 0xba, 0x34, 0x11, 0x38, 0x11, 0x9d, - 0xbf, 0x5b, 0xe0, 0x76, 0xb7, 0xd8, 0x96, 0x98, 0x66, 0x30, 0x7a, 0x9d, 0xe5, 0xb7, 0x07, 0xea, - 0x5c, 0xd0, 0x54, 0x27, 0x7c, 0xf5, 0x6b, 0x24, 0x7c, 0x4d, 0xaa, 0xc9, 0x85, 0x47, 0xad, 0x57, - 0x44, 0xf4, 0x1c, 0x6c, 0xe6, 0x01, 0xbd, 0x4f, 0x43, 0x72, 0x42, 0x10, 0x7c, 0xcd, 0x4d, 0xa5, - 0xf3, 0x5b, 0x0b, 0xdc, 0x7c, 0xf2, 0x7c, 0x44, 0x32, 0xfa, 0x7f, 0xb2, 0x75, 0x04, 0x56, 0x70, - 0x89, 0x8f, 0x37, 0x2b, 0x5b, 0x95, 0xed, 0xc6, 0xee, 0x5d, 0xc7, 0xc4, 0x5d, 0xb4, 0xe4, 0x3c, - 0xf8, 0xb2, 0x75, 0x6f, 0x5a, 0xf7, 0xd1, 0x7c, 0xd3, 0xea, 0xfc, 0xd9, 0x02, 0x1b, 0x32, 0x35, - 0x06, 0xd8, 0xc3, 0x2f, 0x20, 0x0b, 0x0f, 0x70, 0x42, 0x63, 0xfe, 0x8d, 0xfd, 0xec, 0x80, 0x95, - 0x50, 0x31, 0xf9, 0x82, 0xfa, 0x30, 0x0c, 0x95, 0x9f, 0x0a, 0x23, 0x85, 0x7d, 0xba, 0x17, 0x86, - 0xf6, 0x36, 0x58, 0x9b, 0x60, 0x98, 0x4c, 0x31, 0x79, 0xf2, 0x12, 0xb6, 0x9a, 0xc3, 0x54, 0xe2, - 0xbd, 0xfa, 0x64, 0xff, 0x6d, 0x81, 0xb5, 0x77, 0x22, 0x1a, 0xc0, 0xe8, 0x38, 0x82, 0x7c, 0x28, - 0xcb, 0x66, 0x2c, 0x33, 0x8a, 0x61, 0xd3, 0xaf, 0x94, 0xfb, 0x33, 0x67, 0x94, 0x54, 0x53, 0x1d, - 0xf4, 0x31, 0xb8, 0x5e, 0x74, 0x90, 0xe2, 0x88, 0x55, 0xb4, 0xfb, 0x37, 0xce, 0xbe, 0x6c, 0x5f, - 0xcb, 0xd3, 0xa9, 0xab, 0x8e, 0xfb, 0xc0, 0xbb, 0x86, 0xa6, 0x04, 0xa1, 0xdd, 0x02, 0x0d, 0x12, - 0x20, 0x9f, 0xe3, 0xe7, 0x7e, 0x32, 0x8a, 0x55, 0x76, 0x54, 0xbd, 0x3a, 0x09, 0xd0, 0x31, 0x7e, - 0xfe, 0xc1, 0x28, 0xb6, 0xdf, 0x04, 0xb7, 0xf2, 0x7b, 0x85, 0x9f, 0xc1, 0xc8, 0x97, 0xfa, 0x72, - 0xbb, 0x98, 0x2a, 0x81, 0x65, 0xef, 0x46, 0xbe, 0xfa, 0x0c, 0x46, 0xd2, 0xd8, 0x5e, 0x18, 0xb2, - 0xce, 0xef, 0x16, 0xc0, 0x62, 0x0f, 0x32, 0x18, 0x73, 0xbb, 0x0f, 0xae, 0x09, 0x1c, 0xa7, 0x11, - 0x14, 0xd8, 0xd7, 0xd3, 0xc9, 0x44, 0x7a, 0x5f, 0x4d, 0xad, 0xf2, 0x1d, 0xc0, 0x29, 0x4d, 0xfd, - 0x6c, 0xc7, 0xe9, 0x2a, 0xe9, 0xb1, 0x80, 0x02, 0x7b, 0xab, 0x39, 0x87, 0x16, 0xda, 0x0f, 0x41, - 0x53, 0xb0, 0x11, 0x17, 0x93, 0xb9, 0x31, 0x69, 0x98, 0xfa, 0xac, 0x6f, 0xe5, 0xeb, 0xba, 0xd5, - 0x16, 0x8d, 0xf2, 0xf2, 0x11, 0x51, 0xf9, 0x26, 0x23, 0x22, 0x04, 0x9b, 0x5c, 0x1e, 0xaa, 0x1f, - 0x63, 0xa1, 0x1a, 0x79, 0x1a, 0xe1, 0x84, 0xf0, 0x61, 0x4e, 0xbe, 0x38, 0x3b, 0xf9, 0xba, 0x22, - 0x7a, 0x5f, 0xf2, 0x78, 0x39, 0x8d, 0xb1, 0xd2, 0x05, 0xad, 0xcb, 0xad, 0x14, 0x81, 0x2f, 0xa9, - 0xc0, 0xbf, 0x7d, 0x09, 0x45, 0x11, 0x3d, 0x07, 0xf7, 0x4a, 0x03, 0x47, 0x56, 0x93, 0xaf, 0x12, - 0xd9, 0x67, 0x78, 0x20, 0xbb, 0x32, 0xd4, 0xb3, 0x07, 0xe3, 0x62, 0x68, 0x9a, 0x9c, 0x96, 0x37, - 0xa6, 0x52, 0x52, 0x93, 0xc4, 0xdc, 0x2c, 0x3a, 0x93, 0xb9, 0x54, 0xd4, 0xa6, 0x57, 0xe2, 0x7a, - 0x1b, 0x63, 0x59, 0x45, 0xa5, 0xd9, 0x84, 0x53, 0x8a, 0x86, 0x6a, 0x76, 0x56, 0xbc, 0xd5, 0x62, - 0x0e, 0x3d, 0x91, 0x52, 0xfb, 0x63, 0x70, 0x3f, 0x19, 0xc5, 0x01, 0x66, 0x3e, 0x3d, 0xd1, 0x40, - 0x55, 0x79, 0x5c, 0x40, 0x26, 0x7c, 0x86, 0x11, 0x26, 0x99, 0x3c, 0x71, 0xed, 0x39, 0x57, 0xa3, - 0xb1, 0xe2, 0xdd, 0xd5, 0x2a, 0x1f, 0x9e, 0x28, 0x0e, 0xde, 0xa7, 0xc7, 0x12, 0xee, 0xe5, 0x68, - 0xed, 0x18, 0x3f, 0xac, 0xd6, 0xaa, 0x6b, 0x0b, 0x87, 0xd5, 0xda, 0xc2, 0xda, 0xe2, 0x61, 0xb5, - 0x56, 0x5b, 0xab, 0x77, 0xbe, 0x07, 0xea, 0xaa, 0x18, 0xf7, 0xd0, 0x29, 0xb7, 0x37, 0x41, 0x5d, - 0x66, 0x35, 0xe6, 0x1c, 0xf3, 0xa6, 0xa5, 0x6a, 0x7c, 0x22, 0xe8, 0x08, 0xb0, 0x7e, 0xd5, 0x4d, - 0x8f, 0xdb, 0x1f, 0x81, 0xa5, 0x14, 0xab, 0x6b, 0x88, 0x52, 0x6c, 0xec, 0xbe, 0xe5, 0xcc, 0x70, - 0x45, 0x77, 0xae, 0x22, 0xf4, 0x72, 0xb6, 0x0e, 0x9b, 0xdc, 0x2f, 0xcf, 0xcd, 0x37, 0x6e, 0x3f, - 0x3b, 0x6f, 0xf4, 0xc7, 0x5f, 0xcb, 0xe8, 0x39, 0xbe, 0x89, 0xcd, 0xfb, 0xa0, 0xb1, 0xa7, 0xc3, - 0x7e, 0x8f, 0x70, 0x71, 0x71, 0x5b, 0x96, 0xcb, 0xdb, 0x72, 0x08, 0x56, 0xcd, 0xd0, 0xee, 0x53, - 0xd5, 0x50, 0xec, 0xef, 0x00, 0x60, 0xa6, 0xbd, 0x6c, 0x44, 0xba, 0x25, 0xd7, 0x8d, 0xe4, 0xdd, - 0x70, 0x6a, 0x10, 0xcd, 0x4f, 0x0f, 0x22, 0x0a, 0xd6, 0x9f, 0xc1, 0x88, 0x84, 0x50, 0x50, 0x76, - 0x8c, 0x85, 0xee, 0xf8, 0x3d, 0x88, 0x4e, 0xb1, 0xe0, 0xb6, 0x07, 0xaa, 0x11, 0xe1, 0xc2, 0x84, - 0xfa, 0xf0, 0xca, 0x50, 0xb3, 0x1d, 0xe7, 0x2a, 0x92, 0x03, 0x28, 0xa0, 0x49, 0x5a, 0xc5, 0xd5, - 0xf9, 0xb5, 0x05, 0x9a, 0x47, 0x78, 0xbc, 0xc7, 0x39, 0x19, 0x24, 0x31, 0x4e, 0x84, 0x2c, 0x17, - 0x88, 0xb0, 0x7c, 0xb4, 0xdf, 0x00, 0x2b, 0x45, 0xdb, 0x53, 0xdd, 0xce, 0x52, 0xdd, 0x6e, 0x39, - 0x17, 0xca, 0x3d, 0xb2, 0x1f, 0x01, 0x90, 0x32, 0x9c, 0xf9, 0xc8, 0x3f, 0xc5, 0x63, 0x15, 0x4f, - 0x63, 0x77, 0xb3, 0xdc, 0xc5, 0xf4, 0x97, 0x8a, 0xd3, 0x1b, 0x05, 0x11, 0x41, 0x47, 0x78, 0xec, - 0xd5, 0x24, 0xbe, 0x7b, 0x84, 0xc7, 0x72, 0x6c, 0xa5, 0xf4, 0x05, 0x66, 0xaa, 0xf5, 0x54, 0x3c, - 0xfd, 0xd2, 0xf9, 0x8d, 0x05, 0x6e, 0x17, 0x01, 0xe4, 0x67, 0xd5, 0x1b, 0x05, 0x52, 0xa3, 0xbc, - 0x77, 0xd6, 0xf4, 0xd5, 0xe4, 0x82, 0xb7, 0xf3, 0x97, 0x78, 0xfb, 0x18, 0x2c, 0x17, 0xb5, 0x2f, - 0xfd, 0xad, 0xcc, 0xe0, 0x6f, 0x23, 0xd7, 0x38, 0xc2, 0xe3, 0xce, 0x2f, 0x4a, 0xbe, 0xed, 0x8f, - 0x4b, 0xe9, 0xcb, 0x5e, 0xe1, 0x5b, 0x61, 0xb6, 0xec, 0x1b, 0x2a, 0xeb, 0x5f, 0x08, 0xa0, 0x72, - 0x31, 0x80, 0xce, 0xdf, 0x2c, 0x70, 0xab, 0x6c, 0x95, 0xf7, 0x69, 0x8f, 0x8d, 0x12, 0xfc, 0x6c, - 0xf7, 0x7f, 0xd9, 0x7f, 0x0c, 0x6a, 0xa9, 0x44, 0xf9, 0x82, 0x9b, 0x23, 0x9a, 0x6d, 0xc6, 0x2e, - 0x29, 0xad, 0xbe, 0x2c, 0xef, 0xd5, 0xa9, 0x00, 0xb8, 0xd9, 0xb9, 0x1f, 0xce, 0x54, 0x70, 0xa5, - 0x62, 0xf2, 0x56, 0xca, 0x31, 0xf3, 0xce, 0x5f, 0x2c, 0x70, 0x3d, 0x8f, 0xa7, 0xd8, 0x58, 0xfb, - 0x07, 0xc0, 0x2e, 0xb6, 0x62, 0x32, 0x6c, 0x75, 0xfa, 0xad, 0xe5, 0x2b, 0xf9, 0xa4, 0x9d, 0xa4, - 0xd1, 0x7c, 0x29, 0x8d, 0xec, 0xf7, 0xc0, 0x8d, 0xc2, 0xe5, 0x54, 0x1d, 0xe6, 0xcc, 0x27, 0x5e, - 0x5c, 0x27, 0x0a, 0x91, 0xfc, 0x16, 0xfc, 0x19, 0x25, 0x49, 0xf9, 0xa3, 0xb3, 0xe2, 0x01, 0x29, - 0xd2, 0xdf, 0x93, 0x9d, 0x5f, 0x59, 0x93, 0xf6, 0x68, 0xda, 0xed, 0x5e, 0x14, 0x99, 0x4b, 0x9c, - 0x9d, 0x82, 0xa5, 0xbc, 0x61, 0xeb, 0xf2, 0xdd, 0xbc, 0x74, 0xa8, 0x1c, 0x60, 0xa4, 0xe6, 0xca, - 0x43, 0x79, 0x02, 0x7f, 0xf8, 0xaa, 0x7d, 0x7f, 0x40, 0xc4, 0x70, 0x14, 0x38, 0x88, 0xc6, 0xe6, - 0x4b, 0xdc, 0xfc, 0x7b, 0xc0, 0xc3, 0x53, 0x57, 0x8c, 0x53, 0xcc, 0x73, 0x1d, 0xfe, 0xfb, 0x7f, - 0xfd, 0xf1, 0xfb, 0x96, 0x97, 0x9b, 0xd9, 0xff, 0xe8, 0xf3, 0xb3, 0x96, 0xf5, 0xc5, 0x59, 0xcb, - 0xfa, 0xe7, 0x59, 0xcb, 0xfa, 0xe4, 0x65, 0x6b, 0xee, 0x8b, 0x97, 0xad, 0xb9, 0x7f, 0xbc, 0x6c, - 0xcd, 0x7d, 0xfc, 0xd6, 0x45, 0xd2, 0xc9, 0x21, 0x3e, 0x28, 0x7e, 0x28, 0xc9, 0x7e, 0xe4, 0xfe, - 0x7c, 0xfa, 0x67, 0x18, 0x65, 0x2f, 0x58, 0x54, 0x19, 0xf3, 0xe6, 0x7f, 0x03, 0x00, 0x00, 0xff, - 0xff, 0x56, 0x2e, 0x91, 0x7b, 0xb7, 0x11, 0x00, 0x00, + // 1865 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x4f, 0x6f, 0x1b, 0xc7, + 0x15, 0xd7, 0x8a, 0x94, 0x44, 0x0e, 0xf5, 0x87, 0x1a, 0xb9, 0xf1, 0x4a, 0x55, 0x49, 0x9a, 0xa9, + 0x0d, 0x35, 0xae, 0x97, 0x91, 0x82, 0x02, 0x86, 0xd1, 0xc0, 0x90, 0x28, 0x27, 0x8e, 0x94, 0x38, + 0xec, 0x8a, 0x70, 0x80, 0xf4, 0xb0, 0x18, 0xce, 0x8e, 0xc8, 0xa9, 0x96, 0x3b, 0xeb, 0x99, 0xe1, + 0xaa, 0xbc, 0xf4, 0xdc, 0x4b, 0x81, 0xf4, 0x16, 0xf4, 0xd0, 0x06, 0xe8, 0xa5, 0xc8, 0xa9, 0x87, + 0x7e, 0x82, 0x1e, 0x8a, 0xa0, 0x40, 0xd1, 0x1c, 0x7b, 0x4a, 0x0a, 0xfb, 0xd0, 0x43, 0xbf, 0x44, + 0x31, 0x33, 0xbb, 0xcb, 0xa5, 0xfe, 0xc4, 0x34, 0xd2, 0x5c, 0xa4, 0xdd, 0xf7, 0x7e, 0xef, 0x37, + 0xef, 0xcd, 0xbc, 0x79, 0xef, 0x2d, 0xc1, 0x1e, 0x0d, 0x25, 0xe1, 0x78, 0x80, 0x68, 0xe8, 0x09, + 0x82, 0x47, 0x9c, 0xca, 0x71, 0x0b, 0xe3, 0xb8, 0x15, 0x71, 0x16, 0x53, 0x9f, 0xf0, 0x56, 0xbc, + 0x9b, 0x3d, 0x3b, 0x11, 0x67, 0x92, 0xc1, 0xd7, 0xaf, 0xb0, 0x71, 0x30, 0x8e, 0x9d, 0x0c, 0x17, + 0xef, 0x6e, 0xdd, 0xbe, 0x8e, 0x38, 0xde, 0x6d, 0x9d, 0x53, 0x4e, 0x0c, 0xd7, 0xd6, 0x8d, 0x3e, + 0xeb, 0x33, 0xfd, 0xd8, 0x52, 0x4f, 0x89, 0xb4, 0xde, 0x67, 0xac, 0x1f, 0x90, 0x96, 0x7e, 0xeb, + 0x8d, 0x4e, 0x5b, 0x92, 0x0e, 0x89, 0x90, 0x68, 0x18, 0x25, 0x80, 0xda, 0x45, 0x80, 0x3f, 0xe2, + 0x48, 0x52, 0x16, 0xa6, 0x04, 0xb4, 0x87, 0x5b, 0x98, 0x71, 0xd2, 0xc2, 0x01, 0x25, 0xa1, 0x54, + 0xab, 0x9a, 0xa7, 0x04, 0xd0, 0x52, 0x80, 0x80, 0xf6, 0x07, 0xd2, 0x88, 0x45, 0x4b, 0x92, 0xd0, + 0x27, 0x7c, 0x48, 0x0d, 0x78, 0xf2, 0x96, 0x18, 0x6c, 0xe7, 0xf4, 0x98, 0x8f, 0x23, 0xc9, 0x5a, + 0x67, 0x64, 0x2c, 0x12, 0xed, 0x1d, 0xcc, 0xc4, 0x90, 0x89, 0x16, 0x51, 0xf1, 0x87, 0x98, 0xb4, + 0xe2, 0xdd, 0x1e, 0x91, 0x68, 0x37, 0x13, 0xa4, 0x7e, 0x27, 0xb8, 0x1e, 0x12, 0x13, 0x0c, 0x66, + 0x34, 0xf5, 0x7b, 0xd3, 0xe8, 0x3d, 0xb3, 0x23, 0xe6, 0x25, 0x51, 0xad, 0xa3, 0x21, 0x0d, 0x59, + 0x4b, 0xff, 0x35, 0xa2, 0xe6, 0xe7, 0x25, 0x60, 0xb7, 0x59, 0x28, 0x46, 0x43, 0xc2, 0xf7, 0x7d, + 0x9f, 0xaa, 0x0d, 0xe8, 0x70, 0x16, 0x31, 0x81, 0x02, 0x78, 0x03, 0x2c, 0x48, 0x2a, 0x03, 0x62, + 0x5b, 0x0d, 0x6b, 0xa7, 0xec, 0x9a, 0x17, 0xd8, 0x00, 0x15, 0x9f, 0x08, 0xcc, 0x69, 0xa4, 0xc0, + 0xf6, 0xbc, 0xd6, 0xe5, 0x45, 0x70, 0x13, 0x94, 0xcc, 0xa9, 0x51, 0xdf, 0x2e, 0x68, 0xf5, 0x92, + 0x7e, 0x7f, 0xcf, 0x87, 0xef, 0x82, 0x55, 0x1a, 0x52, 0x49, 0x51, 0xe0, 0x0d, 0x88, 0xda, 0x3b, + 0xbb, 0xd8, 0xb0, 0x76, 0x2a, 0x7b, 0x5b, 0x0e, 0xed, 0x61, 0x47, 0x6d, 0xb7, 0x93, 0x6c, 0x72, + 0xbc, 0xeb, 0x3c, 0xd6, 0x88, 0x83, 0xe2, 0x17, 0x5f, 0xd5, 0xe7, 0xdc, 0x95, 0xc4, 0xce, 0x08, + 0xe1, 0x2d, 0xb0, 0xdc, 0x27, 0x21, 0x11, 0x54, 0x78, 0x03, 0x24, 0x06, 0xf6, 0x42, 0xc3, 0xda, + 0x59, 0x76, 0x2b, 0x89, 0xec, 0x31, 0x12, 0x03, 0x58, 0x07, 0x95, 0x1e, 0x0d, 0x11, 0x1f, 0x1b, + 0xc4, 0xa2, 0x46, 0x00, 0x23, 0xd2, 0x80, 0x36, 0x00, 0x22, 0x42, 0xe7, 0xa1, 0xa7, 0x72, 0xc3, + 0x5e, 0x4a, 0x1c, 0x31, 0x79, 0xe1, 0xa4, 0x79, 0xe1, 0x74, 0xd3, 0xc4, 0x39, 0x28, 0x29, 0x47, + 0x3e, 0xf9, 0xba, 0x6e, 0xb9, 0x65, 0x6d, 0xa7, 0x34, 0xf0, 0x09, 0xa8, 0x8e, 0xc2, 0x1e, 0x0b, + 0x7d, 0x1a, 0xf6, 0xbd, 0x88, 0x70, 0xca, 0x7c, 0xbb, 0xa4, 0xa9, 0x36, 0x2f, 0x51, 0x1d, 0x26, + 0x29, 0x66, 0x98, 0x3e, 0x55, 0x4c, 0x6b, 0x99, 0x71, 0x47, 0xdb, 0xc2, 0x9f, 0x01, 0x88, 0x71, + 0xac, 0x5d, 0x62, 0x23, 0x99, 0x32, 0x96, 0x67, 0x67, 0xac, 0x62, 0x1c, 0x77, 0x8d, 0x75, 0x42, + 0xf9, 0x73, 0x70, 0x53, 0x72, 0x14, 0x8a, 0x53, 0xc2, 0x2f, 0xf2, 0x82, 0xd9, 0x79, 0xbf, 0x97, + 0x72, 0x4c, 0x93, 0x3f, 0x06, 0x0d, 0x9c, 0x24, 0x90, 0xc7, 0x89, 0x4f, 0x85, 0xe4, 0xb4, 0x37, + 0x52, 0xb6, 0xde, 0x29, 0x47, 0x58, 0xe7, 0x48, 0x45, 0x27, 0x41, 0x2d, 0xc5, 0xb9, 0x53, 0xb0, + 0x77, 0x12, 0x14, 0xfc, 0x10, 0xfc, 0xb0, 0x17, 0x30, 0x7c, 0x26, 0x94, 0x73, 0xde, 0x14, 0x93, + 0x5e, 0x7a, 0x48, 0x85, 0x50, 0x6c, 0xcb, 0x0d, 0x6b, 0xa7, 0xe0, 0xde, 0x32, 0xd8, 0x0e, 0xe1, + 0x87, 0x39, 0x64, 0x37, 0x07, 0x84, 0xf7, 0x00, 0x1c, 0x50, 0x21, 0x19, 0xa7, 0x18, 0x05, 0x1e, + 0x09, 0x25, 0xa7, 0x44, 0xd8, 0x2b, 0xda, 0x7c, 0x7d, 0xa2, 0x79, 0x64, 0x14, 0xf0, 0x08, 0xdc, + 0xba, 0x76, 0x51, 0x0f, 0x0f, 0x50, 0x18, 0x92, 0xc0, 0x5e, 0xd5, 0xa1, 0xd4, 0xfd, 0x6b, 0xd6, + 0x6c, 0x1b, 0x18, 0xdc, 0x00, 0x0b, 0x92, 0x45, 0xde, 0x13, 0x7b, 0xad, 0x61, 0xed, 0xac, 0xb8, + 0x45, 0xc9, 0xa2, 0x27, 0xf0, 0x4d, 0x70, 0x23, 0x46, 0x01, 0xf5, 0x91, 0x64, 0x5c, 0x78, 0x11, + 0x3b, 0x27, 0xdc, 0xc3, 0x28, 0xb2, 0xab, 0x1a, 0x03, 0x27, 0xba, 0x8e, 0x52, 0xb5, 0x51, 0x04, + 0xdf, 0x00, 0xeb, 0x99, 0xd4, 0x13, 0x44, 0x6a, 0xf8, 0xba, 0x86, 0xaf, 0x65, 0x8a, 0x13, 0x22, + 0x15, 0x76, 0x1b, 0x94, 0x51, 0x10, 0xb0, 0xf3, 0x80, 0x0a, 0x69, 0xc3, 0x46, 0x61, 0xa7, 0xec, + 0x4e, 0x04, 0x70, 0x0b, 0x94, 0x7c, 0x12, 0x8e, 0xb5, 0x72, 0x43, 0x2b, 0xb3, 0xf7, 0x07, 0x77, + 0x7e, 0xfd, 0x59, 0x7d, 0xee, 0xd3, 0xcf, 0xea, 0x73, 0x7f, 0xff, 0xcb, 0xbd, 0xad, 0xa4, 0x62, + 0xf4, 0x59, 0xec, 0x24, 0xd5, 0xc5, 0x69, 0xb3, 0x50, 0x92, 0x50, 0x36, 0xff, 0x69, 0x81, 0x9b, + 0xed, 0xec, 0x0c, 0x87, 0x2c, 0x46, 0xc1, 0x77, 0x59, 0x2b, 0xf6, 0x41, 0x59, 0xa8, 0x4d, 0xd4, + 0xb7, 0xb3, 0xf8, 0x0a, 0xb7, 0xb3, 0xa4, 0xcc, 0x94, 0xe2, 0x41, 0xed, 0x25, 0x11, 0xfd, 0x7e, + 0x1e, 0x6c, 0xa7, 0x11, 0x7d, 0xc0, 0x7c, 0x7a, 0x4a, 0x31, 0xfa, 0xae, 0x4b, 0x60, 0x96, 0x1a, + 0xc5, 0x19, 0x52, 0x63, 0xe1, 0xd5, 0x52, 0x63, 0x71, 0x86, 0xd4, 0x58, 0xfa, 0xa6, 0xd4, 0x28, + 0x4d, 0xa7, 0x46, 0xf3, 0x0f, 0x16, 0xb8, 0xf1, 0xe8, 0xd9, 0x88, 0xc6, 0xec, 0xff, 0xb4, 0x31, + 0xc7, 0x60, 0x85, 0xe4, 0xf8, 0x84, 0x5d, 0x68, 0x14, 0x76, 0x2a, 0x7b, 0xb7, 0x9d, 0xe4, 0x94, + 0xb2, 0x6e, 0x97, 0x1e, 0x55, 0x7e, 0x75, 0x77, 0xda, 0xf6, 0xc1, 0xbc, 0x6d, 0x35, 0xff, 0x6a, + 0x81, 0x2d, 0x75, 0xeb, 0xfa, 0xc4, 0x25, 0xe7, 0x88, 0xfb, 0x87, 0x24, 0x64, 0x43, 0xf1, 0xad, + 0xfd, 0x6c, 0x82, 0x15, 0x5f, 0x33, 0x79, 0x92, 0x79, 0xc8, 0xf7, 0xb5, 0x9f, 0x1a, 0xa3, 0x84, + 0x5d, 0xb6, 0xef, 0xfb, 0x70, 0x07, 0x54, 0x27, 0x18, 0xae, 0x2e, 0x84, 0xca, 0x53, 0x05, 0x5b, + 0x4d, 0x61, 0xfa, 0x9a, 0xbc, 0x3c, 0x0f, 0xff, 0x6b, 0x81, 0xea, 0xbb, 0x01, 0xeb, 0xa1, 0xe0, + 0x24, 0x40, 0x62, 0xa0, 0x2a, 0xd2, 0x58, 0xe5, 0x3f, 0x27, 0x49, 0x2b, 0xd0, 0xee, 0xcf, 0x9c, + 0xff, 0xca, 0x4c, 0x37, 0xa7, 0x87, 0x60, 0x3d, 0x2b, 0xce, 0x59, 0x3e, 0xea, 0x68, 0x0f, 0x36, + 0x9e, 0x7f, 0x55, 0x5f, 0x4b, 0x73, 0xbf, 0xad, 0x73, 0xf3, 0xd0, 0x5d, 0xc3, 0x53, 0x02, 0x1f, + 0xd6, 0x40, 0x85, 0xf6, 0xb0, 0x27, 0xc8, 0x33, 0x2f, 0x1c, 0x0d, 0x75, 0x2a, 0x17, 0xdd, 0x32, + 0xed, 0xe1, 0x13, 0xf2, 0xec, 0xc9, 0x68, 0x08, 0xdf, 0x02, 0xaf, 0xa5, 0x23, 0x9b, 0x17, 0xa3, + 0xc0, 0x53, 0xf6, 0x6a, 0xbb, 0xb8, 0xce, 0xee, 0x65, 0x77, 0x23, 0xd5, 0x3e, 0x45, 0x81, 0x5a, + 0x6c, 0xdf, 0xf7, 0x79, 0xf3, 0x8f, 0x0b, 0x60, 0xb1, 0x83, 0x38, 0x1a, 0x0a, 0xd8, 0x05, 0x6b, + 0x92, 0x0c, 0xa3, 0x00, 0x49, 0xe2, 0x99, 0xc6, 0x9f, 0x44, 0x7a, 0x57, 0x0f, 0x04, 0xf9, 0xf1, + 0xca, 0xc9, 0x0d, 0x54, 0xf1, 0xae, 0xd3, 0xd6, 0xd2, 0x13, 0x89, 0x24, 0x71, 0x57, 0x53, 0x0e, + 0x23, 0x84, 0xf7, 0x81, 0x2d, 0xf9, 0x48, 0xc8, 0x49, 0x4b, 0x9e, 0xf4, 0x22, 0x73, 0xd6, 0xaf, + 0xa5, 0x7a, 0xd3, 0xc5, 0xb2, 0x1e, 0x74, 0x75, 0xf7, 0x2d, 0x7c, 0x9b, 0xee, 0xeb, 0x83, 0x6d, + 0xa1, 0x0e, 0xd5, 0x1b, 0x12, 0xa9, 0x7b, 0x64, 0x14, 0x90, 0x90, 0x8a, 0x41, 0x4a, 0xbe, 0x38, + 0x3b, 0xf9, 0xa6, 0x26, 0xfa, 0x40, 0xf1, 0xb8, 0x29, 0x4d, 0xb2, 0x4a, 0x1b, 0xd4, 0xae, 0x5e, + 0x25, 0x0b, 0x7c, 0x49, 0x07, 0xfe, 0xfd, 0x2b, 0x28, 0xb2, 0xe8, 0x05, 0xb8, 0x93, 0xeb, 0xe5, + 0xea, 0x36, 0x79, 0x3a, 0x91, 0x3d, 0x4e, 0xfa, 0xaa, 0xe1, 0x21, 0xd3, 0xd6, 0x09, 0xc9, 0xe6, + 0x91, 0x24, 0xa7, 0xd5, 0x30, 0x9a, 0x4b, 0x6a, 0x1a, 0x26, 0x43, 0x5b, 0x73, 0xd2, 0xf2, 0xb3, + 0xbb, 0xe9, 0xe6, 0xb8, 0xde, 0x21, 0x44, 0xdd, 0xa2, 0x5c, 0xdb, 0x27, 0x11, 0xc3, 0x03, 0x3d, + 0x96, 0x14, 0xdc, 0xd5, 0xac, 0xc5, 0x3f, 0x52, 0x52, 0xf8, 0x31, 0xb8, 0x1b, 0x8e, 0x86, 0x3d, + 0xc2, 0x3d, 0x76, 0x6a, 0x80, 0xfa, 0xe6, 0x09, 0x89, 0xb8, 0xf4, 0x38, 0xc1, 0x84, 0xc6, 0xea, + 0xc4, 0x8d, 0xe7, 0x42, 0x4f, 0x1d, 0x05, 0xf7, 0xb6, 0x31, 0xf9, 0xf0, 0x54, 0x73, 0x88, 0x2e, + 0x3b, 0x51, 0x70, 0x37, 0x45, 0x1b, 0xc7, 0xc4, 0x51, 0xb1, 0x54, 0xac, 0x2e, 0x1c, 0x15, 0x4b, + 0x0b, 0xd5, 0xc5, 0xa3, 0x62, 0xa9, 0x54, 0x2d, 0x37, 0x7f, 0x04, 0xca, 0xfa, 0x32, 0xee, 0xe3, + 0x33, 0xa1, 0x2b, 0xa8, 0xef, 0x73, 0x22, 0x04, 0x11, 0xb6, 0x95, 0x54, 0xd0, 0x54, 0xd0, 0x94, + 0x60, 0xf3, 0xba, 0x21, 0x5a, 0xc0, 0x8f, 0xc0, 0x52, 0x44, 0xf4, 0x84, 0xa7, 0x0d, 0x2b, 0x7b, + 0x6f, 0x3b, 0x33, 0x7c, 0xfd, 0x38, 0xd7, 0x11, 0xba, 0x29, 0x5b, 0x93, 0x4f, 0x46, 0xf7, 0x0b, + 0xdd, 0x58, 0xc0, 0xa7, 0x17, 0x17, 0xfd, 0xe9, 0x2b, 0x2d, 0x7a, 0x81, 0x6f, 0xb2, 0xe6, 0x5d, + 0x50, 0xd9, 0x37, 0x61, 0xbf, 0xaf, 0x5a, 0xc7, 0xa5, 0x6d, 0x59, 0xce, 0x6f, 0xcb, 0x11, 0x58, + 0x4d, 0xe6, 0xa1, 0x2e, 0xd3, 0x05, 0x05, 0xfe, 0x00, 0x80, 0x64, 0x90, 0x52, 0x85, 0xc8, 0x94, + 0xe4, 0x72, 0x22, 0x79, 0xcf, 0x9f, 0xea, 0x9a, 0xf3, 0x53, 0x5d, 0xb3, 0xc9, 0xc0, 0xe6, 0xd3, + 0x7c, 0x57, 0xd3, 0x15, 0xbf, 0x83, 0xf0, 0x19, 0x91, 0x02, 0xba, 0xa0, 0xa8, 0xbb, 0x97, 0x09, + 0xf5, 0xfe, 0xb5, 0xa1, 0xc6, 0xbb, 0xce, 0x75, 0x24, 0x87, 0x48, 0xa2, 0x24, 0x69, 0x35, 0x57, + 0xf3, 0xb7, 0x16, 0xb0, 0x8f, 0xc9, 0x78, 0x5f, 0x08, 0xda, 0x0f, 0x87, 0x24, 0x94, 0xea, 0xba, + 0x20, 0x4c, 0xd4, 0x23, 0x7c, 0x1d, 0xac, 0x64, 0x65, 0x4f, 0x57, 0x3b, 0x4b, 0x57, 0xbb, 0xe5, + 0x54, 0xa8, 0xf6, 0x08, 0x3e, 0x00, 0x20, 0xe2, 0x24, 0xf6, 0xb0, 0x77, 0x46, 0xc6, 0x3a, 0x9e, + 0xca, 0xde, 0x76, 0xbe, 0x8a, 0x99, 0x8f, 0x40, 0xa7, 0x33, 0xea, 0x05, 0x14, 0x1f, 0x93, 0xb1, + 0x5b, 0x52, 0xf8, 0xf6, 0x31, 0x19, 0xab, 0xb6, 0xa5, 0x87, 0x00, 0x5d, 0x7a, 0x0a, 0xae, 0x79, + 0x69, 0xfe, 0xce, 0x02, 0x37, 0xb3, 0x00, 0xd2, 0xb3, 0xea, 0x8c, 0x7a, 0xca, 0x22, 0xbf, 0x77, + 0xd6, 0xf4, 0xc4, 0x71, 0xc9, 0xdb, 0xf9, 0x2b, 0xbc, 0x7d, 0x08, 0x96, 0xb3, 0xbb, 0xaf, 0xfc, + 0x2d, 0xcc, 0xe0, 0x6f, 0x25, 0xb5, 0x38, 0x26, 0xe3, 0xe6, 0xaf, 0x72, 0xbe, 0x1d, 0x8c, 0x73, + 0xe9, 0xcb, 0x5f, 0xe2, 0x5b, 0xb6, 0x6c, 0xde, 0x37, 0x9c, 0xb7, 0xbf, 0x14, 0x40, 0xe1, 0x72, + 0x00, 0xcd, 0x7f, 0x58, 0xe0, 0xb5, 0xfc, 0xaa, 0xa2, 0xcb, 0x3a, 0x7c, 0x14, 0x92, 0xa7, 0x7b, + 0xdf, 0xb4, 0xfe, 0x43, 0x50, 0x8a, 0x14, 0xca, 0x93, 0x22, 0x39, 0xa2, 0xd9, 0x7a, 0xec, 0x92, + 0xb6, 0xea, 0xaa, 0xeb, 0xbd, 0x3a, 0x15, 0x80, 0x48, 0x76, 0xee, 0xcd, 0x99, 0x2e, 0x5c, 0xee, + 0x32, 0xb9, 0x2b, 0xf9, 0x98, 0x45, 0xf3, 0x6f, 0x16, 0x58, 0x4f, 0xe3, 0xc9, 0x36, 0x16, 0xfe, + 0x18, 0xc0, 0x6c, 0x2b, 0x26, 0xcd, 0xd6, 0xa4, 0x5f, 0x35, 0xd5, 0xa4, 0x9d, 0x76, 0x92, 0x46, + 0xf3, 0xb9, 0x34, 0x82, 0xef, 0x83, 0x8d, 0xcc, 0xe5, 0x48, 0x1f, 0xe6, 0xcc, 0x27, 0x9e, 0x8d, + 0x13, 0x99, 0x48, 0x7d, 0x66, 0xff, 0x82, 0xd1, 0x30, 0xff, 0x3d, 0x5f, 0x70, 0x81, 0x12, 0x99, + 0x4f, 0xf5, 0xe6, 0x6f, 0xac, 0x49, 0x79, 0x4c, 0xca, 0xed, 0x7e, 0x10, 0x24, 0x43, 0x1c, 0x8c, + 0xc0, 0x52, 0x5a, 0xb0, 0xcd, 0xf5, 0xdd, 0xbe, 0xb2, 0xa9, 0x1c, 0x12, 0xac, 0xfb, 0xca, 0x7d, + 0x75, 0x02, 0x9f, 0x7f, 0x5d, 0xbf, 0xdb, 0xa7, 0x72, 0x30, 0xea, 0x39, 0x98, 0x0d, 0x93, 0x1f, + 0x39, 0x92, 0x7f, 0xf7, 0x84, 0x7f, 0xd6, 0x92, 0xe3, 0x88, 0x88, 0xd4, 0x46, 0xfc, 0xe9, 0x3f, + 0x7f, 0x7e, 0xc3, 0x72, 0xd3, 0x65, 0x0e, 0x3e, 0xfa, 0xe2, 0x79, 0xcd, 0xfa, 0xf2, 0x79, 0xcd, + 0xfa, 0xf7, 0xf3, 0x9a, 0xf5, 0xc9, 0x8b, 0xda, 0xdc, 0x97, 0x2f, 0x6a, 0x73, 0xff, 0x7a, 0x51, + 0x9b, 0xfb, 0xf8, 0xed, 0xcb, 0xa4, 0x93, 0x43, 0xbc, 0x97, 0xfd, 0x06, 0x15, 0xff, 0xa4, 0xf5, + 0xcb, 0xe9, 0x5f, 0xb8, 0xf4, 0x7a, 0xbd, 0x45, 0x9d, 0x31, 0x6f, 0xfd, 0x2f, 0x00, 0x00, 0xff, + 0xff, 0xae, 0x29, 0x6e, 0xec, 0x12, 0x13, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { @@ -1430,6 +1524,47 @@ func (m *ConsumerAdditionProposal) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x88 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } + if m.Top_N != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x78 + } if len(m.DistributionTransmissionChannel) > 0 { i -= len(m.DistributionTransmissionChannel) copy(dAtA[i:], m.DistributionTransmissionChannel) @@ -1606,6 +1741,39 @@ func (m *ConsumerModificationProposal) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x30 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x28 + } + if m.Top_N != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x20 + } if len(m.ChainId) > 0 { i -= len(m.ChainId) copy(dAtA[i:], m.ChainId) @@ -2423,6 +2591,27 @@ func (m *ConsumerAdditionProposal) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } + if m.Top_N != 0 { + n += 1 + sovProvider(uint64(m.Top_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 2 + sovProvider(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 2 + sovProvider(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 2 + l + sovProvider(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 2 + l + sovProvider(uint64(l)) + } + } return n } @@ -2467,6 +2656,27 @@ func (m *ConsumerModificationProposal) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } + if m.Top_N != 0 { + n += 1 + sovProvider(uint64(m.Top_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 1 + sovProvider(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 1 + sovProvider(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 1 + l + sovProvider(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 1 + l + sovProvider(uint64(l)) + } + } return n } @@ -3254,6 +3464,127 @@ func (m *ConsumerAdditionProposal) Unmarshal(dAtA []byte) error { } m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) + } + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", 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.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", 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.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:]) @@ -3579,6 +3910,127 @@ func (m *ConsumerModificationProposal) Unmarshal(dAtA []byte) error { } m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) + } + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", 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.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", 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.Denylist = append(m.Denylist, 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 275ff3757c..26076d73f1 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -375,6 +375,12 @@ func (m *QueryConsumerChainStopProposalsResponse) GetProposals() *ConsumerRemova type Chain struct { ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // If chain with `chainID` is a Top-N chain, i.e., enforces at least one + // validator to validate chain `chainID` + Top_N uint32 `protobuf:"varint,3,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // If the chain is a Top-N chain, this is the minimum power required to be in + // the top N. Otherwise, this is -1. + MinPowerInTop_N int64 `protobuf:"varint,4,opt,name=min_power_in_top_N,json=minPowerInTopN,proto3" json:"min_power_in_top_N,omitempty"` } func (m *Chain) Reset() { *m = Chain{} } @@ -424,6 +430,20 @@ func (m *Chain) GetClientId() string { return "" } +func (m *Chain) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *Chain) GetMinPowerInTop_N() int64 { + if m != nil { + return m.MinPowerInTop_N + } + return 0 +} + type QueryValidatorConsumerAddrRequest struct { // The id of the consumer chain ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` @@ -1305,6 +1325,103 @@ func (m *QueryConsumerValidatorsResponse) GetValidators() []*QueryConsumerValida return nil } +type QueryConsumerChainOptedInValidatorsRequest struct { + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +} + +func (m *QueryConsumerChainOptedInValidatorsRequest) Reset() { + *m = QueryConsumerChainOptedInValidatorsRequest{} +} +func (m *QueryConsumerChainOptedInValidatorsRequest) String() string { + return proto.CompactTextString(m) +} +func (*QueryConsumerChainOptedInValidatorsRequest) ProtoMessage() {} +func (*QueryConsumerChainOptedInValidatorsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{28} +} +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest.Merge(m, src) +} +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest proto.InternalMessageInfo + +func (m *QueryConsumerChainOptedInValidatorsRequest) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +type QueryConsumerChainOptedInValidatorsResponse struct { + // The consensus addresses of opted-in validators on the provider chain + ValidatorsProviderAddresses []string `protobuf:"bytes,1,rep,name=validators_provider_addresses,json=validatorsProviderAddresses,proto3" json:"validators_provider_addresses,omitempty"` +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) Reset() { + *m = QueryConsumerChainOptedInValidatorsResponse{} +} +func (m *QueryConsumerChainOptedInValidatorsResponse) String() string { + return proto.CompactTextString(m) +} +func (*QueryConsumerChainOptedInValidatorsResponse) ProtoMessage() {} +func (*QueryConsumerChainOptedInValidatorsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{29} +} +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse.Merge(m, src) +} +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse proto.InternalMessageInfo + +func (m *QueryConsumerChainOptedInValidatorsResponse) GetValidatorsProviderAddresses() []string { + if m != nil { + return m.ValidatorsProviderAddresses + } + return nil +} + func init() { proto.RegisterType((*QueryConsumerGenesisRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisRequest") proto.RegisterType((*QueryConsumerGenesisResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisResponse") @@ -1334,6 +1451,8 @@ func init() { proto.RegisterType((*QueryConsumerValidatorsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerValidatorsRequest") proto.RegisterType((*QueryConsumerValidatorsValidator)(nil), "interchain_security.ccv.provider.v1.QueryConsumerValidatorsValidator") proto.RegisterType((*QueryConsumerValidatorsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerValidatorsResponse") + proto.RegisterType((*QueryConsumerChainOptedInValidatorsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainOptedInValidatorsRequest") + proto.RegisterType((*QueryConsumerChainOptedInValidatorsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainOptedInValidatorsResponse") } func init() { @@ -1341,103 +1460,111 @@ func init() { } var fileDescriptor_422512d7b7586cd7 = []byte{ - // 1532 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xcf, 0x6f, 0xdc, 0x44, - 0x14, 0x8e, 0x93, 0x36, 0x24, 0x93, 0xfe, 0x62, 0x1a, 0xda, 0xd4, 0x09, 0xbb, 0xad, 0x2b, 0x20, - 0x6d, 0xc1, 0x4e, 0xb6, 0xaa, 0xe8, 0x0f, 0xd2, 0x74, 0x37, 0x9b, 0x96, 0x55, 0x5a, 0x35, 0xb8, - 0xa5, 0x48, 0x80, 0x70, 0x27, 0xf6, 0xb0, 0xb1, 0xea, 0xb5, 0xdd, 0x19, 0xef, 0xa6, 0xab, 0x8a, - 0x43, 0x39, 0x40, 0x8f, 0x95, 0x80, 0x7b, 0x2f, 0xfc, 0x03, 0x9c, 0x38, 0x72, 0xec, 0x8d, 0xa2, - 0x5e, 0x38, 0x15, 0x94, 0x72, 0x40, 0x1c, 0x10, 0xaa, 0xb8, 0x22, 0x21, 0x8f, 0xc7, 0x5e, 0x7b, - 0xd7, 0x9b, 0xf5, 0x6e, 0x72, 0xdb, 0x9d, 0x99, 0xf7, 0xbd, 0xf7, 0xbd, 0x79, 0xf3, 0xe6, 0x1b, - 0x03, 0xc5, 0xb4, 0x3d, 0x4c, 0xf4, 0x75, 0x64, 0xda, 0x1a, 0xc5, 0x7a, 0x9d, 0x98, 0x5e, 0x53, - 0xd1, 0xf5, 0x86, 0xe2, 0x12, 0xa7, 0x61, 0x1a, 0x98, 0x28, 0x8d, 0x79, 0xe5, 0x6e, 0x1d, 0x93, - 0xa6, 0xec, 0x12, 0xc7, 0x73, 0xe0, 0xf1, 0x14, 0x03, 0x59, 0xd7, 0x1b, 0x72, 0x68, 0x20, 0x37, - 0xe6, 0xc5, 0x99, 0xaa, 0xe3, 0x54, 0x2d, 0xac, 0x20, 0xd7, 0x54, 0x90, 0x6d, 0x3b, 0x1e, 0xf2, - 0x4c, 0xc7, 0xa6, 0x01, 0x84, 0x38, 0x59, 0x75, 0xaa, 0x0e, 0xfb, 0xa9, 0xf8, 0xbf, 0xf8, 0x68, - 0x9e, 0xdb, 0xb0, 0x7f, 0x6b, 0xf5, 0xcf, 0x15, 0xcf, 0xac, 0x61, 0xea, 0xa1, 0x9a, 0xcb, 0x17, - 0x14, 0xb2, 0x84, 0x1a, 0x45, 0x11, 0xd8, 0xcc, 0x75, 0xb3, 0x69, 0xcc, 0x2b, 0x74, 0x1d, 0x11, - 0x6c, 0x68, 0xba, 0x63, 0xd3, 0x7a, 0x2d, 0xb2, 0x78, 0x63, 0x0b, 0x8b, 0x0d, 0x93, 0x60, 0xbe, - 0x6c, 0xc6, 0xc3, 0xb6, 0x81, 0x49, 0xcd, 0xb4, 0x3d, 0x45, 0x27, 0x4d, 0xd7, 0x73, 0x94, 0x3b, - 0xb8, 0x19, 0x32, 0x3c, 0xa2, 0x3b, 0xb4, 0xe6, 0x50, 0x2d, 0x20, 0x19, 0xfc, 0x09, 0xa6, 0xa4, - 0xb3, 0x60, 0xfa, 0x03, 0x3f, 0x9d, 0x4b, 0xdc, 0xed, 0x15, 0x6c, 0x63, 0x6a, 0x52, 0x15, 0xdf, - 0xad, 0x63, 0xea, 0xc1, 0x23, 0x60, 0x2c, 0xf0, 0x6d, 0x1a, 0x53, 0xc2, 0x51, 0x61, 0x76, 0x5c, - 0x7d, 0x85, 0xfd, 0xaf, 0x18, 0xd2, 0x7d, 0x30, 0x93, 0x6e, 0x49, 0x5d, 0xc7, 0xa6, 0x18, 0x7e, - 0x02, 0xf6, 0x56, 0x83, 0x21, 0x8d, 0x7a, 0xc8, 0xc3, 0xcc, 0x7e, 0xa2, 0x30, 0x27, 0x77, 0xdb, - 0xb1, 0xc6, 0xbc, 0xdc, 0x86, 0x75, 0xc3, 0xb7, 0x2b, 0xed, 0x7a, 0xf2, 0x3c, 0x3f, 0xa4, 0xee, - 0xa9, 0xc6, 0xc6, 0xa4, 0x19, 0x20, 0x26, 0x9c, 0x2f, 0xf9, 0x70, 0x61, 0xd4, 0x12, 0x6a, 0x23, - 0x15, 0xce, 0xf2, 0xc8, 0x4a, 0x60, 0x94, 0xb9, 0xa7, 0x53, 0xc2, 0xd1, 0x91, 0xd9, 0x89, 0xc2, - 0x49, 0x39, 0x43, 0x11, 0xc9, 0x0c, 0x44, 0xe5, 0x96, 0xd2, 0x09, 0xf0, 0x56, 0xa7, 0x8b, 0x1b, - 0x1e, 0x22, 0xde, 0x2a, 0x71, 0x5c, 0x87, 0x22, 0x2b, 0x8a, 0xe6, 0xa1, 0x00, 0x66, 0x7b, 0xaf, - 0xe5, 0xb1, 0x7d, 0x0a, 0xc6, 0xdd, 0x70, 0x90, 0x67, 0xec, 0x62, 0xb6, 0xf0, 0x38, 0x78, 0xd1, - 0x30, 0x4c, 0xbf, 0xba, 0x5b, 0xd0, 0x2d, 0x40, 0x69, 0x16, 0xbc, 0x99, 0x16, 0x89, 0xe3, 0x76, - 0x04, 0xfd, 0x95, 0x90, 0x4e, 0x30, 0xb1, 0x34, 0xda, 0xe9, 0x8e, 0x98, 0x17, 0xfa, 0x8a, 0x59, - 0xc5, 0x35, 0xa7, 0x81, 0xac, 0xd4, 0x90, 0x17, 0xc1, 0x6e, 0xe6, 0x7a, 0x8b, 0x52, 0x84, 0xd3, - 0x60, 0x5c, 0xb7, 0x4c, 0x6c, 0x7b, 0xfe, 0xdc, 0x30, 0x9b, 0x1b, 0x0b, 0x06, 0x2a, 0x86, 0xf4, - 0xb5, 0x00, 0x8e, 0x31, 0x26, 0xb7, 0x90, 0x65, 0x1a, 0xc8, 0x73, 0x48, 0x2c, 0x55, 0xa4, 0x77, - 0xa1, 0xc3, 0x05, 0x70, 0x20, 0x0c, 0x5a, 0x43, 0x86, 0x41, 0x30, 0xa5, 0x81, 0x93, 0x12, 0x7c, - 0xf9, 0x3c, 0xbf, 0xaf, 0x89, 0x6a, 0xd6, 0x79, 0x89, 0x4f, 0x48, 0xea, 0xfe, 0x70, 0x6d, 0x31, - 0x18, 0x39, 0x3f, 0xf6, 0xf0, 0x71, 0x7e, 0xe8, 0xcf, 0xc7, 0xf9, 0x21, 0xe9, 0x3a, 0x90, 0xb6, - 0x0a, 0x84, 0x67, 0xf3, 0x04, 0x38, 0x10, 0xf6, 0x80, 0xc8, 0x5d, 0x10, 0xd1, 0x7e, 0x3d, 0xb6, - 0xde, 0x77, 0xd6, 0x49, 0x6d, 0x35, 0xe6, 0x3c, 0x1b, 0xb5, 0x0e, 0x5f, 0x5b, 0x50, 0x6b, 0xf3, - 0xbf, 0x15, 0xb5, 0x64, 0x20, 0x2d, 0x6a, 0x1d, 0x99, 0xe4, 0xd4, 0xda, 0xb2, 0x26, 0x4d, 0x83, - 0x23, 0x0c, 0xf0, 0xe6, 0x3a, 0x71, 0x3c, 0xcf, 0xc2, 0xec, 0xd8, 0x87, 0xc5, 0xf9, 0x8b, 0xc0, - 0x8f, 0x7f, 0xdb, 0x2c, 0x77, 0x93, 0x07, 0x13, 0xd4, 0x42, 0x74, 0x5d, 0xab, 0x61, 0x0f, 0x13, - 0xe6, 0x61, 0x44, 0x05, 0x6c, 0xe8, 0x9a, 0x3f, 0x02, 0x0b, 0xe0, 0xb5, 0xd8, 0x02, 0x0d, 0x59, - 0x96, 0xb3, 0x81, 0x6c, 0x1d, 0x33, 0xee, 0x23, 0xea, 0xc1, 0xd6, 0xd2, 0x62, 0x38, 0x05, 0x3f, - 0x03, 0x53, 0x36, 0xbe, 0xe7, 0x69, 0x04, 0xbb, 0x16, 0xb6, 0x4d, 0xba, 0xae, 0xe9, 0xc8, 0x36, - 0x7c, 0xb2, 0x78, 0x6a, 0x84, 0xd5, 0xbc, 0x28, 0x07, 0x57, 0x86, 0x1c, 0x5e, 0x19, 0xf2, 0xcd, - 0xf0, 0xca, 0x28, 0x8d, 0xf9, 0x3d, 0xec, 0xd1, 0x6f, 0x79, 0x41, 0x3d, 0xe4, 0xa3, 0xa8, 0x21, - 0xc8, 0x52, 0x88, 0x21, 0xbd, 0x0d, 0x4e, 0x32, 0x4a, 0x2a, 0xae, 0x9a, 0xd4, 0xc3, 0x04, 0x1b, - 0xad, 0xd3, 0xb1, 0x81, 0x88, 0x51, 0xc6, 0xb6, 0x53, 0x8b, 0x8e, 0xe7, 0x32, 0x38, 0x95, 0x69, - 0x35, 0xcf, 0xc8, 0x21, 0x30, 0x6a, 0xb0, 0x11, 0xd6, 0xf1, 0xc6, 0x55, 0xfe, 0x4f, 0xca, 0xf1, - 0x1e, 0x1e, 0x9c, 0x3c, 0x6c, 0xb0, 0x93, 0x56, 0x29, 0x47, 0x6e, 0x1e, 0x08, 0xe0, 0xf5, 0x2e, - 0x0b, 0x38, 0xf2, 0x6d, 0xb0, 0xcf, 0x8d, 0xcf, 0x85, 0x3d, 0xb5, 0x90, 0xa9, 0x01, 0x24, 0x60, - 0x79, 0xa3, 0x6f, 0xc3, 0x93, 0x2a, 0x60, 0x6f, 0x62, 0x19, 0x9c, 0x02, 0xbc, 0x7e, 0xcb, 0xc9, - 0x72, 0x2e, 0xc3, 0x1c, 0x00, 0x61, 0xe3, 0xa8, 0x94, 0xd9, 0x66, 0xee, 0x52, 0x63, 0x23, 0xd2, - 0x55, 0xa0, 0x30, 0x36, 0x45, 0xcb, 0x5a, 0x45, 0x26, 0xa1, 0xb7, 0x90, 0xb5, 0xe4, 0xd8, 0x7e, - 0xc9, 0x95, 0x92, 0x7d, 0xae, 0x52, 0xce, 0x70, 0x01, 0x7e, 0x2f, 0x80, 0xb9, 0xec, 0x70, 0x3c, - 0x5f, 0x77, 0xc1, 0xab, 0x2e, 0x32, 0x89, 0xd6, 0x40, 0x96, 0x7f, 0xd5, 0xb3, 0x63, 0xc0, 0x53, - 0x76, 0x39, 0x5b, 0xca, 0x90, 0x49, 0x5a, 0x8e, 0xa2, 0x63, 0x66, 0xb7, 0x0a, 0x60, 0x9f, 0x9b, - 0x58, 0x22, 0xfd, 0x2b, 0x80, 0x63, 0x3d, 0xad, 0xe0, 0xe5, 0x6e, 0x67, 0xb3, 0x34, 0xfd, 0xf2, - 0x79, 0xfe, 0x70, 0xd0, 0x0a, 0xda, 0x57, 0x74, 0xb6, 0x3b, 0x1f, 0xa7, 0x4b, 0x4b, 0x89, 0xe1, - 0xb4, 0xaf, 0xe8, 0xec, 0x2d, 0x70, 0x11, 0xec, 0x89, 0x56, 0xdd, 0xc1, 0x4d, 0x7e, 0xc6, 0x66, - 0xe4, 0x96, 0xd0, 0x91, 0x03, 0xa1, 0x23, 0xaf, 0xd6, 0xd7, 0x2c, 0x53, 0x5f, 0xc1, 0x4d, 0x75, - 0x22, 0xb4, 0x58, 0xc1, 0x4d, 0x69, 0x12, 0xc0, 0xa0, 0x74, 0x11, 0x41, 0xad, 0x83, 0x73, 0x1b, - 0x1c, 0x4c, 0x8c, 0xf2, 0x6d, 0xa9, 0x80, 0x51, 0x97, 0x8d, 0xf0, 0xfb, 0xeb, 0x54, 0xc6, 0xbd, - 0xf0, 0x4d, 0x78, 0xdd, 0x72, 0x00, 0xe9, 0x02, 0xc8, 0x25, 0x2e, 0xce, 0xa8, 0x25, 0x66, 0x11, - 0x55, 0x3f, 0x0a, 0xe0, 0x68, 0x17, 0xeb, 0xe8, 0x57, 0xea, 0x85, 0x24, 0x64, 0xbe, 0x90, 0x3a, - 0x32, 0x3b, 0xdc, 0x67, 0x66, 0xe1, 0x24, 0xd8, 0xed, 0x3a, 0x1b, 0x98, 0xb0, 0x3d, 0x19, 0x51, - 0x83, 0x3f, 0xbe, 0xcc, 0xc9, 0x77, 0x25, 0xce, 0xd3, 0x8c, 0x01, 0x68, 0x44, 0xa3, 0xbc, 0xec, - 0x97, 0x33, 0xa5, 0xba, 0x57, 0x52, 0xd4, 0x18, 0x70, 0xe1, 0xa7, 0x43, 0x60, 0x37, 0x33, 0x80, - 0x9b, 0x02, 0x98, 0x4c, 0x53, 0xa9, 0xf0, 0x52, 0xff, 0x5e, 0x93, 0xd2, 0x58, 0x2c, 0x6e, 0x03, - 0x21, 0x48, 0x87, 0xb4, 0xfc, 0xe5, 0xb3, 0x3f, 0xbe, 0x19, 0x5e, 0x84, 0x0b, 0xbd, 0x9f, 0x3d, - 0xd1, 0x8e, 0x71, 0x19, 0xac, 0xdc, 0x0f, 0x4b, 0xe8, 0x0b, 0xf8, 0x4c, 0xe0, 0x45, 0x9d, 0xd4, - 0xbb, 0x70, 0xb1, 0xff, 0x08, 0x13, 0x3a, 0x5a, 0xbc, 0x34, 0x38, 0x00, 0x67, 0x78, 0x8e, 0x31, - 0x3c, 0x0d, 0xe7, 0xfb, 0x60, 0x18, 0x28, 0x6c, 0xf8, 0x60, 0x18, 0x4c, 0x75, 0x91, 0xcd, 0x14, - 0x5e, 0x1d, 0x30, 0xb2, 0x54, 0x85, 0x2e, 0x5e, 0xdb, 0x21, 0x34, 0x4e, 0xfa, 0x7d, 0x46, 0xba, - 0x04, 0x2f, 0xf5, 0x4b, 0xda, 0x7f, 0x28, 0x11, 0x4f, 0x8b, 0xc4, 0x2f, 0xfc, 0x4f, 0x00, 0x87, - 0xd3, 0x55, 0x38, 0x85, 0x2b, 0x03, 0x07, 0xdd, 0x29, 0xf7, 0xc5, 0xab, 0x3b, 0x03, 0xc6, 0x13, - 0x70, 0x85, 0x25, 0xa0, 0x08, 0x17, 0x07, 0x48, 0x80, 0xe3, 0xc6, 0xf8, 0xff, 0x13, 0x0a, 0xbd, - 0x54, 0xc9, 0x0c, 0x2f, 0x67, 0x8f, 0x7a, 0x2b, 0xf1, 0x2f, 0x5e, 0xd9, 0x36, 0x0e, 0x27, 0x5e, - 0x64, 0xc4, 0x2f, 0xc0, 0x73, 0x19, 0xbe, 0x63, 0x84, 0x40, 0x5a, 0xe2, 0x32, 0x4c, 0xa1, 0x1c, - 0x97, 0xd2, 0x03, 0x51, 0x4e, 0x79, 0x14, 0x0c, 0x44, 0x39, 0x4d, 0xd3, 0x0f, 0x46, 0x39, 0x71, - 0x7d, 0xc1, 0x9f, 0x05, 0x7e, 0x55, 0x27, 0xe4, 0x3c, 0xbc, 0x98, 0x3d, 0xc4, 0xb4, 0x57, 0x82, - 0xb8, 0x38, 0xb0, 0x3d, 0xa7, 0x76, 0x96, 0x51, 0x2b, 0xc0, 0xb9, 0xde, 0xd4, 0x3c, 0x0e, 0x10, - 0x7c, 0xea, 0x80, 0xdf, 0x0d, 0x83, 0xe3, 0x19, 0xf4, 0x39, 0xbc, 0x9e, 0x3d, 0xc4, 0x4c, 0xef, - 0x02, 0x71, 0x75, 0xe7, 0x00, 0x79, 0x12, 0x56, 0x58, 0x12, 0x96, 0xe1, 0x52, 0xef, 0x24, 0x90, - 0x08, 0xb1, 0x55, 0xd3, 0x84, 0x61, 0x6a, 0xc1, 0x7b, 0x03, 0xfe, 0xd5, 0xf1, 0x9e, 0x48, 0xca, - 0x64, 0x0a, 0xfb, 0xb8, 0x55, 0xbb, 0x3c, 0x5a, 0xc4, 0xd2, 0x76, 0x20, 0x38, 0xeb, 0x12, 0x63, - 0xfd, 0x1e, 0x3c, 0xdf, 0x9b, 0x75, 0xf8, 0x5c, 0xd1, 0xda, 0x2f, 0xb0, 0x6f, 0x87, 0xf9, 0x77, - 0x9f, 0x0c, 0xef, 0x03, 0x78, 0x33, 0x7b, 0xd0, 0xd9, 0x5f, 0x2f, 0xe2, 0x87, 0x3b, 0x8c, 0xca, - 0xb3, 0x73, 0x81, 0x65, 0xe7, 0x0c, 0x3c, 0xdd, 0x77, 0x7f, 0x37, 0x0d, 0xf8, 0x83, 0x00, 0x26, - 0x62, 0x12, 0x1c, 0xbe, 0xdb, 0xc7, 0x76, 0xc5, 0xa5, 0xbc, 0x78, 0xb6, 0x7f, 0x43, 0x1e, 0xff, - 0x1c, 0x8b, 0xff, 0x24, 0x9c, 0xcd, 0xb0, 0xbb, 0x41, 0x90, 0x7f, 0xb7, 0x5f, 0xc4, 0x2d, 0x09, - 0x0a, 0x97, 0xb6, 0x23, 0x60, 0x43, 0x32, 0xe5, 0xed, 0x81, 0x6c, 0x43, 0x79, 0xb4, 0x74, 0x73, - 0x4c, 0x53, 0x96, 0x3e, 0x7a, 0xb2, 0x99, 0x13, 0x9e, 0x6e, 0xe6, 0x84, 0xdf, 0x37, 0x73, 0xc2, - 0xa3, 0x17, 0xb9, 0xa1, 0xa7, 0x2f, 0x72, 0x43, 0xbf, 0xbe, 0xc8, 0x0d, 0x7d, 0xbc, 0x50, 0x35, - 0xbd, 0xf5, 0xfa, 0x9a, 0xac, 0x3b, 0x35, 0xfe, 0x29, 0x39, 0xe6, 0xec, 0x9d, 0xc8, 0x59, 0xe3, - 0x8c, 0x72, 0xaf, 0xad, 0x47, 0x36, 0x5d, 0x4c, 0xd7, 0x46, 0xd9, 0xd7, 0x91, 0xd3, 0xff, 0x07, - 0x00, 0x00, 0xff, 0xff, 0x50, 0x0b, 0x43, 0xa2, 0xea, 0x17, 0x00, 0x00, + // 1653 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0x4d, 0x6f, 0xdc, 0xc4, + 0x1b, 0x8f, 0xf3, 0xf6, 0x4f, 0x26, 0x6d, 0xda, 0xff, 0x34, 0xb4, 0xe9, 0x26, 0xdd, 0x4d, 0x5d, + 0x01, 0x69, 0x0a, 0x76, 0xb2, 0x55, 0x45, 0x5f, 0x48, 0xd3, 0x6c, 0x92, 0x86, 0x55, 0xfa, 0x12, + 0xdc, 0x50, 0x24, 0x40, 0xb8, 0x8e, 0x3d, 0x6c, 0xac, 0x7a, 0x3d, 0xce, 0x78, 0xb2, 0xe9, 0xaa, + 0x42, 0xa2, 0x1c, 0xa0, 0xc7, 0x8a, 0x97, 0x7b, 0x2f, 0x7c, 0x01, 0x4e, 0x7c, 0x84, 0xde, 0x28, + 0xaa, 0x90, 0x38, 0x15, 0x94, 0x72, 0x40, 0x1c, 0x10, 0xaa, 0xb8, 0x22, 0x21, 0x8f, 0xc7, 0x5e, + 0x7b, 0xd7, 0x9b, 0xf5, 0x6e, 0x72, 0x8b, 0x67, 0x9e, 0xe7, 0xf7, 0x3c, 0xbf, 0x67, 0x66, 0x9e, + 0x97, 0x0d, 0x90, 0x4d, 0x9b, 0x22, 0xa2, 0x6f, 0x68, 0xa6, 0xad, 0xba, 0x48, 0xdf, 0x22, 0x26, + 0xad, 0xca, 0xba, 0x5e, 0x91, 0x1d, 0x82, 0x2b, 0xa6, 0x81, 0x88, 0x5c, 0x99, 0x91, 0x37, 0xb7, + 0x10, 0xa9, 0x4a, 0x0e, 0xc1, 0x14, 0xc3, 0x53, 0x09, 0x0a, 0x92, 0xae, 0x57, 0xa4, 0x40, 0x41, + 0xaa, 0xcc, 0x64, 0xc6, 0x4b, 0x18, 0x97, 0x2c, 0x24, 0x6b, 0x8e, 0x29, 0x6b, 0xb6, 0x8d, 0xa9, + 0x46, 0x4d, 0x6c, 0xbb, 0x3e, 0x44, 0x66, 0xa4, 0x84, 0x4b, 0x98, 0xfd, 0x29, 0x7b, 0x7f, 0xf1, + 0xd5, 0x1c, 0xd7, 0x61, 0x5f, 0xeb, 0x5b, 0x9f, 0xc8, 0xd4, 0x2c, 0x23, 0x97, 0x6a, 0x65, 0x87, + 0x0b, 0xe4, 0xd3, 0xb8, 0x1a, 0x7a, 0xe1, 0xeb, 0x4c, 0x37, 0xd3, 0xa9, 0xcc, 0xc8, 0xee, 0x86, + 0x46, 0x90, 0xa1, 0xea, 0xd8, 0x76, 0xb7, 0xca, 0xa1, 0xc6, 0xab, 0xbb, 0x68, 0x6c, 0x9b, 0x04, + 0x71, 0xb1, 0x71, 0x8a, 0x6c, 0x03, 0x91, 0xb2, 0x69, 0x53, 0x59, 0x27, 0x55, 0x87, 0x62, 0xf9, + 0x2e, 0xaa, 0x06, 0x0c, 0x8f, 0xeb, 0xd8, 0x2d, 0x63, 0x57, 0xf5, 0x49, 0xfa, 0x1f, 0xfe, 0x96, + 0x78, 0x1e, 0x8c, 0xbd, 0xeb, 0x85, 0x73, 0x81, 0x9b, 0x5d, 0x46, 0x36, 0x72, 0x4d, 0x57, 0x41, + 0x9b, 0x5b, 0xc8, 0xa5, 0xf0, 0x38, 0x18, 0xf0, 0x6d, 0x9b, 0xc6, 0xa8, 0x30, 0x21, 0x4c, 0x0e, + 0x2a, 0xff, 0x63, 0xdf, 0x45, 0x43, 0xbc, 0x0f, 0xc6, 0x93, 0x35, 0x5d, 0x07, 0xdb, 0x2e, 0x82, + 0x1f, 0x82, 0x83, 0x25, 0x7f, 0x49, 0x75, 0xa9, 0x46, 0x11, 0xd3, 0x1f, 0xca, 0x4f, 0x4b, 0xcd, + 0x4e, 0xac, 0x32, 0x23, 0xd5, 0x61, 0xdd, 0xf2, 0xf4, 0x0a, 0xbd, 0x4f, 0x9e, 0xe7, 0xba, 0x94, + 0x03, 0xa5, 0xc8, 0x9a, 0x38, 0x0e, 0x32, 0x31, 0xe3, 0x0b, 0x1e, 0x5c, 0xe0, 0xb5, 0xa8, 0xd5, + 0x91, 0x0a, 0x76, 0xb9, 0x67, 0x05, 0xd0, 0xcf, 0xcc, 0xbb, 0xa3, 0xc2, 0x44, 0xcf, 0xe4, 0x50, + 0x7e, 0x4a, 0x4a, 0x71, 0x89, 0x24, 0x06, 0xa2, 0x70, 0x4d, 0xf1, 0x34, 0x78, 0xbd, 0xd1, 0xc4, + 0x2d, 0xaa, 0x11, 0xba, 0x4a, 0xb0, 0x83, 0x5d, 0xcd, 0x0a, 0xbd, 0x79, 0x28, 0x80, 0xc9, 0xd6, + 0xb2, 0xdc, 0xb7, 0x8f, 0xc0, 0xa0, 0x13, 0x2c, 0xf2, 0x88, 0x5d, 0x4e, 0xe7, 0x1e, 0x07, 0x9f, + 0x37, 0x0c, 0xd3, 0xbb, 0xdd, 0x35, 0xe8, 0x1a, 0xa0, 0x38, 0x09, 0x5e, 0x4b, 0xf2, 0x04, 0x3b, + 0x0d, 0x4e, 0x7f, 0x21, 0x24, 0x13, 0x8c, 0x89, 0x86, 0x27, 0xdd, 0xe0, 0xf3, 0x6c, 0x5b, 0x3e, + 0x2b, 0xa8, 0x8c, 0x2b, 0x9a, 0x95, 0xe8, 0xf2, 0x67, 0x02, 0xe8, 0x63, 0xb6, 0x77, 0xb9, 0x8b, + 0x70, 0x0c, 0x0c, 0xea, 0x96, 0x89, 0x6c, 0xea, 0xed, 0x75, 0xb3, 0xbd, 0x01, 0x7f, 0xa1, 0x68, + 0xc0, 0x23, 0xa0, 0x8f, 0x62, 0x47, 0xbd, 0x31, 0xda, 0x33, 0x21, 0x4c, 0x1e, 0x54, 0x7a, 0x29, + 0x76, 0x6e, 0xc0, 0x29, 0x00, 0xcb, 0xa6, 0xad, 0x3a, 0x78, 0x1b, 0x11, 0xd5, 0xb4, 0x55, 0x5f, + 0xa2, 0x77, 0x42, 0x98, 0xec, 0x51, 0x86, 0xcb, 0xa6, 0xbd, 0xea, 0x6d, 0x14, 0xed, 0x35, 0xec, + 0xdc, 0x10, 0xbf, 0x14, 0xc0, 0x49, 0x16, 0x8b, 0xdb, 0x9a, 0x65, 0x1a, 0x1a, 0xc5, 0x24, 0x12, + 0x6c, 0xd2, 0xfa, 0xa9, 0xc0, 0x59, 0x70, 0x38, 0xa0, 0xad, 0x6a, 0x86, 0x41, 0x90, 0xeb, 0xfa, + 0x5e, 0x16, 0xe0, 0xcb, 0xe7, 0xb9, 0xe1, 0xaa, 0x56, 0xb6, 0x2e, 0x8a, 0x7c, 0x43, 0x54, 0x0e, + 0x05, 0xb2, 0xf3, 0xfe, 0xca, 0xc5, 0x81, 0x87, 0x8f, 0x73, 0x5d, 0x7f, 0x3c, 0xce, 0x75, 0x89, + 0x37, 0x81, 0xb8, 0x9b, 0x23, 0xfc, 0x3c, 0x4e, 0x83, 0xc3, 0x41, 0x16, 0x09, 0xcd, 0xf9, 0x1e, + 0x1d, 0xd2, 0x23, 0xf2, 0x9e, 0xb1, 0x46, 0x6a, 0xab, 0x11, 0xe3, 0xe9, 0xa8, 0x35, 0xd8, 0xda, + 0x85, 0x5a, 0x9d, 0xfd, 0xdd, 0xa8, 0xc5, 0x1d, 0xa9, 0x51, 0x6b, 0x88, 0x24, 0xa7, 0x56, 0x17, + 0x35, 0x71, 0x0c, 0x1c, 0x67, 0x80, 0x6b, 0x1b, 0x04, 0x53, 0x6a, 0x21, 0x96, 0x38, 0x82, 0xeb, + 0xfd, 0x93, 0xc0, 0x13, 0x48, 0xdd, 0x2e, 0x37, 0x93, 0x03, 0x43, 0xae, 0xa5, 0xb9, 0x1b, 0x6a, + 0x19, 0x51, 0x44, 0x98, 0x85, 0x1e, 0x05, 0xb0, 0xa5, 0xeb, 0xde, 0x0a, 0xcc, 0x83, 0x57, 0x22, + 0x02, 0xaa, 0x66, 0x59, 0x78, 0x5b, 0xb3, 0x75, 0xc4, 0xb8, 0xf7, 0x28, 0x47, 0x6a, 0xa2, 0xf3, + 0xc1, 0x16, 0xfc, 0x18, 0x8c, 0xda, 0xe8, 0x1e, 0x55, 0x09, 0x72, 0x2c, 0x64, 0x9b, 0xee, 0x86, + 0xaa, 0x6b, 0xb6, 0xe1, 0x91, 0x45, 0xec, 0x6a, 0x0e, 0xe5, 0x33, 0x92, 0x5f, 0x74, 0xa4, 0xa0, + 0xe8, 0x48, 0x6b, 0x41, 0xd1, 0x29, 0x0c, 0x78, 0x59, 0xf0, 0xd1, 0xaf, 0x39, 0x41, 0x39, 0xea, + 0xa1, 0x28, 0x01, 0xc8, 0x42, 0x80, 0x21, 0xbe, 0x01, 0xa6, 0x18, 0x25, 0x05, 0x95, 0x4c, 0x97, + 0x22, 0x82, 0x8c, 0xda, 0xfb, 0xda, 0xd6, 0x88, 0xb1, 0x88, 0x6c, 0x5c, 0x0e, 0x1f, 0xf8, 0x12, + 0x38, 0x93, 0x4a, 0x9a, 0x47, 0xe4, 0x28, 0xe8, 0x37, 0xd8, 0x0a, 0xcb, 0x99, 0x83, 0x0a, 0xff, + 0x12, 0xb3, 0xbc, 0x0a, 0xf8, 0x6f, 0x17, 0x19, 0xec, 0xa9, 0x16, 0x17, 0x43, 0x33, 0x0f, 0x04, + 0x70, 0xa2, 0x89, 0x00, 0x47, 0xbe, 0x03, 0x86, 0x9d, 0xe8, 0x5e, 0x90, 0x95, 0xf3, 0xa9, 0x52, + 0x48, 0x0c, 0x96, 0x97, 0x8a, 0x3a, 0x3c, 0xb1, 0x08, 0x0e, 0xc6, 0xc4, 0xe0, 0x28, 0xe0, 0xf7, + 0x77, 0x31, 0x7e, 0x9d, 0x17, 0x61, 0x16, 0x80, 0x20, 0xf5, 0x14, 0x17, 0xd9, 0x61, 0xf6, 0x2a, + 0x91, 0x15, 0xf1, 0x1a, 0x90, 0x19, 0x9b, 0x79, 0xcb, 0x5a, 0xd5, 0x4c, 0xe2, 0xde, 0xd6, 0xac, + 0x05, 0x6c, 0x7b, 0x57, 0xae, 0x10, 0xcf, 0x94, 0xc5, 0xc5, 0x14, 0x25, 0xf4, 0x3b, 0x01, 0x4c, + 0xa7, 0x87, 0xe3, 0xf1, 0xda, 0x04, 0xff, 0x77, 0x34, 0x93, 0xa8, 0x15, 0xcd, 0xf2, 0x9a, 0x05, + 0xf6, 0x0c, 0x78, 0xc8, 0xae, 0xa6, 0x0b, 0x99, 0x66, 0x92, 0x9a, 0xa1, 0xf0, 0x99, 0xd9, 0xb5, + 0x0b, 0x30, 0xec, 0xc4, 0x44, 0xc4, 0x7f, 0x04, 0x70, 0xb2, 0xa5, 0x16, 0xbc, 0xda, 0xec, 0x6d, + 0x16, 0xc6, 0x5e, 0x3e, 0xcf, 0x1d, 0xf3, 0x53, 0x41, 0xbd, 0x44, 0x63, 0xba, 0xf3, 0x70, 0x9a, + 0xa4, 0x94, 0x08, 0x4e, 0xbd, 0x44, 0x63, 0x6e, 0x81, 0x73, 0xe0, 0x40, 0x28, 0x75, 0x17, 0x55, + 0xf9, 0x1b, 0x1b, 0x97, 0x6a, 0xad, 0x92, 0xe4, 0xb7, 0x4a, 0xd2, 0xea, 0xd6, 0xba, 0x65, 0xea, + 0x2b, 0xa8, 0xaa, 0x0c, 0x05, 0x1a, 0x2b, 0xa8, 0x2a, 0x8e, 0x00, 0xe8, 0x5f, 0x5d, 0x8d, 0x68, + 0xb5, 0x87, 0x73, 0x07, 0x1c, 0x89, 0xad, 0xf2, 0x63, 0x29, 0x82, 0x7e, 0x87, 0xad, 0xf0, 0x0a, + 0x78, 0x26, 0xe5, 0x59, 0x78, 0x2a, 0xfc, 0xde, 0x72, 0x00, 0xf1, 0x12, 0xc8, 0xc6, 0x4a, 0x6f, + 0x98, 0x12, 0xd3, 0xb4, 0x65, 0x3f, 0x08, 0x60, 0xa2, 0x89, 0x76, 0xf8, 0x57, 0x62, 0x41, 0x12, + 0x52, 0x17, 0xa4, 0x86, 0xc8, 0x76, 0xb7, 0x19, 0x59, 0x38, 0x02, 0xfa, 0x58, 0xe5, 0x65, 0x67, + 0xd2, 0xa3, 0xf8, 0x1f, 0x5e, 0xa3, 0x94, 0x6b, 0x4a, 0x9c, 0x87, 0x19, 0x01, 0x50, 0x09, 0x57, + 0xf9, 0xb5, 0x5f, 0x4a, 0x15, 0xea, 0x56, 0x41, 0x51, 0x22, 0xc0, 0xe2, 0x32, 0xcf, 0xa5, 0xb1, + 0x47, 0x78, 0xd3, 0xa1, 0xc8, 0x28, 0xda, 0x6d, 0x1d, 0xc7, 0x26, 0x4f, 0xb3, 0xad, 0x80, 0xc2, + 0xd6, 0xf4, 0x44, 0xcd, 0x0b, 0xb5, 0xfe, 0x8c, 0x50, 0x90, 0x7d, 0xc7, 0x6a, 0x42, 0xab, 0xf1, + 0xb3, 0x41, 0x6e, 0xfe, 0xe7, 0x51, 0xd0, 0xc7, 0x6c, 0xc2, 0x1d, 0x01, 0x8c, 0x24, 0xf5, 0xe8, + 0xf0, 0x4a, 0xfb, 0x11, 0x8b, 0x0f, 0x06, 0x99, 0xf9, 0x3d, 0x20, 0xf8, 0x5c, 0xc5, 0xa5, 0xcf, + 0x9f, 0xfd, 0xfe, 0x75, 0xf7, 0x1c, 0x9c, 0x6d, 0x3d, 0xf4, 0x85, 0xb7, 0x8d, 0x0f, 0x01, 0xf2, + 0xfd, 0x20, 0xde, 0x9f, 0xc2, 0x67, 0x02, 0x7f, 0x90, 0xf1, 0x6e, 0x1f, 0xce, 0xb5, 0xef, 0x61, + 0x6c, 0x8a, 0xc8, 0x5c, 0xe9, 0x1c, 0x80, 0x33, 0xbc, 0xc0, 0x18, 0x9e, 0x85, 0x33, 0x6d, 0x30, + 0xf4, 0xe7, 0x0b, 0xf8, 0xa0, 0x1b, 0x8c, 0x36, 0x19, 0x1a, 0x5c, 0x78, 0xad, 0x43, 0xcf, 0x12, + 0xe7, 0x93, 0xcc, 0xf5, 0x7d, 0x42, 0xe3, 0xa4, 0xdf, 0x61, 0xa4, 0x0b, 0xf0, 0x4a, 0xbb, 0xa4, + 0xbd, 0x31, 0x91, 0x50, 0x35, 0x6c, 0xfd, 0xe1, 0xbf, 0x02, 0x38, 0x96, 0x3c, 0x83, 0xb8, 0x70, + 0xa5, 0x63, 0xa7, 0x1b, 0x87, 0x9d, 0xcc, 0xb5, 0xfd, 0x01, 0xe3, 0x01, 0x58, 0x66, 0x01, 0x98, + 0x87, 0x73, 0x1d, 0x04, 0x00, 0x3b, 0x11, 0xfe, 0x7f, 0x07, 0x4d, 0x6a, 0x62, 0xbb, 0x0f, 0xaf, + 0xa6, 0xf7, 0x7a, 0xb7, 0xc1, 0x25, 0xb3, 0xbc, 0x67, 0x1c, 0x4e, 0x7c, 0x9e, 0x11, 0xbf, 0x04, + 0x2f, 0xa4, 0xf8, 0x15, 0x27, 0x00, 0x52, 0x63, 0x85, 0x3c, 0x81, 0x72, 0x34, 0xbf, 0x75, 0x44, + 0x39, 0x61, 0xa0, 0xe9, 0x88, 0x72, 0xd2, 0x3c, 0xd2, 0x19, 0xe5, 0x58, 0x5a, 0x87, 0x3f, 0x0a, + 0xbc, 0xcd, 0x88, 0x8d, 0x22, 0xf0, 0x72, 0x7a, 0x17, 0x93, 0x26, 0x9c, 0xcc, 0x5c, 0xc7, 0xfa, + 0x9c, 0xda, 0x79, 0x46, 0x2d, 0x0f, 0xa7, 0x5b, 0x53, 0xa3, 0x1c, 0xc0, 0xff, 0xa1, 0x07, 0x7e, + 0xdb, 0x0d, 0x4e, 0xa5, 0x98, 0x2d, 0xe0, 0xcd, 0xf4, 0x2e, 0xa6, 0x9a, 0x69, 0x32, 0xab, 0xfb, + 0x07, 0xc8, 0x83, 0xb0, 0xc2, 0x82, 0xb0, 0x04, 0x17, 0x5a, 0x07, 0x81, 0x84, 0x88, 0xb5, 0x3b, + 0x4d, 0x18, 0xa6, 0xea, 0xcf, 0x4a, 0xf0, 0xcf, 0x86, 0x59, 0x28, 0xde, 0xe2, 0xbb, 0xb0, 0x8d, + 0xaa, 0xda, 0x64, 0xe0, 0xca, 0x14, 0xf6, 0x02, 0xc1, 0x59, 0x17, 0x18, 0xeb, 0xb7, 0xe1, 0xc5, + 0xd6, 0xac, 0x83, 0x51, 0x4b, 0xad, 0x2f, 0x60, 0xdf, 0x74, 0xf3, 0x5f, 0xbd, 0x52, 0xcc, 0x36, + 0x70, 0x2d, 0xbd, 0xd3, 0xe9, 0x27, 0xaf, 0xcc, 0x7b, 0xfb, 0x8c, 0xca, 0xa3, 0x73, 0x89, 0x45, + 0xe7, 0x1c, 0x3c, 0xdb, 0x76, 0x7e, 0x37, 0x0d, 0xf8, 0xbd, 0x00, 0x86, 0x22, 0xe3, 0x03, 0x7c, + 0xab, 0x8d, 0xe3, 0x8a, 0x8e, 0x21, 0x99, 0xf3, 0xed, 0x2b, 0x72, 0xff, 0xa7, 0x99, 0xff, 0x53, + 0x70, 0x32, 0xc5, 0xe9, 0xfa, 0x4e, 0xfe, 0x55, 0x5f, 0x88, 0x6b, 0x9d, 0x2b, 0x5c, 0xd8, 0x4b, + 0xf3, 0x1d, 0x90, 0x59, 0xdc, 0x1b, 0xc8, 0x1e, 0x3a, 0x8f, 0x5a, 0x23, 0x1d, 0xed, 0x29, 0xbf, + 0x0a, 0x32, 0xd8, 0xee, 0x6d, 0x7b, 0x3b, 0x19, 0x2c, 0xd5, 0x24, 0xd1, 0x4e, 0x06, 0x4b, 0x37, + 0x51, 0xb4, 0x13, 0x14, 0xec, 0x81, 0xa8, 0xa6, 0x9d, 0x1c, 0x94, 0xc2, 0xfb, 0x4f, 0x76, 0xb2, + 0xc2, 0xd3, 0x9d, 0xac, 0xf0, 0xdb, 0x4e, 0x56, 0x78, 0xf4, 0x22, 0xdb, 0xf5, 0xf4, 0x45, 0xb6, + 0xeb, 0x97, 0x17, 0xd9, 0xae, 0x0f, 0x66, 0x4b, 0x26, 0xdd, 0xd8, 0x5a, 0x97, 0x74, 0x5c, 0xe6, + 0xff, 0x5d, 0x88, 0x18, 0x7b, 0x33, 0x34, 0x56, 0x39, 0x27, 0xdf, 0xab, 0x2b, 0x1c, 0x55, 0x07, + 0xb9, 0xeb, 0xfd, 0xec, 0xe7, 0xae, 0xb3, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x2a, 0x41, 0xde, + 0xa3, 0xfd, 0x19, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1487,6 +1614,9 @@ type QueryClient interface { // chain is using this validator set at this exact moment because a VSCPacket // could be delayed to be delivered on the consumer chain. QueryConsumerValidators(ctx context.Context, in *QueryConsumerValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerValidatorsResponse, error) + // QueryConsumerChainOptedInValidators returns all opted-in validators for a + // given consumer chain + QueryConsumerChainOptedInValidators(ctx context.Context, in *QueryConsumerChainOptedInValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerChainOptedInValidatorsResponse, error) } type queryClient struct { @@ -1605,6 +1735,15 @@ func (c *queryClient) QueryConsumerValidators(ctx context.Context, in *QueryCons return out, nil } +func (c *queryClient) QueryConsumerChainOptedInValidators(ctx context.Context, in *QueryConsumerChainOptedInValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerChainOptedInValidatorsResponse, error) { + out := new(QueryConsumerChainOptedInValidatorsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainOptedInValidators", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // ConsumerGenesis queries the genesis state needed to start a consumer chain @@ -1642,6 +1781,9 @@ type QueryServer interface { // chain is using this validator set at this exact moment because a VSCPacket // could be delayed to be delivered on the consumer chain. QueryConsumerValidators(context.Context, *QueryConsumerValidatorsRequest) (*QueryConsumerValidatorsResponse, error) + // QueryConsumerChainOptedInValidators returns all opted-in validators for a + // given consumer chain + QueryConsumerChainOptedInValidators(context.Context, *QueryConsumerChainOptedInValidatorsRequest) (*QueryConsumerChainOptedInValidatorsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -1684,6 +1826,9 @@ func (*UnimplementedQueryServer) QueryParams(ctx context.Context, req *QueryPara func (*UnimplementedQueryServer) QueryConsumerValidators(ctx context.Context, req *QueryConsumerValidatorsRequest) (*QueryConsumerValidatorsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerValidators not implemented") } +func (*UnimplementedQueryServer) QueryConsumerChainOptedInValidators(ctx context.Context, req *QueryConsumerChainOptedInValidatorsRequest) (*QueryConsumerChainOptedInValidatorsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChainOptedInValidators not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -1905,6 +2050,24 @@ func _Query_QueryConsumerValidators_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _Query_QueryConsumerChainOptedInValidators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerChainOptedInValidatorsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryConsumerChainOptedInValidators(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainOptedInValidators", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerChainOptedInValidators(ctx, req.(*QueryConsumerChainOptedInValidatorsRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.provider.v1.Query", HandlerType: (*QueryServer)(nil), @@ -1957,6 +2120,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryConsumerValidators", Handler: _Query_QueryConsumerValidators_Handler, }, + { + MethodName: "QueryConsumerChainOptedInValidators", + Handler: _Query_QueryConsumerChainOptedInValidators_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/query.proto", @@ -2221,6 +2388,16 @@ func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MinPowerInTop_N != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.MinPowerInTop_N)) + i-- + dAtA[i] = 0x20 + } + if m.Top_N != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x18 + } if len(m.ClientId) > 0 { i -= len(m.ClientId) copy(dAtA[i:], m.ClientId) @@ -2872,6 +3049,68 @@ func (m *QueryConsumerValidatorsResponse) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *QueryConsumerChainOptedInValidatorsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainOptedInValidatorsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainOptedInValidatorsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorsProviderAddresses) > 0 { + for iNdEx := len(m.ValidatorsProviderAddresses) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ValidatorsProviderAddresses[iNdEx]) + copy(dAtA[i:], m.ValidatorsProviderAddresses[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorsProviderAddresses[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2989,6 +3228,12 @@ func (m *Chain) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + if m.Top_N != 0 { + n += 1 + sovQuery(uint64(m.Top_N)) + } + if m.MinPowerInTop_N != 0 { + n += 1 + sovQuery(uint64(m.MinPowerInTop_N)) + } return n } @@ -3259,6 +3504,34 @@ func (m *QueryConsumerValidatorsResponse) Size() (n int) { return n } +func (m *QueryConsumerChainOptedInValidatorsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ValidatorsProviderAddresses) > 0 { + for _, s := range m.ValidatorsProviderAddresses { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3929,6 +4202,44 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } m.ClientId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinPowerInTop_N", wireType) + } + m.MinPowerInTop_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinPowerInTop_N |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -5632,6 +5943,170 @@ func (m *QueryConsumerValidatorsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryConsumerChainOptedInValidatorsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", 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.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerChainOptedInValidatorsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsProviderAddresses", 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.ValidatorsProviderAddresses = append(m.ValidatorsProviderAddresses, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ccv/provider/types/query.pb.gw.go b/x/ccv/provider/types/query.pb.gw.go index 5f6bc49b10..5bd5aa2c75 100644 --- a/x/ccv/provider/types/query.pb.gw.go +++ b/x/ccv/provider/types/query.pb.gw.go @@ -375,6 +375,60 @@ func local_request_Query_QueryConsumerValidators_0(ctx context.Context, marshale } +func request_Query_QueryConsumerChainOptedInValidators_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerChainOptedInValidatorsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := client.QueryConsumerChainOptedInValidators(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryConsumerChainOptedInValidators_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerChainOptedInValidatorsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := server.QueryConsumerChainOptedInValidators(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -657,6 +711,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_QueryConsumerChainOptedInValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QueryConsumerChainOptedInValidators_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerChainOptedInValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -938,6 +1015,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_QueryConsumerChainOptedInValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryConsumerChainOptedInValidators_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerChainOptedInValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -965,6 +1062,8 @@ var ( pattern_Query_QueryParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "params"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_QueryConsumerValidators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "consumer_validators", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryConsumerChainOptedInValidators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "opted_in_validators", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -991,4 +1090,6 @@ var ( forward_Query_QueryParams_0 = runtime.ForwardResponseMessage forward_Query_QueryConsumerValidators_0 = runtime.ForwardResponseMessage + + forward_Query_QueryConsumerChainOptedInValidators_0 = runtime.ForwardResponseMessage ) diff --git a/x/ccv/provider/types/tx.pb.go b/x/ccv/provider/types/tx.pb.go index 19a1916184..db2ca17860 100644 --- a/x/ccv/provider/types/tx.pb.go +++ b/x/ccv/provider/types/tx.pb.go @@ -427,8 +427,34 @@ type MsgConsumerAddition struct { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintan the existing ibc transfer channel DistributionTransmissionChannel string `protobuf:"bytes,12,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,13,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,14,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,15,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + Allowlist []string `protobuf:"bytes,16,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,17,rep,name=denylist,proto3" json:"denylist,omitempty"` // signer address - Authority string `protobuf:"bytes,13,opt,name=authority,proto3" json:"authority,omitempty"` + Authority string `protobuf:"bytes,18,opt,name=authority,proto3" json:"authority,omitempty"` } func (m *MsgConsumerAddition) Reset() { *m = MsgConsumerAddition{} } @@ -548,6 +574,41 @@ func (m *MsgConsumerAddition) GetDistributionTransmissionChannel() string { return "" } +func (m *MsgConsumerAddition) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *MsgConsumerAddition) GetValidatorsPowerCap() uint32 { + if m != nil { + return m.ValidatorsPowerCap + } + return 0 +} + +func (m *MsgConsumerAddition) GetValidatorSetCap() uint32 { + if m != nil { + return m.ValidatorSetCap + } + return 0 +} + +func (m *MsgConsumerAddition) GetAllowlist() []string { + if m != nil { + return m.Allowlist + } + return nil +} + +func (m *MsgConsumerAddition) GetDenylist() []string { + if m != nil { + return m.Denylist + } + return nil +} + func (m *MsgConsumerAddition) GetAuthority() string { if m != nil { return m.Authority @@ -808,6 +869,169 @@ func (m *MsgChangeRewardDenomsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgChangeRewardDenomsResponse proto.InternalMessageInfo +type MsgOptIn struct { + // the chain id of the consumer chain to opt in to + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // the validator address on the provider + ProviderAddr string `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty" yaml:"address"` + // (optional) The consensus public key to use on the consumer in json string + // format corresponding to proto-any, for example + // `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`. + // This field is optional and can remain empty (i.e., `consumer_key = ""`). A + // validator can always change the consumer public key at a later stage by + // issuing a `MsgAssignConsumerKey` message. + ConsumerKey string `protobuf:"bytes,3,opt,name=consumer_key,json=consumerKey,proto3" json:"consumer_key,omitempty"` + // signer address + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` +} + +func (m *MsgOptIn) Reset() { *m = MsgOptIn{} } +func (m *MsgOptIn) String() string { return proto.CompactTextString(m) } +func (*MsgOptIn) ProtoMessage() {} +func (*MsgOptIn) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{14} +} +func (m *MsgOptIn) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptIn) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptIn.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptIn) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptIn.Merge(m, src) +} +func (m *MsgOptIn) XXX_Size() int { + return m.Size() +} +func (m *MsgOptIn) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptIn.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptIn proto.InternalMessageInfo + +type MsgOptInResponse struct { +} + +func (m *MsgOptInResponse) Reset() { *m = MsgOptInResponse{} } +func (m *MsgOptInResponse) String() string { return proto.CompactTextString(m) } +func (*MsgOptInResponse) ProtoMessage() {} +func (*MsgOptInResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{15} +} +func (m *MsgOptInResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptInResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptInResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptInResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptInResponse.Merge(m, src) +} +func (m *MsgOptInResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgOptInResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptInResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptInResponse proto.InternalMessageInfo + +type MsgOptOut struct { + // the chain id of the consumer chain to opt out from + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // the validator address on the provider + ProviderAddr string `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty" yaml:"address"` + // signer address + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` +} + +func (m *MsgOptOut) Reset() { *m = MsgOptOut{} } +func (m *MsgOptOut) String() string { return proto.CompactTextString(m) } +func (*MsgOptOut) ProtoMessage() {} +func (*MsgOptOut) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{16} +} +func (m *MsgOptOut) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptOut) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptOut.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptOut) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptOut.Merge(m, src) +} +func (m *MsgOptOut) XXX_Size() int { + return m.Size() +} +func (m *MsgOptOut) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptOut.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptOut proto.InternalMessageInfo + +type MsgOptOutResponse struct { +} + +func (m *MsgOptOutResponse) Reset() { *m = MsgOptOutResponse{} } +func (m *MsgOptOutResponse) String() string { return proto.CompactTextString(m) } +func (*MsgOptOutResponse) ProtoMessage() {} +func (*MsgOptOutResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{17} +} +func (m *MsgOptOutResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptOutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptOutResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptOutResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptOutResponse.Merge(m, src) +} +func (m *MsgOptOutResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgOptOutResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptOutResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptOutResponse proto.InternalMessageInfo + // MsgConsumerModification message contains a governance proposal on the // provider chain to modify a running consumer chain. If it passes, the consumer // chain's parameters are updated. @@ -821,15 +1045,41 @@ type MsgConsumerModification struct { Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // the chain-id of the consumer chain to be modified ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain + // under the Top N case. For example, 53 corresponds to a Top 53% chain, + // meaning that the top 53% provider validators by voting power have to + // validate the proposed consumer chain. top_N can either be 0 or any value in + // [50, 100]. A chain can join with top_N == 0 as an Opt In chain, or with + // top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,4,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on + // the consumer chain. For instance, if `validators_power_cap` is set to 32, + // it means that no validator can have more than 32% of the voting power on + // the consumer chain. Note that this might not be feasible. For example, + // think of a consumer chain with only 5 validators and with + // `validators_power_cap` set to 10%. In such a scenario, at least one + // validator would need to have more than 20% of the total voting power. + // Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,5,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a + // consumer chain. Only applicable to Opt In chains. Setting + // `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,6,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // are the ONLY ones that can validate the consumer chain. + Allowlist []string `protobuf:"bytes,7,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that + // CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,8,rep,name=denylist,proto3" json:"denylist,omitempty"` // signer address - Authority string `protobuf:"bytes,4,opt,name=authority,proto3" json:"authority,omitempty"` + Authority string `protobuf:"bytes,9,opt,name=authority,proto3" json:"authority,omitempty"` } func (m *MsgConsumerModification) Reset() { *m = MsgConsumerModification{} } func (m *MsgConsumerModification) String() string { return proto.CompactTextString(m) } func (*MsgConsumerModification) ProtoMessage() {} func (*MsgConsumerModification) Descriptor() ([]byte, []int) { - return fileDescriptor_43221a4391e9fbf4, []int{14} + return fileDescriptor_43221a4391e9fbf4, []int{18} } func (m *MsgConsumerModification) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -879,6 +1129,41 @@ func (m *MsgConsumerModification) GetChainId() string { return "" } +func (m *MsgConsumerModification) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *MsgConsumerModification) GetValidatorsPowerCap() uint32 { + if m != nil { + return m.ValidatorsPowerCap + } + return 0 +} + +func (m *MsgConsumerModification) GetValidatorSetCap() uint32 { + if m != nil { + return m.ValidatorSetCap + } + return 0 +} + +func (m *MsgConsumerModification) GetAllowlist() []string { + if m != nil { + return m.Allowlist + } + return nil +} + +func (m *MsgConsumerModification) GetDenylist() []string { + if m != nil { + return m.Denylist + } + return nil +} + func (m *MsgConsumerModification) GetAuthority() string { if m != nil { return m.Authority @@ -893,7 +1178,7 @@ func (m *MsgConsumerModificationResponse) Reset() { *m = MsgConsumerModi func (m *MsgConsumerModificationResponse) String() string { return proto.CompactTextString(m) } func (*MsgConsumerModificationResponse) ProtoMessage() {} func (*MsgConsumerModificationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_43221a4391e9fbf4, []int{15} + return fileDescriptor_43221a4391e9fbf4, []int{19} } func (m *MsgConsumerModificationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -937,6 +1222,10 @@ func init() { proto.RegisterType((*MsgConsumerRemovalResponse)(nil), "interchain_security.ccv.provider.v1.MsgConsumerRemovalResponse") proto.RegisterType((*MsgChangeRewardDenoms)(nil), "interchain_security.ccv.provider.v1.MsgChangeRewardDenoms") proto.RegisterType((*MsgChangeRewardDenomsResponse)(nil), "interchain_security.ccv.provider.v1.MsgChangeRewardDenomsResponse") + proto.RegisterType((*MsgOptIn)(nil), "interchain_security.ccv.provider.v1.MsgOptIn") + proto.RegisterType((*MsgOptInResponse)(nil), "interchain_security.ccv.provider.v1.MsgOptInResponse") + proto.RegisterType((*MsgOptOut)(nil), "interchain_security.ccv.provider.v1.MsgOptOut") + proto.RegisterType((*MsgOptOutResponse)(nil), "interchain_security.ccv.provider.v1.MsgOptOutResponse") proto.RegisterType((*MsgConsumerModification)(nil), "interchain_security.ccv.provider.v1.MsgConsumerModification") proto.RegisterType((*MsgConsumerModificationResponse)(nil), "interchain_security.ccv.provider.v1.MsgConsumerModificationResponse") } @@ -946,94 +1235,106 @@ func init() { } var fileDescriptor_43221a4391e9fbf4 = []byte{ - // 1384 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0x26, 0x69, 0x9a, 0x8c, 0x93, 0x34, 0xdd, 0x26, 0xdf, 0x38, 0xfe, 0xb6, 0x76, 0x62, - 0x7e, 0xb4, 0x2a, 0xed, 0x2e, 0x0d, 0x3f, 0x0a, 0x51, 0x11, 0x38, 0x4d, 0xa1, 0x2d, 0x0a, 0x84, - 0x6d, 0x28, 0x12, 0x48, 0xac, 0xc6, 0xbb, 0x93, 0xf5, 0xa8, 0xde, 0x19, 0x6b, 0x66, 0xec, 0xd6, - 0x37, 0xd4, 0x13, 0x12, 0x12, 0x2a, 0x37, 0xc4, 0xa9, 0x07, 0x8e, 0x20, 0xf5, 0xd0, 0x13, 0x17, - 0xc4, 0xad, 0xc7, 0x0a, 0x71, 0xe0, 0x54, 0xaa, 0xe6, 0x50, 0xce, 0xfc, 0x05, 0x68, 0x7e, 0xec, - 0x7a, 0x9d, 0x38, 0xa9, 0xe3, 0x72, 0xb1, 0x3c, 0xf3, 0x3e, 0xef, 0xf3, 0x3e, 0xef, 0xcd, 0xbc, - 0x99, 0x59, 0x70, 0x06, 0x13, 0x81, 0x58, 0x50, 0x83, 0x98, 0xf8, 0x1c, 0x05, 0x4d, 0x86, 0x45, - 0xdb, 0x0d, 0x82, 0x96, 0xdb, 0x60, 0xb4, 0x85, 0x43, 0xc4, 0xdc, 0xd6, 0x39, 0x57, 0xdc, 0x72, - 0x1a, 0x8c, 0x0a, 0x6a, 0xbf, 0xd0, 0x03, 0xed, 0x04, 0x41, 0xcb, 0x49, 0xd0, 0x4e, 0xeb, 0x5c, - 0xe1, 0x28, 0x8c, 0x31, 0xa1, 0xae, 0xfa, 0xd5, 0x7e, 0x85, 0xe3, 0x11, 0xa5, 0x51, 0x1d, 0xb9, - 0xb0, 0x81, 0x5d, 0x48, 0x08, 0x15, 0x50, 0x60, 0x4a, 0xb8, 0xb1, 0x96, 0x8c, 0x55, 0x8d, 0xaa, - 0xcd, 0x2d, 0x57, 0xe0, 0x18, 0x71, 0x01, 0xe3, 0x86, 0x01, 0x14, 0x77, 0x02, 0xc2, 0x26, 0x53, - 0x0c, 0xc6, 0xbe, 0xb0, 0xd3, 0x0e, 0x49, 0xdb, 0x98, 0x66, 0x23, 0x1a, 0x51, 0xf5, 0xd7, 0x95, - 0xff, 0x12, 0x87, 0x80, 0xf2, 0x98, 0x72, 0x5f, 0x1b, 0xf4, 0xc0, 0x98, 0xe6, 0xf5, 0xc8, 0x8d, - 0x79, 0x24, 0x53, 0x8f, 0x79, 0x94, 0xa8, 0xc4, 0xd5, 0xc0, 0x0d, 0x28, 0x43, 0x6e, 0x50, 0xc7, - 0x88, 0x08, 0x69, 0xd5, 0xff, 0x0c, 0x60, 0xb9, 0x9f, 0x52, 0xa6, 0x85, 0xd2, 0x3e, 0xae, 0x24, - 0xad, 0xe3, 0xa8, 0x26, 0x34, 0x15, 0x77, 0x05, 0x22, 0x21, 0x62, 0x31, 0xd6, 0x01, 0x3a, 0xa3, - 0x44, 0x45, 0xc6, 0x2e, 0xda, 0x0d, 0xc4, 0x5d, 0x24, 0xf9, 0x48, 0x80, 0x34, 0xa0, 0xfc, 0x87, - 0x05, 0x66, 0xd7, 0x79, 0x54, 0xe1, 0x1c, 0x47, 0xe4, 0x22, 0x25, 0xbc, 0x19, 0x23, 0xf6, 0x21, - 0x6a, 0xdb, 0x0b, 0x60, 0x5c, 0x6b, 0xc3, 0x61, 0xde, 0x5a, 0xb4, 0x4e, 0x4d, 0x78, 0x87, 0xd5, - 0xf8, 0x4a, 0x68, 0x9f, 0x07, 0x53, 0x89, 0x2e, 0x1f, 0x86, 0x21, 0xcb, 0x0f, 0x4b, 0xfb, 0xaa, - 0xfd, 0xcf, 0xa3, 0xd2, 0x74, 0x1b, 0xc6, 0xf5, 0x95, 0xb2, 0x9c, 0x45, 0x9c, 0x97, 0xbd, 0xc9, - 0x04, 0x58, 0x09, 0x43, 0x66, 0x2f, 0x81, 0xc9, 0xc0, 0x84, 0xf0, 0x6f, 0xa0, 0x76, 0x7e, 0x44, - 0xf1, 0xe6, 0x82, 0x4c, 0xd8, 0x57, 0xc1, 0x98, 0x54, 0x82, 0x58, 0x7e, 0x54, 0x91, 0xe6, 0x7f, - 0xbf, 0x7f, 0x76, 0xd6, 0x54, 0xbc, 0xa2, 0x59, 0xaf, 0x09, 0x86, 0x49, 0xe4, 0x19, 0xdc, 0xca, - 0xb1, 0xaf, 0xef, 0x96, 0x86, 0xfe, 0xbe, 0x5b, 0x1a, 0xba, 0xfd, 0xf4, 0xde, 0x69, 0x33, 0x59, - 0x2e, 0x82, 0xe3, 0xbd, 0xb2, 0xf2, 0x10, 0x6f, 0x50, 0xc2, 0x51, 0xf9, 0x37, 0x0b, 0x9c, 0x58, - 0xe7, 0xd1, 0xb5, 0x66, 0x35, 0xc6, 0x22, 0x01, 0xac, 0x63, 0x5e, 0x45, 0x35, 0xd8, 0xc2, 0xb4, - 0xc9, 0xec, 0x37, 0xc1, 0x04, 0x57, 0x56, 0x81, 0x98, 0x2e, 0xc0, 0x3e, 0x5a, 0x3a, 0x50, 0x7b, - 0x03, 0x4c, 0xc6, 0x19, 0x1e, 0x55, 0x9b, 0xdc, 0xf2, 0x19, 0x07, 0x57, 0x03, 0x27, 0xbb, 0x72, - 0x4e, 0x66, 0xad, 0x5a, 0xe7, 0x9c, 0x6c, 0x6c, 0xaf, 0x8b, 0x61, 0xe5, 0x7f, 0xd9, 0x04, 0x3b, - 0x91, 0xca, 0x27, 0xc1, 0x4b, 0xfb, 0xa6, 0x90, 0x26, 0x7b, 0x6f, 0xb8, 0x47, 0xb2, 0x6b, 0xb4, - 0x59, 0xad, 0xa3, 0xeb, 0x54, 0x60, 0x12, 0x0d, 0x9c, 0xac, 0x0f, 0xe6, 0xc3, 0x66, 0xa3, 0x8e, - 0x03, 0x28, 0x90, 0xdf, 0xa2, 0x02, 0xf9, 0xc9, 0xf6, 0x32, 0x79, 0x9f, 0xcc, 0xa6, 0xa9, 0x36, - 0xa0, 0xb3, 0x96, 0x38, 0x5c, 0xa7, 0x02, 0x5d, 0x32, 0x70, 0x6f, 0x2e, 0xec, 0x35, 0x6d, 0x7f, - 0x09, 0xe6, 0x31, 0xd9, 0x62, 0x30, 0x90, 0xed, 0xeb, 0x57, 0xeb, 0x34, 0xb8, 0xe1, 0xd7, 0x10, - 0x0c, 0x11, 0x53, 0x9b, 0x27, 0xb7, 0xfc, 0xf2, 0xb3, 0x0a, 0x7b, 0x59, 0xa1, 0xbd, 0xb9, 0x0e, - 0xcd, 0xaa, 0x64, 0xd1, 0xd3, 0x07, 0xaa, 0x6d, 0xb6, 0x62, 0x69, 0x6d, 0x7f, 0xb4, 0xc0, 0x91, - 0x75, 0x1e, 0x7d, 0xda, 0x08, 0xa1, 0x40, 0x1b, 0x90, 0xc1, 0x98, 0xcb, 0x6a, 0xc2, 0xa6, 0xa8, - 0x51, 0xd9, 0xd1, 0xcf, 0xae, 0x66, 0x0a, 0xb5, 0xaf, 0x80, 0xb1, 0x86, 0x62, 0x30, 0xc5, 0x7b, - 0xc5, 0xe9, 0xe3, 0xfc, 0x74, 0x74, 0xd0, 0xd5, 0xd1, 0x07, 0x8f, 0x4a, 0x43, 0x9e, 0x21, 0x58, - 0x99, 0x56, 0xf9, 0xa4, 0xd4, 0xe5, 0x05, 0x30, 0xbf, 0x43, 0x65, 0x9a, 0xc1, 0xe3, 0x31, 0x70, - 0x6c, 0x9d, 0x47, 0x49, 0x96, 0x95, 0x30, 0xc4, 0xb2, 0x4a, 0xfb, 0x1d, 0x00, 0x1f, 0x80, 0x69, - 0x4c, 0xb0, 0xc0, 0xb0, 0xee, 0xd7, 0x90, 0x2c, 0xbd, 0x11, 0x5c, 0x50, 0x8b, 0x21, 0x0f, 0x3d, - 0xc7, 0x1c, 0x75, 0x6a, 0x01, 0x24, 0xc2, 0xe8, 0x9b, 0x32, 0x7e, 0x7a, 0x52, 0x1e, 0x08, 0x11, - 0x22, 0x88, 0x63, 0xee, 0xd7, 0x20, 0xaf, 0xa9, 0x35, 0x9d, 0xf4, 0x72, 0x66, 0xee, 0x32, 0xe4, - 0x35, 0xbb, 0x04, 0x72, 0x55, 0x4c, 0x20, 0x6b, 0x6b, 0xc4, 0xa8, 0x42, 0x00, 0x3d, 0xa5, 0x00, - 0x17, 0x01, 0xe0, 0x0d, 0x78, 0x93, 0xf8, 0xf2, 0x1a, 0xc8, 0x1f, 0x32, 0x42, 0xf4, 0x11, 0xef, - 0x24, 0x47, 0xbc, 0xb3, 0x99, 0xdc, 0x11, 0xab, 0xe3, 0x52, 0xc8, 0x9d, 0xbf, 0x4a, 0x96, 0x37, - 0xa1, 0xfc, 0xa4, 0xc5, 0xfe, 0x08, 0xcc, 0x34, 0x49, 0x95, 0x92, 0x10, 0x93, 0xc8, 0x6f, 0x20, - 0x86, 0x69, 0x98, 0x1f, 0x53, 0x54, 0x0b, 0xbb, 0xa8, 0xd6, 0xcc, 0x6d, 0xa2, 0x99, 0xbe, 0x97, - 0x4c, 0x47, 0x52, 0xe7, 0x0d, 0xe5, 0x6b, 0x7f, 0x02, 0xec, 0x20, 0x68, 0x29, 0x49, 0xb4, 0x29, - 0x12, 0xc6, 0xc3, 0xfd, 0x33, 0xce, 0x04, 0x41, 0x6b, 0x53, 0x7b, 0x1b, 0xca, 0x2f, 0xc0, 0xbc, - 0x60, 0x90, 0xf0, 0x2d, 0xc4, 0x76, 0xf2, 0x8e, 0xf7, 0xcf, 0x3b, 0x97, 0x70, 0x74, 0x93, 0x5f, - 0x06, 0x8b, 0xe9, 0xc9, 0xcc, 0x50, 0x88, 0xb9, 0x60, 0xb8, 0xda, 0x54, 0x4d, 0x97, 0xb4, 0x4d, - 0x7e, 0x42, 0x6d, 0x82, 0x62, 0x82, 0xf3, 0xba, 0x60, 0xef, 0x1b, 0x94, 0xfd, 0x31, 0x78, 0x51, - 0xb5, 0x29, 0x97, 0xe2, 0xfc, 0x2e, 0x26, 0x15, 0x3a, 0xc6, 0x9c, 0x4b, 0x36, 0xb0, 0x68, 0x9d, - 0x1a, 0xf1, 0x96, 0x34, 0x76, 0x03, 0xb1, 0xb5, 0x0c, 0x72, 0x33, 0x03, 0xb4, 0xcf, 0x02, 0xbb, - 0x86, 0xb9, 0xa0, 0x0c, 0x07, 0xb0, 0xee, 0x23, 0x22, 0x18, 0x46, 0x3c, 0x9f, 0x53, 0xee, 0x47, - 0x3b, 0x96, 0x4b, 0xda, 0x60, 0x5f, 0x05, 0x4b, 0x7b, 0x06, 0xf5, 0x83, 0x1a, 0x24, 0x04, 0xd5, - 0xf3, 0x93, 0x2a, 0x95, 0x52, 0xb8, 0x47, 0xcc, 0x8b, 0x1a, 0xd6, 0xdd, 0xc8, 0x53, 0x7d, 0x37, - 0xf2, 0xae, 0xee, 0x3b, 0x01, 0xfe, 0xdf, 0xa3, 0xc3, 0xd2, 0x0e, 0xfc, 0xc5, 0x02, 0x76, 0xc6, - 0xee, 0xa1, 0x98, 0xb6, 0x60, 0x7d, 0xbf, 0x06, 0xac, 0x80, 0x09, 0x2e, 0x68, 0x43, 0x6f, 0xf9, - 0xe1, 0x03, 0x6c, 0xf9, 0x71, 0xe9, 0xa6, 0x76, 0x7c, 0x57, 0x6e, 0x23, 0x83, 0xe7, 0x76, 0x1c, - 0x14, 0x76, 0x6b, 0x4f, 0x53, 0xfb, 0xd9, 0x02, 0x73, 0xd2, 0x5c, 0x83, 0x24, 0x42, 0x1e, 0xba, - 0x09, 0x59, 0xb8, 0x86, 0x08, 0x8d, 0xb9, 0x5d, 0x06, 0x53, 0xa1, 0xfa, 0xe7, 0x0b, 0x2a, 0x5f, - 0x11, 0x79, 0x6b, 0x71, 0x44, 0x3e, 0x06, 0xf4, 0xe4, 0x26, 0xad, 0x84, 0xa1, 0x7d, 0x0a, 0xcc, - 0x74, 0x30, 0x4c, 0x52, 0xcb, 0x6c, 0x25, 0x6c, 0x3a, 0x81, 0xa9, 0x80, 0xff, 0x5d, 0x36, 0x25, - 0x75, 0x53, 0xee, 0x96, 0x9b, 0x26, 0x74, 0xdf, 0x52, 0x27, 0x69, 0x7a, 0xdf, 0xd2, 0x10, 0x6f, - 0xc9, 0x6b, 0x4b, 0xee, 0xd4, 0x59, 0x70, 0x48, 0x60, 0x51, 0x47, 0x66, 0xb5, 0xf4, 0xc0, 0x5e, - 0x04, 0xb9, 0x10, 0xf1, 0x80, 0xe1, 0x86, 0xea, 0xa2, 0x61, 0xfd, 0xe6, 0xc9, 0x4c, 0x75, 0x2d, - 0xf4, 0x48, 0xf7, 0x42, 0x77, 0xe5, 0x35, 0x3a, 0x78, 0x5e, 0x4b, 0xa0, 0xb4, 0x87, 0xea, 0x24, - 0xb3, 0xe5, 0x5f, 0xc7, 0xc1, 0xc8, 0x3a, 0x8f, 0xec, 0xef, 0x2c, 0x70, 0x74, 0xf7, 0x73, 0xf0, - 0xed, 0xbe, 0xee, 0xa2, 0x5e, 0x6f, 0xae, 0x42, 0x65, 0x60, 0xd7, 0x44, 0x9b, 0xfd, 0x93, 0x05, - 0x0a, 0xfb, 0xbc, 0xd5, 0x56, 0xfb, 0x8d, 0xb0, 0x37, 0x47, 0xe1, 0xea, 0xf3, 0x73, 0xec, 0x23, - 0xb7, 0xeb, 0xb5, 0x35, 0xa0, 0xdc, 0x2c, 0xc7, 0xa0, 0x72, 0x7b, 0xbd, 0x61, 0xec, 0x6f, 0x2d, - 0x30, 0xb3, 0xeb, 0xfa, 0x7f, 0xab, 0xdf, 0x00, 0x3b, 0x3d, 0x0b, 0xef, 0x0d, 0xea, 0x99, 0x0a, - 0xfa, 0xc6, 0x02, 0x47, 0x76, 0x9e, 0x86, 0xe7, 0x0f, 0xca, 0x6a, 0x1c, 0x0b, 0xef, 0x0e, 0xe8, - 0x98, 0xaa, 0xb9, 0x6d, 0x81, 0xc9, 0xae, 0xf7, 0xdd, 0xeb, 0xfd, 0x32, 0x66, 0xbd, 0x0a, 0x17, - 0x06, 0xf1, 0x4a, 0x45, 0xfc, 0x60, 0x81, 0xd9, 0x9e, 0x87, 0xce, 0x85, 0x83, 0xa6, 0x97, 0xf5, - 0x2e, 0xac, 0x3d, 0x8f, 0x77, 0x22, 0xae, 0x70, 0xe8, 0xab, 0xa7, 0xf7, 0x4e, 0x5b, 0xab, 0x9f, - 0x3d, 0x78, 0x52, 0xb4, 0x1e, 0x3e, 0x29, 0x5a, 0x8f, 0x9f, 0x14, 0xad, 0x3b, 0xdb, 0xc5, 0xa1, - 0x87, 0xdb, 0xc5, 0xa1, 0x3f, 0xb7, 0x8b, 0x43, 0x9f, 0xbf, 0x13, 0x61, 0x51, 0x6b, 0x56, 0x9d, - 0x80, 0xc6, 0xe6, 0xf3, 0xd9, 0xed, 0xc4, 0x3d, 0x9b, 0x7e, 0xfd, 0xb6, 0xde, 0x70, 0x6f, 0x75, - 0x7f, 0x02, 0xab, 0x4f, 0x86, 0xea, 0x98, 0xba, 0xd3, 0x5e, 0xfb, 0x37, 0x00, 0x00, 0xff, 0xff, - 0xa3, 0x6c, 0x64, 0x1a, 0x7e, 0x10, 0x00, 0x00, + // 1580 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcd, 0x6f, 0xdb, 0x46, + 0x16, 0x37, 0xfd, 0x15, 0x69, 0xe4, 0x4f, 0xda, 0x5e, 0xcb, 0x5a, 0x47, 0xb2, 0xb5, 0x1f, 0x31, + 0xb2, 0x31, 0x99, 0x78, 0x37, 0xc9, 0xae, 0x91, 0x45, 0xeb, 0x8f, 0xb4, 0x49, 0x0a, 0xc7, 0x2e, + 0xe3, 0xa6, 0x40, 0x0b, 0x94, 0x18, 0x91, 0x63, 0x6a, 0x10, 0x92, 0x43, 0xcc, 0x8c, 0xe4, 0xe8, + 0x56, 0xe4, 0x54, 0xa0, 0x68, 0x91, 0xde, 0x8a, 0x9e, 0x72, 0x28, 0x7a, 0x6a, 0x81, 0x1c, 0x7a, + 0xea, 0xad, 0xb7, 0x1c, 0x83, 0xa2, 0x87, 0x9e, 0xd2, 0x36, 0x39, 0xa4, 0xe7, 0xfe, 0x05, 0xc5, + 0x0c, 0x3f, 0x44, 0xd9, 0xb2, 0x22, 0x29, 0xed, 0xa1, 0x17, 0x41, 0x33, 0xef, 0xf7, 0x7e, 0xef, + 0xf7, 0xde, 0x70, 0xde, 0x0c, 0x09, 0xce, 0x61, 0x9f, 0x23, 0x6a, 0x55, 0x21, 0xf6, 0x4d, 0x86, + 0xac, 0x1a, 0xc5, 0xbc, 0xa1, 0x5b, 0x56, 0x5d, 0x0f, 0x28, 0xa9, 0x63, 0x1b, 0x51, 0xbd, 0x7e, + 0x41, 0xe7, 0x77, 0xb5, 0x80, 0x12, 0x4e, 0xd4, 0xbf, 0xb5, 0x41, 0x6b, 0x96, 0x55, 0xd7, 0x62, + 0xb4, 0x56, 0xbf, 0x50, 0x98, 0x86, 0x1e, 0xf6, 0x89, 0x2e, 0x7f, 0x43, 0xbf, 0xc2, 0xa2, 0x43, + 0x88, 0xe3, 0x22, 0x1d, 0x06, 0x58, 0x87, 0xbe, 0x4f, 0x38, 0xe4, 0x98, 0xf8, 0x2c, 0xb2, 0x96, + 0x22, 0xab, 0x1c, 0x55, 0x6a, 0x07, 0x3a, 0xc7, 0x1e, 0x62, 0x1c, 0x7a, 0x41, 0x04, 0x28, 0x1e, + 0x05, 0xd8, 0x35, 0x2a, 0x19, 0x22, 0xfb, 0xc2, 0x51, 0x3b, 0xf4, 0x1b, 0x91, 0x69, 0xd6, 0x21, + 0x0e, 0x91, 0x7f, 0x75, 0xf1, 0x2f, 0x76, 0xb0, 0x08, 0xf3, 0x08, 0x33, 0x43, 0x43, 0x38, 0x88, + 0x4c, 0xf3, 0xe1, 0x48, 0xf7, 0x98, 0x23, 0x52, 0xf7, 0x98, 0x13, 0xab, 0xc4, 0x15, 0x4b, 0xb7, + 0x08, 0x45, 0xba, 0xe5, 0x62, 0xe4, 0x73, 0x61, 0x0d, 0xff, 0x45, 0x80, 0xb5, 0x6e, 0x4a, 0x99, + 0x14, 0x2a, 0xf4, 0xd1, 0x05, 0xa9, 0x8b, 0x9d, 0x2a, 0x0f, 0xa9, 0x98, 0xce, 0x91, 0x6f, 0x23, + 0xea, 0xe1, 0x30, 0x40, 0x73, 0x14, 0xab, 0x48, 0xd9, 0x79, 0x23, 0x40, 0x4c, 0x47, 0x82, 0xcf, + 0xb7, 0x50, 0x08, 0x28, 0x7f, 0xaf, 0x80, 0xd9, 0x1d, 0xe6, 0x6c, 0x30, 0x86, 0x1d, 0x7f, 0x8b, + 0xf8, 0xac, 0xe6, 0x21, 0xfa, 0x06, 0x6a, 0xa8, 0x0b, 0x20, 0x13, 0x6a, 0xc3, 0x76, 0x5e, 0x59, + 0x52, 0x56, 0xb2, 0xc6, 0x29, 0x39, 0xbe, 0x6e, 0xab, 0x97, 0xc1, 0x78, 0xac, 0xcb, 0x84, 0xb6, + 0x4d, 0xf3, 0x83, 0xc2, 0xbe, 0xa9, 0xfe, 0xfa, 0xa4, 0x34, 0xd1, 0x80, 0x9e, 0xbb, 0x5e, 0x16, + 0xb3, 0x88, 0xb1, 0xb2, 0x31, 0x16, 0x03, 0x37, 0x6c, 0x9b, 0xaa, 0xcb, 0x60, 0xcc, 0x8a, 0x42, + 0x98, 0x77, 0x50, 0x23, 0x3f, 0x24, 0x79, 0x73, 0x56, 0x2a, 0xec, 0x79, 0x30, 0x2a, 0x94, 0x20, + 0x9a, 0x1f, 0x96, 0xa4, 0xf9, 0xef, 0xbe, 0x5e, 0x9d, 0x8d, 0x2a, 0xbe, 0x11, 0xb2, 0xde, 0xe2, + 0x14, 0xfb, 0x8e, 0x11, 0xe1, 0xd6, 0x67, 0x3e, 0x78, 0x50, 0x1a, 0xf8, 0xe5, 0x41, 0x69, 0xe0, + 0xde, 0xf3, 0x87, 0x67, 0xa3, 0xc9, 0x72, 0x11, 0x2c, 0xb6, 0xcb, 0xca, 0x40, 0x2c, 0x20, 0x3e, + 0x43, 0xe5, 0x6f, 0x15, 0x70, 0x7a, 0x87, 0x39, 0xb7, 0x6a, 0x15, 0x0f, 0xf3, 0x18, 0xb0, 0x83, + 0x59, 0x05, 0x55, 0x61, 0x1d, 0x93, 0x1a, 0x55, 0x2f, 0x81, 0x2c, 0x93, 0x56, 0x8e, 0x68, 0x58, + 0x80, 0x0e, 0x5a, 0x9a, 0x50, 0x75, 0x0f, 0x8c, 0x79, 0x29, 0x1e, 0x59, 0x9b, 0xdc, 0xda, 0x39, + 0x0d, 0x57, 0x2c, 0x2d, 0xbd, 0x72, 0x5a, 0x6a, 0xad, 0xea, 0x17, 0xb4, 0x74, 0x6c, 0xa3, 0x85, + 0x61, 0xfd, 0x2f, 0xe9, 0x04, 0x9b, 0x91, 0xca, 0x67, 0xc0, 0x3f, 0x3a, 0xa6, 0x90, 0x24, 0xfb, + 0x70, 0xb0, 0x4d, 0xb2, 0xdb, 0xa4, 0x56, 0x71, 0xd1, 0x6d, 0xc2, 0xb1, 0xef, 0xf4, 0x9d, 0xac, + 0x09, 0xe6, 0xed, 0x5a, 0xe0, 0x62, 0x0b, 0x72, 0x64, 0xd6, 0x09, 0x47, 0x66, 0xfc, 0x78, 0x45, + 0x79, 0x9f, 0x49, 0xa7, 0x29, 0x1f, 0x40, 0x6d, 0x3b, 0x76, 0xb8, 0x4d, 0x38, 0xba, 0x1a, 0xc1, + 0x8d, 0x39, 0xbb, 0xdd, 0xb4, 0xfa, 0x1e, 0x98, 0xc7, 0xfe, 0x01, 0x85, 0x96, 0xd8, 0xbe, 0x66, + 0xc5, 0x25, 0xd6, 0x1d, 0xb3, 0x8a, 0xa0, 0x8d, 0xa8, 0x7c, 0x78, 0x72, 0x6b, 0xff, 0x7c, 0x51, + 0x61, 0xaf, 0x49, 0xb4, 0x31, 0xd7, 0xa4, 0xd9, 0x14, 0x2c, 0xe1, 0x74, 0x4f, 0xb5, 0x4d, 0x57, + 0x2c, 0xa9, 0xed, 0xe7, 0x0a, 0x98, 0xdc, 0x61, 0xce, 0x5b, 0x81, 0x0d, 0x39, 0xda, 0x83, 0x14, + 0x7a, 0x4c, 0x54, 0x13, 0xd6, 0x78, 0x95, 0x88, 0x1d, 0xfd, 0xe2, 0x6a, 0x26, 0x50, 0xf5, 0x3a, + 0x18, 0x0d, 0x24, 0x43, 0x54, 0xbc, 0x7f, 0x69, 0x5d, 0xf4, 0x4f, 0x2d, 0x0c, 0xba, 0x39, 0xfc, + 0xe8, 0x49, 0x69, 0xc0, 0x88, 0x08, 0xd6, 0x27, 0x64, 0x3e, 0x09, 0x75, 0x79, 0x01, 0xcc, 0x1f, + 0x51, 0x99, 0x64, 0xf0, 0x51, 0x06, 0xcc, 0xec, 0x30, 0x27, 0xce, 0x72, 0xc3, 0xb6, 0xb1, 0xa8, + 0x52, 0xa7, 0x06, 0xf0, 0x3a, 0x98, 0xc0, 0x3e, 0xe6, 0x18, 0xba, 0x66, 0x15, 0x89, 0xd2, 0x47, + 0x82, 0x0b, 0x72, 0x31, 0x44, 0xd3, 0xd3, 0xa2, 0x56, 0x27, 0x17, 0x40, 0x20, 0x22, 0x7d, 0xe3, + 0x91, 0x5f, 0x38, 0x29, 0x1a, 0x82, 0x83, 0x7c, 0xc4, 0x30, 0x33, 0xab, 0x90, 0x55, 0xe5, 0x9a, + 0x8e, 0x19, 0xb9, 0x68, 0xee, 0x1a, 0x64, 0x55, 0xb5, 0x04, 0x72, 0x15, 0xec, 0x43, 0xda, 0x08, + 0x11, 0xc3, 0x12, 0x01, 0xc2, 0x29, 0x09, 0xd8, 0x02, 0x80, 0x05, 0xf0, 0xd0, 0x37, 0xc5, 0x31, + 0x90, 0x1f, 0x89, 0x84, 0x84, 0x2d, 0x5e, 0x8b, 0x5b, 0xbc, 0xb6, 0x1f, 0x9f, 0x11, 0x9b, 0x19, + 0x21, 0xe4, 0xfe, 0x8f, 0x25, 0xc5, 0xc8, 0x4a, 0x3f, 0x61, 0x51, 0x6f, 0x82, 0xa9, 0x9a, 0x5f, + 0x21, 0xbe, 0x8d, 0x7d, 0xc7, 0x0c, 0x10, 0xc5, 0xc4, 0xce, 0x8f, 0x4a, 0xaa, 0x85, 0x63, 0x54, + 0xdb, 0xd1, 0x69, 0x12, 0x32, 0x7d, 0x2a, 0x98, 0x26, 0x13, 0xe7, 0x3d, 0xe9, 0xab, 0xbe, 0x09, + 0x54, 0xcb, 0xaa, 0x4b, 0x49, 0xa4, 0xc6, 0x63, 0xc6, 0x53, 0xdd, 0x33, 0x4e, 0x59, 0x56, 0x7d, + 0x3f, 0xf4, 0x8e, 0x28, 0xdf, 0x05, 0xf3, 0x9c, 0x42, 0x9f, 0x1d, 0x20, 0x7a, 0x94, 0x37, 0xd3, + 0x3d, 0xef, 0x5c, 0xcc, 0xd1, 0x4a, 0x7e, 0x0d, 0x2c, 0x25, 0x9d, 0x99, 0x22, 0x1b, 0x33, 0x4e, + 0x71, 0xa5, 0x26, 0x37, 0x5d, 0xbc, 0x6d, 0xf2, 0x59, 0xf9, 0x10, 0x14, 0x63, 0x9c, 0xd1, 0x02, + 0x7b, 0x2d, 0x42, 0xa9, 0xbb, 0xe0, 0xef, 0x72, 0x9b, 0x32, 0x21, 0xce, 0x6c, 0x61, 0x92, 0xa1, + 0x3d, 0xcc, 0x98, 0x60, 0x03, 0x4b, 0xca, 0xca, 0x90, 0xb1, 0x1c, 0x62, 0xf7, 0x10, 0xdd, 0x4e, + 0x21, 0xf7, 0x53, 0x40, 0x75, 0x15, 0xa8, 0x55, 0xcc, 0x38, 0xa1, 0xd8, 0x82, 0xae, 0x89, 0x7c, + 0x4e, 0x31, 0x62, 0xf9, 0x9c, 0x74, 0x9f, 0x6e, 0x5a, 0xae, 0x86, 0x06, 0xf5, 0x06, 0x58, 0x3e, + 0x31, 0xa8, 0x69, 0x55, 0xa1, 0xef, 0x23, 0x37, 0x3f, 0x26, 0x53, 0x29, 0xd9, 0x27, 0xc4, 0xdc, + 0x0a, 0x61, 0xea, 0x0c, 0x18, 0xe1, 0x24, 0x30, 0x6f, 0xe6, 0xc7, 0x97, 0x94, 0x95, 0x71, 0x63, + 0x98, 0x93, 0xe0, 0xa6, 0x7a, 0x1e, 0xcc, 0xd6, 0xa1, 0x8b, 0x6d, 0xc8, 0x09, 0x65, 0x66, 0x40, + 0x0e, 0x11, 0x35, 0x2d, 0x18, 0xe4, 0x27, 0x24, 0x46, 0x6d, 0xda, 0xf6, 0x84, 0x69, 0x0b, 0x06, + 0xea, 0x59, 0x30, 0x9d, 0xcc, 0x9a, 0x0c, 0x71, 0x09, 0x9f, 0x94, 0xf0, 0xc9, 0xc4, 0x70, 0x0b, + 0x71, 0x81, 0x5d, 0x04, 0x59, 0xe8, 0xba, 0xe4, 0xd0, 0xc5, 0x8c, 0xe7, 0xa7, 0x96, 0x86, 0x56, + 0xb2, 0x46, 0x73, 0x42, 0x2d, 0x80, 0x8c, 0x8d, 0xfc, 0x86, 0x34, 0x4e, 0x4b, 0x63, 0x32, 0x6e, + 0xed, 0x3a, 0x6a, 0xd7, 0x5d, 0xe7, 0x58, 0xab, 0x38, 0x0d, 0xfe, 0xda, 0xa6, 0x1d, 0x24, 0xed, + 0xe2, 0x1b, 0x05, 0xa8, 0x29, 0xbb, 0x81, 0x3c, 0x52, 0x87, 0x6e, 0xa7, 0x6e, 0xb1, 0x01, 0xb2, + 0x4c, 0x94, 0x51, 0xee, 0xcf, 0xc1, 0x1e, 0xf6, 0x67, 0x46, 0xb8, 0xc9, 0xed, 0xd9, 0x92, 0xdb, + 0x50, 0xff, 0xb9, 0x2d, 0x82, 0xc2, 0x71, 0xed, 0x49, 0x6a, 0x5f, 0x29, 0x60, 0x4e, 0x98, 0xab, + 0xd0, 0x77, 0x90, 0x81, 0x0e, 0x21, 0xb5, 0xb7, 0x91, 0x4f, 0x3c, 0xa6, 0x96, 0xc1, 0xb8, 0x2d, + 0xff, 0x99, 0x9c, 0x88, 0x2b, 0x4f, 0x5e, 0x91, 0xc5, 0xcf, 0x85, 0x93, 0xfb, 0x64, 0xc3, 0xb6, + 0xd5, 0x15, 0x30, 0xd5, 0xc4, 0x50, 0x41, 0x2d, 0xb2, 0x15, 0xb0, 0x89, 0x18, 0x26, 0x03, 0xfe, + 0x7e, 0xd9, 0x94, 0xe4, 0xb1, 0x7e, 0x5c, 0x6e, 0x92, 0xd0, 0x23, 0x05, 0x64, 0x76, 0x98, 0xb3, + 0x1b, 0xf0, 0xeb, 0xfe, 0x9f, 0xfc, 0x42, 0xa7, 0x82, 0xa9, 0x38, 0x93, 0x24, 0xbd, 0x2f, 0x14, + 0x90, 0x0d, 0x27, 0x77, 0x6b, 0xfc, 0x0f, 0xc9, 0xaf, 0x29, 0x7e, 0xe8, 0x65, 0xc4, 0xcf, 0x80, + 0xe9, 0x44, 0x67, 0xa2, 0xfe, 0xe7, 0x41, 0x79, 0x26, 0x27, 0x37, 0x37, 0x62, 0xe3, 0x03, 0x71, + 0x01, 0x12, 0x3d, 0x6f, 0x16, 0x8c, 0x70, 0xcc, 0x5d, 0x14, 0x25, 0x12, 0x0e, 0xd4, 0x25, 0x90, + 0xb3, 0x11, 0xb3, 0x28, 0x0e, 0x64, 0x3f, 0x1e, 0x0c, 0x8b, 0x9d, 0x9a, 0x6a, 0xa9, 0xc1, 0x50, + 0x6b, 0x0d, 0x92, 0x5e, 0x36, 0xdc, 0x45, 0x2f, 0x1b, 0xe9, 0xad, 0x97, 0x8d, 0x76, 0xd1, 0xcb, + 0x4e, 0x75, 0xea, 0x65, 0x99, 0x4e, 0xbd, 0x2c, 0xdb, 0xff, 0x0e, 0x59, 0x06, 0xa5, 0x13, 0x4a, + 0x1c, 0x2f, 0xc3, 0xda, 0x03, 0x00, 0x86, 0x76, 0x98, 0xa3, 0x7e, 0xa2, 0x80, 0xe9, 0xe3, 0x6f, + 0x41, 0xff, 0xeb, 0xea, 0x0a, 0xd6, 0xee, 0x55, 0xa3, 0xb0, 0xd1, 0xb7, 0x6b, 0xac, 0x4d, 0xfd, + 0x52, 0x01, 0x85, 0x0e, 0xaf, 0x28, 0x9b, 0xdd, 0x46, 0x38, 0x99, 0xa3, 0x70, 0xe3, 0xe5, 0x39, + 0x3a, 0xc8, 0x6d, 0x79, 0xc9, 0xe8, 0x53, 0x6e, 0x9a, 0xa3, 0x5f, 0xb9, 0xed, 0xae, 0xee, 0xea, + 0xc7, 0x0a, 0x98, 0x3a, 0x76, 0xeb, 0xfd, 0x6f, 0xb7, 0x01, 0x8e, 0x7a, 0x16, 0x5e, 0xed, 0xd7, + 0x33, 0x11, 0xf4, 0xa1, 0x02, 0x26, 0x8f, 0x9e, 0xab, 0x97, 0x7b, 0x65, 0x8d, 0x1c, 0x0b, 0xaf, + 0xf4, 0xe9, 0x98, 0xa8, 0xb9, 0xa7, 0x80, 0xb1, 0x96, 0xd7, 0x9a, 0xff, 0x74, 0xcb, 0x98, 0xf6, + 0x2a, 0x5c, 0xe9, 0xc7, 0x2b, 0x11, 0xe1, 0x81, 0x91, 0xf0, 0xf4, 0x5a, 0xed, 0x96, 0x46, 0xc2, + 0x0b, 0x17, 0x7b, 0x82, 0x27, 0xe1, 0x02, 0x30, 0x1a, 0x9d, 0x26, 0x5a, 0x0f, 0x04, 0xbb, 0x35, + 0x5e, 0xb8, 0xd4, 0x1b, 0x3e, 0x89, 0xf8, 0x99, 0x02, 0x66, 0xdb, 0x1e, 0x01, 0x57, 0x7a, 0x5d, + 0xbf, 0xb4, 0x77, 0x61, 0xfb, 0x65, 0xbc, 0x63, 0x71, 0x85, 0x91, 0xf7, 0x9f, 0x3f, 0x3c, 0xab, + 0x6c, 0xbe, 0xfd, 0xe8, 0x69, 0x51, 0x79, 0xfc, 0xb4, 0xa8, 0xfc, 0xf4, 0xb4, 0xa8, 0xdc, 0x7f, + 0x56, 0x1c, 0x78, 0xfc, 0xac, 0x38, 0xf0, 0xc3, 0xb3, 0xe2, 0xc0, 0x3b, 0xff, 0x77, 0x30, 0xaf, + 0xd6, 0x2a, 0x9a, 0x45, 0xbc, 0xe8, 0xb3, 0x98, 0xde, 0x8c, 0xbb, 0x9a, 0x7c, 0xd5, 0xaa, 0x5f, + 0xd4, 0xef, 0xb6, 0x7e, 0xda, 0x92, 0x9f, 0x02, 0x2a, 0xa3, 0xf2, 0xfa, 0xf7, 0xef, 0xdf, 0x02, + 0x00, 0x00, 0xff, 0xff, 0xb9, 0x17, 0x7f, 0x49, 0x56, 0x14, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1054,6 +1355,8 @@ type MsgClient interface { ConsumerAddition(ctx context.Context, in *MsgConsumerAddition, opts ...grpc.CallOption) (*MsgConsumerAdditionResponse, error) ConsumerRemoval(ctx context.Context, in *MsgConsumerRemoval, opts ...grpc.CallOption) (*MsgConsumerRemovalResponse, error) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + OptIn(ctx context.Context, in *MsgOptIn, opts ...grpc.CallOption) (*MsgOptInResponse, error) + OptOut(ctx context.Context, in *MsgOptOut, opts ...grpc.CallOption) (*MsgOptOutResponse, error) ConsumerModification(ctx context.Context, in *MsgConsumerModification, opts ...grpc.CallOption) (*MsgConsumerModificationResponse, error) } @@ -1119,6 +1422,24 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts return out, nil } +func (c *msgClient) OptIn(ctx context.Context, in *MsgOptIn, opts ...grpc.CallOption) (*MsgOptInResponse, error) { + out := new(MsgOptInResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/OptIn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) OptOut(ctx context.Context, in *MsgOptOut, opts ...grpc.CallOption) (*MsgOptOutResponse, error) { + out := new(MsgOptOutResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/OptOut", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) ConsumerModification(ctx context.Context, in *MsgConsumerModification, opts ...grpc.CallOption) (*MsgConsumerModificationResponse, error) { out := new(MsgConsumerModificationResponse) err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/ConsumerModification", in, out, opts...) @@ -1136,6 +1457,8 @@ type MsgServer interface { ConsumerAddition(context.Context, *MsgConsumerAddition) (*MsgConsumerAdditionResponse, error) ConsumerRemoval(context.Context, *MsgConsumerRemoval) (*MsgConsumerRemovalResponse, error) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + OptIn(context.Context, *MsgOptIn) (*MsgOptInResponse, error) + OptOut(context.Context, *MsgOptOut) (*MsgOptOutResponse, error) ConsumerModification(context.Context, *MsgConsumerModification) (*MsgConsumerModificationResponse, error) } @@ -1161,6 +1484,12 @@ func (*UnimplementedMsgServer) ConsumerRemoval(ctx context.Context, req *MsgCons func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") } +func (*UnimplementedMsgServer) OptIn(ctx context.Context, req *MsgOptIn) (*MsgOptInResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OptIn not implemented") +} +func (*UnimplementedMsgServer) OptOut(ctx context.Context, req *MsgOptOut) (*MsgOptOutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OptOut not implemented") +} func (*UnimplementedMsgServer) ConsumerModification(ctx context.Context, req *MsgConsumerModification) (*MsgConsumerModificationResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ConsumerModification not implemented") } @@ -1277,6 +1606,42 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_OptIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgOptIn) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).OptIn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/OptIn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).OptIn(ctx, req.(*MsgOptIn)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_OptOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgOptOut) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).OptOut(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/OptOut", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).OptOut(ctx, req.(*MsgOptOut)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_ConsumerModification_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgConsumerModification) if err := dec(in); err != nil { @@ -1323,6 +1688,14 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateParams", Handler: _Msg_UpdateParams_Handler, }, + { + MethodName: "OptIn", + Handler: _Msg_OptIn_Handler, + }, + { + MethodName: "OptOut", + Handler: _Msg_OptOut_Handler, + }, { MethodName: "ConsumerModification", Handler: _Msg_ConsumerModification_Handler, @@ -1636,7 +2009,46 @@ func (m *MsgConsumerAddition) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Authority) i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) i-- - dAtA[i] = 0x6a + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x78 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x70 + } + if m.Top_N != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x68 } if len(m.DistributionTransmissionChannel) > 0 { i -= len(m.DistributionTransmissionChannel) @@ -1890,7 +2302,7 @@ func (m *MsgChangeRewardDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *MsgConsumerModification) Marshal() (dAtA []byte, err error) { +func (m *MsgOptIn) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1900,48 +2312,48 @@ func (m *MsgConsumerModification) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgConsumerModification) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgOptIn) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgConsumerModification) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgOptIn) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Authority) > 0 { - i -= len(m.Authority) - copy(dAtA[i:], m.Authority) - i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- dAtA[i] = 0x22 } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + if len(m.ConsumerKey) > 0 { + i -= len(m.ConsumerKey) + copy(dAtA[i:], m.ConsumerKey) + i = encodeVarintTx(dAtA, i, uint64(len(m.ConsumerKey))) i-- dAtA[i] = 0x1a } - if len(m.Description) > 0 { - i -= len(m.Description) - copy(dAtA[i:], m.Description) - i = encodeVarintTx(dAtA, i, uint64(len(m.Description))) + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProviderAddr))) i-- dAtA[i] = 0x12 } - if len(m.Title) > 0 { - i -= len(m.Title) - copy(dAtA[i:], m.Title) - i = encodeVarintTx(dAtA, i, uint64(len(m.Title))) + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *MsgConsumerModificationResponse) Marshal() (dAtA []byte, err error) { +func (m *MsgOptInResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1951,12 +2363,12 @@ func (m *MsgConsumerModificationResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgConsumerModificationResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgOptInResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgConsumerModificationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgOptInResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1964,15 +2376,189 @@ func (m *MsgConsumerModificationResponse) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } -func encodeVarintTx(dAtA []byte, offset int, v uint64) int { - offset -= sovTx(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *MsgOptOut) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) + return dAtA[:n], nil +} + +func (m *MsgOptOut) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgOptOut) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x1a + } + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProviderAddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgOptOutResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgOptOutResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgOptOutResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgConsumerModification) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgConsumerModification) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerModification) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0x4a + } + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x30 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x28 + } + if m.Top_N != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x20 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0x1a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintTx(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintTx(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgConsumerModificationResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgConsumerModificationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerModificationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) return base } func (m *MsgAssignConsumerKey) Size() (n int) { @@ -2131,9 +2717,30 @@ func (m *MsgConsumerAddition) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + if m.Top_N != 0 { + n += 1 + sovTx(uint64(m.Top_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 2 + l + sovTx(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 2 + l + sovTx(uint64(l)) + } + } l = len(m.Authority) if l > 0 { - n += 1 + l + sovTx(uint64(l)) + n += 2 + l + sovTx(uint64(l)) } return n } @@ -2209,6 +2816,70 @@ func (m *MsgChangeRewardDenomsResponse) Size() (n int) { return n } +func (m *MsgOptIn) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProviderAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ConsumerKey) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgOptInResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgOptOut) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProviderAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgOptOutResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *MsgConsumerModification) Size() (n int) { if m == nil { return 0 @@ -2227,6 +2898,27 @@ func (m *MsgConsumerModification) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + if m.Top_N != 0 { + n += 1 + sovTx(uint64(m.Top_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } l = len(m.Authority) if l > 0 { n += 1 + l + sovTx(uint64(l)) @@ -3411,10 +4103,10 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 13: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) } - var stringLen uint64 + m.Top_N = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -3424,20 +4116,141 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Top_N |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } } - if postIndex > l { + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 16: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 17: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { return io.ErrUnexpectedEOF } m.Authority = string(dAtA[iNdEx:postIndex]) @@ -3906,7 +4719,7 @@ func (m *MsgChangeRewardDenomsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgConsumerModification) Unmarshal(dAtA []byte) error { +func (m *MsgOptIn) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3929,15 +4742,15 @@ func (m *MsgConsumerModification) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgConsumerModification: wiretype end group for non-group") + return fmt.Errorf("proto: MsgOptIn: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgConsumerModification: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgOptIn: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3965,11 +4778,11 @@ func (m *MsgConsumerModification) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Title = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3997,11 +4810,11 @@ func (m *MsgConsumerModification) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Description = string(dAtA[iNdEx:postIndex]) + m.ProviderAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4029,9 +4842,554 @@ func (m *MsgConsumerModification) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgOptInResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgOptInResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgOptInResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgOptOut) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgOptOut: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgOptOut: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgOptOutResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgOptOutResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgOptOutResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgConsumerModification) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgConsumerModification: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgConsumerModification: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) + } + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index feef69013b..97453d3487 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -331,56 +331,57 @@ func init() { } var fileDescriptor_d0a8be0efc64dfbc = []byte{ - // 783 bytes of a gzipped FileDescriptorProto + // 788 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x73, 0xdc, 0x34, - 0x14, 0x8e, 0xbb, 0x25, 0xdd, 0x68, 0x93, 0xa6, 0x68, 0x02, 0x98, 0x74, 0xc6, 0x71, 0x03, 0x87, - 0x1d, 0x98, 0xda, 0x64, 0x29, 0x17, 0x6e, 0x24, 0x4b, 0x29, 0x3d, 0x2c, 0x5b, 0xa7, 0x94, 0x19, - 0x38, 0x68, 0x64, 0xe9, 0xed, 0xae, 0x06, 0x5b, 0xda, 0x91, 0x64, 0x87, 0xfd, 0x05, 0x5c, 0x39, - 0xf2, 0x1b, 0xf8, 0x25, 0xe5, 0xd6, 0x23, 0x27, 0x60, 0x92, 0x3f, 0xc2, 0x58, 0xb6, 0x37, 0x5e, - 0x86, 0x40, 0xb9, 0xe9, 0x49, 0xdf, 0xf7, 0x59, 0xdf, 0x7b, 0x7a, 0xcf, 0xe8, 0x23, 0x21, 0x2d, - 0x68, 0xb6, 0xa0, 0x42, 0x12, 0x03, 0xac, 0xd0, 0xc2, 0xae, 0x62, 0xc6, 0xca, 0xb8, 0x3c, 0x89, - 0xcd, 0x82, 0x6a, 0xe0, 0x84, 0x29, 0x69, 0x8a, 0x1c, 0x74, 0xb4, 0xd4, 0xca, 0x2a, 0x7c, 0xf8, - 0x0f, 0x8c, 0x88, 0xb1, 0x32, 0x2a, 0x4f, 0x0e, 0xef, 0x5b, 0x90, 0x1c, 0x74, 0x2e, 0xa4, 0x8d, - 0x69, 0xca, 0x44, 0x6c, 0x57, 0x4b, 0x30, 0x35, 0xf1, 0x30, 0x16, 0x29, 0x8b, 0x33, 0x31, 0x5f, - 0x58, 0x96, 0x09, 0x90, 0xd6, 0xc4, 0x1d, 0x74, 0x79, 0xd2, 0x89, 0x1a, 0x42, 0x30, 0x57, 0x6a, - 0x9e, 0x41, 0xec, 0xa2, 0xb4, 0x98, 0xc5, 0xbc, 0xd0, 0xd4, 0x0a, 0x25, 0x9b, 0xf3, 0x83, 0xb9, - 0x9a, 0x2b, 0xb7, 0x8c, 0xab, 0x55, 0xbd, 0x7b, 0xfc, 0xcb, 0x36, 0xba, 0x7b, 0xd6, 0x5c, 0x79, - 0x4a, 0x35, 0xcd, 0x0d, 0xf6, 0xd1, 0x1d, 0x90, 0x34, 0xcd, 0x80, 0xfb, 0x5e, 0xe8, 0x0d, 0xfb, - 0x49, 0x1b, 0xe2, 0xaf, 0xd0, 0xfb, 0x69, 0xa6, 0xd8, 0xf7, 0x86, 0x2c, 0x41, 0x13, 0x2e, 0x8c, - 0xd5, 0x22, 0x2d, 0xaa, 0x6f, 0x10, 0xab, 0xa9, 0x34, 0xb9, 0x30, 0x46, 0x28, 0xe9, 0xdf, 0x0a, - 0xbd, 0x61, 0x2f, 0x79, 0x50, 0x63, 0xa7, 0xa0, 0xc7, 0x1d, 0xe4, 0xf3, 0x0e, 0x10, 0x3f, 0x45, - 0x0f, 0x6e, 0x54, 0x21, 0x6c, 0x41, 0xa5, 0x84, 0xcc, 0xef, 0x85, 0xde, 0x70, 0x27, 0x39, 0xe2, - 0x37, 0x88, 0x9c, 0xd5, 0x30, 0xfc, 0x29, 0x3a, 0x5c, 0x6a, 0x55, 0x0a, 0x0e, 0x9a, 0xcc, 0x00, - 0xc8, 0x52, 0xa9, 0x8c, 0x50, 0xce, 0x35, 0x31, 0x56, 0xfb, 0xb7, 0x9d, 0xc8, 0xdb, 0x2d, 0xe2, - 0x31, 0xc0, 0x54, 0xa9, 0xec, 0x33, 0xce, 0xf5, 0xb9, 0xd5, 0xf8, 0x19, 0xc2, 0x8c, 0x95, 0xc4, - 0x8a, 0x1c, 0x54, 0x61, 0x2b, 0x77, 0x42, 0x71, 0xff, 0x8d, 0xd0, 0x1b, 0x0e, 0x46, 0xef, 0x46, - 0x75, 0x62, 0xa3, 0x36, 0xb1, 0xd1, 0xb8, 0x49, 0xec, 0x69, 0xff, 0xe5, 0xef, 0x47, 0x5b, 0x3f, - 0xff, 0x71, 0xe4, 0x25, 0xf7, 0x18, 0x2b, 0x9f, 0xd7, 0xec, 0xa9, 0x23, 0xe3, 0xef, 0xd0, 0x3b, - 0xce, 0xcd, 0x0c, 0xf4, 0xdf, 0x75, 0xb7, 0x5f, 0x5f, 0xf7, 0xad, 0x56, 0x63, 0x53, 0xfc, 0x09, - 0x0a, 0xdb, 0x77, 0x46, 0x34, 0x6c, 0xa4, 0x70, 0xa6, 0x29, 0xab, 0x16, 0xfe, 0x1d, 0xe7, 0x38, - 0x68, 0x71, 0xc9, 0x06, 0xec, 0x71, 0x83, 0xc2, 0x0f, 0x11, 0x5e, 0x08, 0x63, 0x95, 0x16, 0x8c, - 0x66, 0x04, 0xa4, 0xd5, 0x02, 0x8c, 0xdf, 0x77, 0x05, 0x7c, 0xf3, 0xfa, 0xe4, 0xf3, 0xfa, 0x00, - 0x4f, 0xd0, 0xbd, 0x42, 0xa6, 0x4a, 0x72, 0x21, 0xe7, 0xad, 0x9d, 0x9d, 0xd7, 0xb7, 0xb3, 0xbf, - 0x26, 0x37, 0x46, 0xde, 0x43, 0x7b, 0x1a, 0x2e, 0xa8, 0xe6, 0x84, 0x83, 0x54, 0xb9, 0xf1, 0x07, - 0x61, 0x6f, 0xb8, 0x93, 0xec, 0xd6, 0x9b, 0x63, 0xb7, 0x87, 0x1f, 0xa1, 0x75, 0xdd, 0xc8, 0x26, - 0x7a, 0xd7, 0xa1, 0x0f, 0xda, 0xd3, 0xa4, 0xcb, 0x7a, 0x86, 0xb0, 0x06, 0xab, 0x57, 0x84, 0x43, - 0x46, 0x57, 0xed, 0x65, 0xf7, 0xfe, 0x47, 0x4d, 0x1d, 0x7d, 0x5c, 0xb1, 0xeb, 0xdb, 0x1e, 0xff, - 0xea, 0xa1, 0x83, 0xb6, 0x59, 0xbe, 0x00, 0x09, 0x46, 0x98, 0x73, 0x4b, 0x2d, 0xe0, 0x27, 0x68, - 0x7b, 0xe9, 0x9a, 0xc7, 0x75, 0xcc, 0x60, 0xf4, 0x41, 0x74, 0x73, 0xdb, 0x47, 0x9b, 0xed, 0x76, - 0x7a, 0xbb, 0xfa, 0x60, 0xd2, 0xf0, 0xf1, 0x53, 0xd4, 0x6f, 0xdd, 0xb8, 0x36, 0x1a, 0x8c, 0x86, - 0xff, 0xa6, 0x35, 0x6d, 0xb0, 0x5f, 0xca, 0x99, 0x6a, 0x94, 0xd6, 0x7c, 0x7c, 0x1f, 0xed, 0x48, - 0xb8, 0x20, 0x8e, 0xe9, 0xba, 0xa8, 0x9f, 0xf4, 0x25, 0x5c, 0x9c, 0x55, 0xf1, 0xf1, 0x8f, 0xb7, - 0xd0, 0x6e, 0x97, 0x8d, 0x27, 0x68, 0xb7, 0x9e, 0x34, 0xc4, 0x54, 0x9e, 0x1a, 0x27, 0x1f, 0x46, - 0x22, 0x65, 0x51, 0x77, 0x0e, 0x45, 0x9d, 0xc9, 0x53, 0xb9, 0x71, 0xbb, 0x2e, 0x0d, 0xc9, 0x80, - 0x5d, 0x07, 0xf8, 0x1b, 0xb4, 0x5f, 0xbd, 0x3d, 0x90, 0xa6, 0x30, 0x8d, 0x64, 0x6d, 0x28, 0xfa, - 0x4f, 0xc9, 0x96, 0x56, 0xab, 0xde, 0x65, 0x1b, 0x31, 0x9e, 0xa0, 0x7d, 0x21, 0x85, 0x15, 0x34, - 0x23, 0x25, 0xcd, 0x88, 0x01, 0xeb, 0xf7, 0xc2, 0xde, 0x70, 0x30, 0x0a, 0xbb, 0x3a, 0xd5, 0x40, - 0x8d, 0x5e, 0xd0, 0x4c, 0x70, 0x6a, 0x95, 0xfe, 0x7a, 0xc9, 0xa9, 0x85, 0x26, 0x43, 0x7b, 0x0d, - 0xfd, 0x05, 0xcd, 0xce, 0xc1, 0x9e, 0x4e, 0x5e, 0x5e, 0x06, 0xde, 0xab, 0xcb, 0xc0, 0xfb, 0xf3, - 0x32, 0xf0, 0x7e, 0xba, 0x0a, 0xb6, 0x5e, 0x5d, 0x05, 0x5b, 0xbf, 0x5d, 0x05, 0x5b, 0xdf, 0x3e, - 0x9a, 0x0b, 0xbb, 0x28, 0xd2, 0x88, 0xa9, 0x3c, 0x66, 0xca, 0xe4, 0xca, 0xc4, 0xd7, 0xb5, 0x78, - 0xb8, 0xfe, 0x01, 0x94, 0x9f, 0xc4, 0x3f, 0xb8, 0xbf, 0x80, 0x9b, 0xdf, 0xe9, 0xb6, 0x7b, 0x54, - 0x1f, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, 0x3e, 0x93, 0xff, 0x6c, 0x2d, 0x06, 0x00, 0x00, + 0x14, 0x8e, 0xbb, 0x21, 0xdd, 0x68, 0x93, 0x26, 0x68, 0x02, 0x98, 0x74, 0xc6, 0x71, 0x03, 0x87, + 0x1d, 0x98, 0xda, 0x24, 0x94, 0x0b, 0x37, 0x92, 0x50, 0x4a, 0x0e, 0xcb, 0xd6, 0x29, 0x65, 0x06, + 0x0e, 0x1a, 0x59, 0x7a, 0xbb, 0xab, 0xc1, 0x96, 0x76, 0x24, 0xd9, 0x61, 0x7f, 0x01, 0x57, 0x8e, + 0xfc, 0x0c, 0x7e, 0x46, 0xb9, 0xf5, 0xc8, 0x09, 0x98, 0xe4, 0x8f, 0x30, 0x96, 0xed, 0x8d, 0x97, + 0x21, 0x10, 0x6e, 0x7a, 0xd2, 0xf7, 0x7d, 0xd6, 0xf7, 0x9e, 0xde, 0x33, 0xfa, 0x48, 0x48, 0x0b, + 0x9a, 0xcd, 0xa8, 0x90, 0xc4, 0x00, 0x2b, 0xb4, 0xb0, 0x8b, 0x98, 0xb1, 0x32, 0x2e, 0x8f, 0x62, + 0x33, 0xa3, 0x1a, 0x38, 0x61, 0x4a, 0x9a, 0x22, 0x07, 0x1d, 0xcd, 0xb5, 0xb2, 0x0a, 0xef, 0xff, + 0x03, 0x23, 0x62, 0xac, 0x8c, 0xca, 0xa3, 0xfd, 0x87, 0x16, 0x24, 0x07, 0x9d, 0x0b, 0x69, 0x63, + 0x9a, 0x32, 0x11, 0xdb, 0xc5, 0x1c, 0x4c, 0x4d, 0xdc, 0x8f, 0x45, 0xca, 0xe2, 0x4c, 0x4c, 0x67, + 0x96, 0x65, 0x02, 0xa4, 0x35, 0x71, 0x07, 0x5d, 0x1e, 0x75, 0xa2, 0x86, 0x10, 0x4c, 0x95, 0x9a, + 0x66, 0x10, 0xbb, 0x28, 0x2d, 0x26, 0x31, 0x2f, 0x34, 0xb5, 0x42, 0xc9, 0xe6, 0x7c, 0x6f, 0xaa, + 0xa6, 0xca, 0x2d, 0xe3, 0x6a, 0x55, 0xef, 0x1e, 0xfe, 0xb2, 0x81, 0x1e, 0x9c, 0x36, 0x57, 0x1e, + 0x53, 0x4d, 0x73, 0x83, 0x7d, 0x74, 0x1f, 0x24, 0x4d, 0x33, 0xe0, 0xbe, 0x17, 0x7a, 0xc3, 0x7e, + 0xd2, 0x86, 0xf8, 0x2b, 0xf4, 0x7e, 0x9a, 0x29, 0xf6, 0xbd, 0x21, 0x73, 0xd0, 0x84, 0x0b, 0x63, + 0xb5, 0x48, 0x8b, 0xea, 0x1b, 0xc4, 0x6a, 0x2a, 0x4d, 0x2e, 0x8c, 0x11, 0x4a, 0xfa, 0xf7, 0x42, + 0x6f, 0xd8, 0x4b, 0x1e, 0xd5, 0xd8, 0x31, 0xe8, 0xb3, 0x0e, 0xf2, 0x45, 0x07, 0x88, 0xcf, 0xd1, + 0xa3, 0x5b, 0x55, 0x08, 0x9b, 0x51, 0x29, 0x21, 0xf3, 0x7b, 0xa1, 0x37, 0xdc, 0x4c, 0x0e, 0xf8, + 0x2d, 0x22, 0xa7, 0x35, 0x0c, 0x7f, 0x8a, 0xf6, 0xe7, 0x5a, 0x95, 0x82, 0x83, 0x26, 0x13, 0x00, + 0x32, 0x57, 0x2a, 0x23, 0x94, 0x73, 0x4d, 0x8c, 0xd5, 0xfe, 0xba, 0x13, 0x79, 0xbb, 0x45, 0x3c, + 0x05, 0x18, 0x2b, 0x95, 0x7d, 0xc6, 0xb9, 0xbe, 0xb0, 0x1a, 0x3f, 0x47, 0x98, 0xb1, 0x92, 0x58, + 0x91, 0x83, 0x2a, 0x6c, 0xe5, 0x4e, 0x28, 0xee, 0xbf, 0x11, 0x7a, 0xc3, 0xc1, 0xf1, 0xbb, 0x51, + 0x9d, 0xd8, 0xa8, 0x4d, 0x6c, 0x74, 0xd6, 0x24, 0xf6, 0xa4, 0xff, 0xea, 0xf7, 0x83, 0xb5, 0x9f, + 0xff, 0x38, 0xf0, 0x92, 0x5d, 0xc6, 0xca, 0x17, 0x35, 0x7b, 0xec, 0xc8, 0xf8, 0x3b, 0xf4, 0x8e, + 0x73, 0x33, 0x01, 0xfd, 0x77, 0xdd, 0x8d, 0xbb, 0xeb, 0xbe, 0xd5, 0x6a, 0xac, 0x8a, 0x3f, 0x43, + 0x61, 0xfb, 0xce, 0x88, 0x86, 0x95, 0x14, 0x4e, 0x34, 0x65, 0xd5, 0xc2, 0xbf, 0xef, 0x1c, 0x07, + 0x2d, 0x2e, 0x59, 0x81, 0x3d, 0x6d, 0x50, 0xf8, 0x31, 0xc2, 0x33, 0x61, 0xac, 0xd2, 0x82, 0xd1, + 0x8c, 0x80, 0xb4, 0x5a, 0x80, 0xf1, 0xfb, 0xae, 0x80, 0x6f, 0xde, 0x9c, 0x7c, 0x5e, 0x1f, 0xe0, + 0x11, 0xda, 0x2d, 0x64, 0xaa, 0x24, 0x17, 0x72, 0xda, 0xda, 0xd9, 0xbc, 0xbb, 0x9d, 0x9d, 0x25, + 0xb9, 0x31, 0xf2, 0x1e, 0xda, 0xd6, 0x70, 0x49, 0x35, 0x27, 0x1c, 0xa4, 0xca, 0x8d, 0x3f, 0x08, + 0x7b, 0xc3, 0xcd, 0x64, 0xab, 0xde, 0x3c, 0x73, 0x7b, 0xf8, 0x09, 0x5a, 0xd6, 0x8d, 0xac, 0xa2, + 0xb7, 0x1c, 0x7a, 0xaf, 0x3d, 0x4d, 0xba, 0xac, 0xe7, 0x08, 0x6b, 0xb0, 0x7a, 0x41, 0x38, 0x64, + 0x74, 0xd1, 0x5e, 0x76, 0xfb, 0x7f, 0xd4, 0xd4, 0xd1, 0xcf, 0x2a, 0x76, 0x7d, 0xdb, 0xf3, 0xf5, + 0x3e, 0xda, 0x1d, 0x1c, 0xfe, 0xea, 0xa1, 0xbd, 0xb6, 0x65, 0xbe, 0x00, 0x09, 0x46, 0x98, 0x0b, + 0x4b, 0x2d, 0xe0, 0x67, 0x68, 0x63, 0xee, 0x5a, 0xc8, 0xf5, 0xcd, 0xe0, 0xf8, 0x83, 0xe8, 0xf6, + 0xe6, 0x8f, 0x56, 0x9b, 0xee, 0x64, 0xbd, 0xfa, 0x6c, 0xd2, 0xf0, 0xf1, 0x39, 0xea, 0xb7, 0x9e, + 0x5c, 0x33, 0x0d, 0x8e, 0x87, 0xff, 0xa6, 0x35, 0x6e, 0xb0, 0x5f, 0xca, 0x89, 0x6a, 0x94, 0x96, + 0x7c, 0xfc, 0x10, 0x6d, 0x4a, 0xb8, 0x24, 0x8e, 0xe9, 0x7a, 0xa9, 0x9f, 0xf4, 0x25, 0x5c, 0x9e, + 0x56, 0xf1, 0xe1, 0x8f, 0xf7, 0xd0, 0x56, 0x97, 0x8d, 0x47, 0x68, 0xab, 0x9e, 0x37, 0xc4, 0x54, + 0x9e, 0x1a, 0x27, 0x1f, 0x46, 0x22, 0x65, 0x51, 0x77, 0x1a, 0x45, 0x9d, 0xf9, 0x53, 0xb9, 0x71, + 0xbb, 0x2e, 0x0d, 0xc9, 0x80, 0xdd, 0x04, 0xf8, 0x1b, 0xb4, 0x53, 0xbd, 0x40, 0x90, 0xa6, 0x30, + 0x8d, 0x64, 0x6d, 0x28, 0xfa, 0x4f, 0xc9, 0x96, 0x56, 0xab, 0x3e, 0x60, 0x2b, 0x31, 0x1e, 0xa1, + 0x1d, 0x21, 0x85, 0x15, 0x34, 0x23, 0x25, 0xcd, 0x88, 0x01, 0xeb, 0xf7, 0xc2, 0xde, 0x70, 0x70, + 0x1c, 0x76, 0x75, 0xaa, 0xb1, 0x1a, 0xbd, 0xa4, 0x99, 0xe0, 0xd4, 0x2a, 0xfd, 0xf5, 0x9c, 0x53, + 0x0b, 0x4d, 0x86, 0xb6, 0x1b, 0xfa, 0x4b, 0x9a, 0x5d, 0x80, 0x3d, 0x19, 0xbd, 0xba, 0x0a, 0xbc, + 0xd7, 0x57, 0x81, 0xf7, 0xe7, 0x55, 0xe0, 0xfd, 0x74, 0x1d, 0xac, 0xbd, 0xbe, 0x0e, 0xd6, 0x7e, + 0xbb, 0x0e, 0xd6, 0xbe, 0x7d, 0x32, 0x15, 0x76, 0x56, 0xa4, 0x11, 0x53, 0x79, 0xcc, 0x94, 0xc9, + 0x95, 0x89, 0x6f, 0x6a, 0xf1, 0x78, 0xf9, 0x1b, 0x28, 0x3f, 0x89, 0x7f, 0x70, 0xff, 0x02, 0x37, + 0xc5, 0xd3, 0x0d, 0xf7, 0xb4, 0x3e, 0xfe, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x69, 0x35, 0x0b, 0xfa, + 0x33, 0x06, 0x00, 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) {