diff --git a/.changelog/v5.1.1/api-breaking/provider/2095-proto-message-fix.md b/.changelog/v5.1.1/api-breaking/provider/2095-proto-message-fix.md index bb41e17a3c..2fa746a166 100644 --- a/.changelog/v5.1.1/api-breaking/provider/2095-proto-message-fix.md +++ b/.changelog/v5.1.1/api-breaking/provider/2095-proto-message-fix.md @@ -1,2 +1,2 @@ -- Fix incorrect message defitions in the proto files of the provider module +- Fix incorrect message definitions in the proto files of the provider module ([\#2095](https://github.com/cosmos/interchain-security/pull/2095)) \ No newline at end of file diff --git a/.changelog/v5.1.1/state-breaking/provider/2095-proto-message-fix.md b/.changelog/v5.1.1/state-breaking/provider/2095-proto-message-fix.md index bb41e17a3c..2fa746a166 100644 --- a/.changelog/v5.1.1/state-breaking/provider/2095-proto-message-fix.md +++ b/.changelog/v5.1.1/state-breaking/provider/2095-proto-message-fix.md @@ -1,2 +1,2 @@ -- Fix incorrect message defitions in the proto files of the provider module +- Fix incorrect message definitions in the proto files of the provider module ([\#2095](https://github.com/cosmos/interchain-security/pull/2095)) \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 70e4efd850..7f9c8e1027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,13 @@ ### API BREAKING - [Provider](x/ccv/provider) - - Fix incorrect message defitions in the proto files of the provider module + - Fix incorrect message definitions in the proto files of the provider module ([\#2095](https://github.com/cosmos/interchain-security/pull/2095)) ### STATE BREAKING - [Provider](x/ccv/provider) - - Fix incorrect message defitions in the proto files of the provider module + - Fix incorrect message definitions in the proto files of the provider module ([\#2095](https://github.com/cosmos/interchain-security/pull/2095)) ## v5.1.0 diff --git a/docs/docs/integrators/integrating_inactive_validators.md b/docs/docs/integrators/integrating_inactive_validators.md index 8bab9683fa..dbc7408156 100644 --- a/docs/docs/integrators/integrating_inactive_validators.md +++ b/docs/docs/integrators/integrating_inactive_validators.md @@ -4,7 +4,7 @@ sidebar_position: 1 # Inactive Validators Integration Guide -With the [inactive validators feature of Interchain Security](../adrs/adr-017-allowing-inactive-validators.md), validators outside of the active set on the provider chain can validate on consumer chains that allow this. Technically, this is achieved by *increasing* the MaxValidators paramater in the staking module, to let additional validators be part of the set of bonded validators. However, to keep the set of validators participating in consensus on the Cosmos Hub the same, we introduce the MaxProviderConsensusValidators parameter in the provider module, which will restrict the number of validators that actively validate on the provider chain. +With the [inactive validators feature of Interchain Security](../adrs/adr-017-allowing-inactive-validators.md), validators outside of the active set on the provider chain can validate on consumer chains that allow this. Technically, this is achieved by *increasing* the MaxValidators parameter in the staking module, to let additional validators be part of the set of bonded validators. However, to keep the set of validators participating in consensus on the Cosmos Hub the same, we introduce the MaxProviderConsensusValidators parameter in the provider module, which will restrict the number of validators that actively validate on the provider chain. To clarify the terminology: diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index 7204d5754b..3a4a1108aa 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -464,3 +464,20 @@ message PowerShapingParameters { // ConsumerIds contains consumer ids of chains // Used so we can easily (de)serialize slices of strings message ConsumerIds { repeated string ids = 1; } + +// ConsumerPhase indicates the phases of a consumer chain according to ADR 019 +enum ConsumerPhase { + // UNSPECIFIED defines an empty phase. + CONSUMER_PHASE_UNSPECIFIED = 0; + // REGISTERED defines the phase in which a consumer chain has been assigned a unique consumer id. + // A chain in this phase cannot yet launch. + CONSUMER_PHASE_REGISTERED = 1; + // INITIALIZED defines the phase in which a consumer chain has set all the needed parameters to launch but + // has not yet launched (e.g., because the `spawnTime` of the consumer chain has not yet been reached). + CONSUMER_PHASE_INITIALIZED = 2; + // LAUNCHED defines the phase in which a consumer chain is running and consuming a subset of the validator + // set of the provider. + CONSUMER_PHASE_LAUNCHED = 3; + // STOPPED defines the phase in which a previously-launched chain has stopped. + CONSUMER_PHASE_STOPPED = 4; +} diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto index d0a78fe078..05c8ecc5c8 100644 --- a/proto/interchain_security/ccv/provider/v1/query.proto +++ b/proto/interchain_security/ccv/provider/v1/query.proto @@ -196,11 +196,11 @@ message QueryConsumerChainsRequest { // the returned consumer chains bool filter_by_phase = 1; // The phase of the consumer chains returned (optional) - // Registered=0|Initialized=1|FailedToLaunch=2|Launched=3|Stopped=4 - uint32 phase = 2; + // Registered=1|Initialized=2|Launched=3|Stopped=4 + ConsumerPhase phase = 2; // The limit of consumer chains returned (optional) // default is 100 - uint32 limit = 3; + int32 limit = 3; } message QueryConsumerChainsResponse { repeated Chain chains = 1; } @@ -236,7 +236,7 @@ message Chain { // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. repeated string denylist = 8; // The phase the consumer chain (Registered=0|Initialized=1|FailedToLaunch=2|Launched=3|Stopped=4) - uint32 phase = 9; + ConsumerPhase phase = 9; // The metadata of the consumer chain ConsumerMetadata metadata = 10 [(gogoproto.nullable) = false ]; } diff --git a/proto/interchain_security/ccv/provider/v1/tx.proto b/proto/interchain_security/ccv/provider/v1/tx.proto index eb4d5ba5f0..19541025e5 100644 --- a/proto/interchain_security/ccv/provider/v1/tx.proto +++ b/proto/interchain_security/ccv/provider/v1/tx.proto @@ -39,6 +39,7 @@ service Msg { rpc ConsumerModification(MsgConsumerModification) returns (MsgConsumerModificationResponse) { option deprecated = true; } + rpc ChangeRewardDenoms(MsgChangeRewardDenoms) returns (MsgChangeRewardDenomsResponse); } @@ -223,7 +224,7 @@ message MsgConsumerRemovalResponse {} // MsgRemoveConsumer defines the message used to remove (and stop) a consumer chain. // If it passes, all the consumer chain's state is eventually removed from the provider chain. message MsgRemoveConsumer { - option (cosmos.msg.v1.signer) = "authority"; + option (cosmos.msg.v1.signer) = "signer"; // the consumer id of the consumer chain to be stopped string consumer_id = 1; @@ -232,7 +233,7 @@ message MsgRemoveConsumer { google.protobuf.Timestamp stop_time = 2 [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; // signer address - string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string signer = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; } // MsgRemoveConsumerResponse defines response type for MsgRemoveConsumer messages diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 22333aad8c..1ba117b3cc 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -2227,8 +2227,8 @@ func (tr Chain) submitChangeRewardDenomsProposal(action SubmitChangeRewardDenoms "messages": [ { "@type": "/interchain_security.ccv.provider.v1.MsgChangeRewardDenoms", - "denoms_to_add": %s, - "denoms_to_remove": %s, + "denoms_to_add": ["%s"], + "denoms_to_remove": ["%s"], "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn" } ], @@ -2239,15 +2239,15 @@ func (tr Chain) submitChangeRewardDenomsProposal(action SubmitChangeRewardDenoms "expedited": false }` - denomsToAdd := []string{action.Denom} - denomsToRemove := []string{"stake"} + denomsToAdd := action.Denom + denomsToRemove := "stake" jsonStr := fmt.Sprintf(template, denomsToAdd, denomsToRemove, action.Deposit) //#nosec G204 -- bypass unsafe quoting warning (no production code) - proposalFile := "/consumer-addition.proposal" + proposalFile := "/change-reward.proposal" bz, err := tr.target.ExecCommand( "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, proposalFile), ).CombinedOutput() diff --git a/tests/e2e/test_driver.go b/tests/e2e/test_driver.go index e25b27f330..f65ddfe6ab 100644 --- a/tests/e2e/test_driver.go +++ b/tests/e2e/test_driver.go @@ -221,7 +221,8 @@ func (td *DefaultDriver) runAction(action interface{}) error { target.startConsumerEvidenceDetector(action, td.verbose) case SubmitChangeRewardDenomsProposalAction: target = td.getTargetDriver(action.Chain) - if semver.Compare(semver.Major(target.testConfig.providerVersion), "v5") < 0 { + version := target.testConfig.providerVersion + if semver.IsValid(version) && semver.Compare(semver.Major(version), "v5") < 0 { target.submitChangeRewardDenomsLegacyProposal(action, td.verbose) } else { target.submitChangeRewardDenomsProposal(action, td.verbose) diff --git a/tests/integration/setup.go b/tests/integration/setup.go index 20924e9b2e..04f1882113 100644 --- a/tests/integration/setup.go +++ b/tests/integration/setup.go @@ -3,7 +3,6 @@ package integration import ( "context" "fmt" - "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" "testing" transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" @@ -22,6 +21,7 @@ import ( icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" testutil "github.com/cosmos/interchain-security/v5/testutil/integration" consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -150,7 +150,7 @@ func (suite *CCVTestSuite) SetupTest() { // 2. MakeGenesis is called on the provider chain // 3. ibc/testing sets the tendermint header for the consumer chain app - providerKeeper.SetConsumerPhase(suite.providerCtx(), icstestingutils.FirstConsumerId, keeper.Initialized) + providerKeeper.SetConsumerPhase(suite.providerCtx(), icstestingutils.FirstConsumerId, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) preProposalKeyAssignment(suite, icstestingutils.FirstConsumerId) // start consumer chains diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index d9aa02d732..8b0cdfa9f0 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -3,10 +3,10 @@ package ibc_testing import ( "encoding/json" "fmt" - clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" - "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" "testing" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibctesting "github.com/cosmos/ibc-go/v8/testing" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" "github.com/stretchr/testify/require" @@ -158,8 +158,8 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( providerKeeper.SetConsumerMetadata(providerChain.GetContext(), consumerId, consumerMetadata) providerKeeper.SetConsumerInitializationParameters(providerChain.GetContext(), consumerId, initializationParameters) providerKeeper.SetConsumerPowerShapingParameters(providerChain.GetContext(), consumerId, powerShapingParameters) - providerKeeper.SetConsumerPhase(providerChain.GetContext(), consumerId, keeper.Initialized) - providerKeeper.AppendSpawnTimeForConsumerToBeLaunched(providerChain.GetContext(), consumerId, coordinator.CurrentTime) + providerKeeper.SetConsumerPhase(providerChain.GetContext(), consumerId, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(providerChain.GetContext(), consumerId, coordinator.CurrentTime) // opt-in all validators lastVals, err := providerApp.GetProviderKeeper().GetLastBondedValidators(providerChain.GetContext()) diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index ef8d3a747f..a7ef6d7563 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -235,7 +235,7 @@ func SetupForStoppingConsumerChain(t *testing.T, ctx sdk.Context, providerKeeper.SetConsumerMetadata(ctx, consumerId, GetTestConsumerMetadata()) providerKeeper.SetConsumerInitializationParameters(ctx, consumerId, GetTestInitializationParameters()) providerKeeper.SetConsumerPowerShapingParameters(ctx, consumerId, GetTestPowerShapingParameters()) - providerKeeper.SetConsumerPhase(ctx, consumerId, providerkeeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) err := providerKeeper.CreateConsumerClient(ctx, consumerId) require.NoError(t, err) @@ -283,7 +283,7 @@ func GetTestConsumerMetadata() providertypes.ConsumerMetadata { func GetTestInitializationParameters() providertypes.ConsumerInitializationParameters { initialHeight := clienttypes.NewHeight(4, 5) - spawnTime := time.Now() + spawnTime := time.Now().UTC() ccvTimeoutPeriod := types.DefaultCCVTimeoutPeriod transferTimeoutPeriod := types.DefaultTransferTimeoutPeriod unbondingPeriod := types.DefaultConsumerUnbondingPeriod diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go index 84dae8d1da..dca9c0c032 100644 --- a/x/ccv/provider/client/cli/query.go +++ b/x/ccv/provider/client/cli/query.go @@ -94,7 +94,7 @@ func CmdConsumerChains() *cobra.Command { return err } req.FilterByPhase = true - req.Phase = uint32(phase) + req.Phase = types.ConsumerPhase(phase) } if args[1] != "" { @@ -102,7 +102,7 @@ func CmdConsumerChains() *cobra.Command { if err != nil { return err } - req.Limit = uint32(limit) + req.Limit = int32(limit) } res, err := queryClient.QueryConsumerChains(cmd.Context(), req) diff --git a/x/ccv/provider/handler_test.go b/x/ccv/provider/handler_test.go index 7ea306f47e..0d06ba7dea 100644 --- a/x/ccv/provider/handler_test.go +++ b/x/ccv/provider/handler_test.go @@ -55,7 +55,7 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { - k.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) + k.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), @@ -88,7 +88,7 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { - k.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) + k.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), @@ -103,7 +103,7 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { - k.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) + k.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // Use the consumer key already used by some other validator k.SetValidatorByConsumerAddr(ctx, "consumerId", consumerConsAddr, providerConsAddr2) @@ -127,7 +127,7 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { - k.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) + k.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // Use the consumer key already k.SetValidatorByConsumerAddr(ctx, "consumerId", consumerConsAddr, providerConsAddr) @@ -149,7 +149,7 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { - k.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) + k.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // Use the consumer key already used by some other validator k.SetValidatorByConsumerAddr(ctx, "consumerId", consumerConsAddr, providerConsAddr2) diff --git a/x/ccv/provider/keeper/distribution.go b/x/ccv/provider/keeper/distribution.go index 13698cde32..9291e57a76 100644 --- a/x/ccv/provider/keeper/distribution.go +++ b/x/ccv/provider/keeper/distribution.go @@ -74,33 +74,33 @@ func (k Keeper) AllocateTokens(ctx sdk.Context) { return } - // Iterate over all registered consumer chains - for _, consumerChainID := range k.GetAllRegisteredConsumerIds(ctx) { + // Iterate over all launched consumer chains + for _, consumerId := range k.GetAllRegisteredConsumerIds(ctx) { // note that it's possible that no rewards are collected even though the // reward pool isn't empty. This can happen if the reward pool holds some tokens // of non-whitelisted denominations. - alloc := k.GetConsumerRewardsAllocation(ctx, consumerChainID) + alloc := k.GetConsumerRewardsAllocation(ctx, consumerId) if alloc.Rewards.IsZero() { continue } // temporary workaround to keep CanWithdrawInvariant happy // general discussions here: https://github.com/cosmos/cosmos-sdk/issues/2906#issuecomment-441867634 - if k.ComputeConsumerTotalVotingPower(ctx, consumerChainID) == 0 { + if k.ComputeConsumerTotalVotingPower(ctx, consumerId) == 0 { rewardsToSend, rewardsChange := alloc.Rewards.TruncateDecimal() err := k.distributionKeeper.FundCommunityPool(context.Context(ctx), rewardsToSend, k.accountKeeper.GetModuleAccount(ctx, types.ConsumerRewardsPool).GetAddress()) if err != nil { k.Logger(ctx).Error( "fail to allocate rewards from consumer chain %s to community pool: %s", - consumerChainID, + consumerId, err, ) } // set the consumer allocation to the remaining reward decimals alloc.Rewards = rewardsChange - k.SetConsumerRewardsAllocation(ctx, consumerChainID, alloc) + k.SetConsumerRewardsAllocation(ctx, consumerId, alloc) return } @@ -112,7 +112,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context) { if err != nil { k.Logger(ctx).Error( "cannot get community tax while allocating rewards from consumer chain %s: %s", - consumerChainID, + consumerId, err, ) continue @@ -132,7 +132,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context) { if err != nil { k.Logger(ctx).Error( "cannot send rewards to distribution module account %s: %s", - consumerChainID, + consumerId, err, ) continue @@ -141,7 +141,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context) { // allocate tokens to consumer validators k.AllocateTokensToConsumerValidators( ctx, - consumerChainID, + consumerId, sdk.NewDecCoinsFromCoins(validatorsRewardsTrunc...), ) @@ -151,7 +151,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context) { if err != nil { k.Logger(ctx).Error( "fail to allocate rewards from consumer chain %s to community pool: %s", - consumerChainID, + consumerId, err, ) continue @@ -159,7 +159,7 @@ func (k Keeper) AllocateTokens(ctx sdk.Context) { // set consumer allocations to the remaining rewards decimals alloc.Rewards = validatorsRewardsChange.Add(remainingChanges...) - k.SetConsumerRewardsAllocation(ctx, consumerChainID, alloc) + k.SetConsumerRewardsAllocation(ctx, consumerId, alloc) } } diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go index 3a79d77df5..081a7bc6ea 100644 --- a/x/ccv/provider/keeper/grpc_query.go +++ b/x/ccv/provider/keeper/grpc_query.go @@ -52,10 +52,10 @@ func (k Keeper) QueryConsumerChains(goCtx context.Context, req *types.QueryConsu consumerIds := []string{} - phase := ConsumerPhase(byte(req.Phase)) + phase := types.ConsumerPhase(req.Phase) // if phase filter is set Launched get consumer from the state directly - if req.FilterByPhase && phase == Launched { + if req.FilterByPhase && phase == types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED { consumerIds = append(consumerIds, k.GetAllRegisteredConsumerIds(ctx)...) // otherwise iterate over all the consumer using the last unused consumer Id } else { @@ -66,8 +66,8 @@ func (k Keeper) QueryConsumerChains(goCtx context.Context, req *types.QueryConsu for i := uint64(0); i < firstUnusedConsumerId; i++ { // if the filter is set, verify that the consumer has the same phase if req.FilterByPhase { - p, ok := k.GetConsumerPhase(ctx, strconv.FormatInt(int64(i), 10)) - if !ok { + p := k.GetConsumerPhase(ctx, strconv.FormatInt(int64(i), 10)) + if p == types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED { return nil, status.Error(codes.Internal, fmt.Sprintf("cannot retrieve phase for consumer id: %d", i)) } if p != phase { @@ -117,8 +117,8 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, consumerId string) (types.Chai clientId, _ := k.GetConsumerClientId(ctx, consumerId) - phase, ok := k.GetConsumerPhase(ctx, consumerId) - if !ok { + phase := k.GetConsumerPhase(ctx, consumerId) + if phase == types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED { return types.Chain{}, fmt.Errorf("cannot find phase for consumer (%s)", consumerId) } @@ -148,7 +148,7 @@ func (k Keeper) GetConsumerChain(ctx sdk.Context, consumerId string) (types.Chai ValidatorsPowerCap: k.GetValidatorsPowerCap(ctx, consumerId), Allowlist: strAllowlist, Denylist: strDenylist, - Phase: uint32(phase), + Phase: phase, Metadata: metadata, }, nil } @@ -485,29 +485,29 @@ func (k Keeper) hasToValidate( if err != nil { return false, nil } + + minPowerToOptIn := int64(0) + // If the consumer is TopN compute the minimum power if topN := k.GetTopN(ctx, consumerId); topN > 0 { - // in a Top-N chain, we automatically opt in all validators that belong to the top N - minPower, found := k.GetMinimumPowerInTopN(ctx, consumerId) - if found { - k.OptInTopNValidators(ctx, consumerId, activeValidators, minPower) - } else { - k.Logger(ctx).Error("did not find min power in top N for chain", "chain", consumerId) + // compute the minimum power to opt-in since the one in the state is stale + // Note that the effective min power will be computed at the end of the epoch + minPowerToOptIn, err = k.ComputeMinPowerInTopN(ctx, activeValidators, topN) + if err != nil { + return false, err } } - // if the validator is opted in and belongs to the validators of the next epoch, then if nothing changes + // if the validator belongs to the validators of the next epoch, then if nothing changes // the validator would have to validate in the next epoch - if k.IsOptedIn(ctx, consumerId, provAddr) { - lastVals, err := k.GetLastBondedValidators(ctx) - if err != nil { - return false, err - } - nextValidators := k.ComputeNextValidators(ctx, consumerId, lastVals) - for _, v := range nextValidators { - consAddr := sdk.ConsAddress(v.ProviderConsAddr) - if provAddr.ToSdkConsAddr().Equals(consAddr) { - return true, nil - } + lastVals, err := k.GetLastBondedValidators(ctx) + if err != nil { + return false, err + } + nextValidators := k.ComputeNextValidators(ctx, consumerId, lastVals, minPowerToOptIn) + for _, v := range nextValidators { + consAddr := sdk.ConsAddress(v.ProviderConsAddr) + if provAddr.ToSdkConsAddr().Equals(consAddr) { + return true, nil } } diff --git a/x/ccv/provider/keeper/grpc_query_test.go b/x/ccv/provider/keeper/grpc_query_test.go index f0359b5ff6..352a56c225 100644 --- a/x/ccv/provider/keeper/grpc_query_test.go +++ b/x/ccv/provider/keeper/grpc_query_test.go @@ -84,7 +84,7 @@ func TestQueryConsumerChainOptedInValidators(t *testing.T) { require.Error(t, err) pk.FetchAndIncrementConsumerId(ctx) - pk.SetConsumerPhase(ctx, consumerId, keeper.Initialized) + pk.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) providerAddr1 := types.NewProviderConsAddress([]byte("providerAddr1")) providerAddr2 := types.NewProviderConsAddress([]byte("providerAddr2")) @@ -254,7 +254,7 @@ func TestQueryValidatorConsumerCommissionRate(t *testing.T) { require.Error(t, err) pk.FetchAndIncrementConsumerId(ctx) - pk.SetConsumerPhase(ctx, consumerId, keeper.Initialized) + pk.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // validator with set consumer commission rate expectedCommissionRate := math.LegacyMustNewDecFromStr("0.123") @@ -360,8 +360,9 @@ func TestGetConsumerChain(t *testing.T) { metadataLists[i] = types.ConsumerMetadata{Name: chainID} pk.SetConsumerMetadata(ctx, consumerId, metadataLists[i]) - phase := uint32(i) - pk.SetConsumerPhase(ctx, consumerId, keeper.ConsumerPhase(byte(phase))) + phase := int32(i) + + pk.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase(phase)) expectedGetAllOrder = append(expectedGetAllOrder, types.Chain{ @@ -373,7 +374,7 @@ func TestGetConsumerChain(t *testing.T) { ValidatorsPowerCap: validatorPowerCaps[i], Allowlist: strAllowlist, Denylist: strDenylist, - Phase: uint32(i), + Phase: types.ConsumerPhase(i), Metadata: metadataLists[i], }) } @@ -405,7 +406,7 @@ func TestQueryConsumerChains(t *testing.T) { pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - consumerNum := 5 + consumerNum := 4 consumerIds := make([]string, consumerNum) consumers := make([]*types.Chain, consumerNum) @@ -414,7 +415,7 @@ func TestQueryConsumerChains(t *testing.T) { require.NoError(t, err) require.Len(t, res.Chains, 0) - // create five consumer chains in different phase + // create four consumer chains in different phase for i := 0; i < consumerNum; i++ { cID := pk.FetchAndIncrementConsumerId(ctx) chainID := "consumer-" + strconv.Itoa(i) @@ -425,10 +426,10 @@ func TestQueryConsumerChains(t *testing.T) { ValidatorSetCap: 0, Allowlist: []string{}, Denylist: []string{}, - Phase: uint32(i), + Phase: types.ConsumerPhase(i + 1), Metadata: types.ConsumerMetadata{Name: chainID}, } - pk.SetConsumerPhase(ctx, cID, keeper.ConsumerPhase(c.Phase)) + pk.SetConsumerPhase(ctx, cID, types.ConsumerPhase(c.Phase)) pk.SetConsumerMetadata(ctx, cID, c.Metadata) pk.SetConsumerChainId(ctx, cID, chainID) @@ -440,8 +441,8 @@ func TestQueryConsumerChains(t *testing.T) { name string setup func(ctx sdk.Context, pk keeper.Keeper) filter_by_phase bool - phase_filter keeper.ConsumerPhase - limit uint32 + phase_filter types.ConsumerPhase + limit int32 expConsumers []*types.Chain }{ { @@ -453,61 +454,51 @@ func TestQueryConsumerChains(t *testing.T) { name: "expect an amount of consumer equal to the limit", setup: func(ctx sdk.Context, pk keeper.Keeper) {}, expConsumers: consumers[:3], - limit: uint32(3), + limit: int32(3), }, { name: "expect registered consumers when phase filter is set to Registered", setup: func(ctx sdk.Context, pk keeper.Keeper) { - consumers[0].Phase = uint32(keeper.Registered) - pk.SetConsumerPhase(ctx, consumerIds[0], keeper.Registered) + consumers[0].Phase = types.ConsumerPhase_CONSUMER_PHASE_REGISTERED + pk.SetConsumerPhase(ctx, consumerIds[0], types.ConsumerPhase_CONSUMER_PHASE_REGISTERED) }, filter_by_phase: true, - phase_filter: keeper.Registered, + phase_filter: types.ConsumerPhase_CONSUMER_PHASE_REGISTERED, expConsumers: consumers[0:1], }, { name: "expect initialized consumers when phase is set to Initialized", setup: func(ctx sdk.Context, pk keeper.Keeper) { - consumers[1].Phase = uint32(keeper.Initialized) - err := pk.AppendSpawnTimeForConsumerToBeLaunched(ctx, consumerIds[1], time.Now()) + consumers[1].Phase = types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED + err := pk.AppendConsumerToBeLaunchedOnSpawnTime(ctx, consumerIds[1], time.Now()) require.NoError(t, err) - pk.SetConsumerPhase(ctx, consumerIds[1], keeper.Initialized) + pk.SetConsumerPhase(ctx, consumerIds[1], types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) }, filter_by_phase: true, - phase_filter: keeper.Initialized, + phase_filter: types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED, expConsumers: consumers[1:2], }, - { - name: "expect consumers that failed to launch when phase is set to FailToLaunch", - setup: func(ctx sdk.Context, pk keeper.Keeper) { - consumers[2].Phase = uint32(keeper.FailedToLaunch) - pk.SetConsumerPhase(ctx, consumerIds[2], keeper.FailedToLaunch) - }, - filter_by_phase: true, - phase_filter: keeper.FailedToLaunch, - expConsumers: consumers[2:3], - }, { name: "expect launched consumers when phase is set to Launched", setup: func(ctx sdk.Context, pk keeper.Keeper) { - consumers[3].Phase = uint32(keeper.Launched) - consumers[3].ClientId = "ClientID" - pk.SetConsumerClientId(ctx, consumerIds[3], consumers[3].ClientId) - pk.SetConsumerPhase(ctx, consumerIds[3], keeper.Launched) + consumers[2].Phase = types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED + consumers[2].ClientId = "ClientID" + pk.SetConsumerClientId(ctx, consumerIds[2], consumers[2].ClientId) + pk.SetConsumerPhase(ctx, consumerIds[2], types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) }, filter_by_phase: true, - phase_filter: keeper.Launched, - expConsumers: consumers[3:4], + phase_filter: types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED, + expConsumers: consumers[2:3], }, { name: "expect stopped consumers when phase is set to Stopped", setup: func(ctx sdk.Context, pk keeper.Keeper) { - consumers[4].Phase = uint32(keeper.Stopped) - pk.SetConsumerPhase(ctx, consumerIds[4], keeper.Stopped) + consumers[3].Phase = types.ConsumerPhase_CONSUMER_PHASE_STOPPED + pk.SetConsumerPhase(ctx, consumerIds[3], types.ConsumerPhase_CONSUMER_PHASE_STOPPED) }, filter_by_phase: true, - phase_filter: keeper.Stopped, - expConsumers: consumers[4:], + phase_filter: types.ConsumerPhase_CONSUMER_PHASE_STOPPED, + expConsumers: consumers[3:], }, } @@ -516,7 +507,7 @@ func TestQueryConsumerChains(t *testing.T) { tc.setup(ctx, pk) req := types.QueryConsumerChainsRequest{ FilterByPhase: tc.filter_by_phase, - Phase: uint32(tc.phase_filter), + Phase: tc.phase_filter, Limit: tc.limit, } expectedResponse := types.QueryConsumerChainsResponse{ diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index 841db8330e..efcbd8a721 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -2,8 +2,9 @@ package keeper import ( "context" - "cosmossdk.io/math" "fmt" + + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkgov "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -115,44 +116,19 @@ func (h Hooks) AfterProposalSubmission(goCtx context.Context, proposalId uint64) return fmt.Errorf("cannot retrieve proposal with id: %d", proposalId) } - hasUpdateConsumerMsg := false - for _, msg := range p.GetMessages() { - sdkMsg, isMsgUpdateConsumer := msg.GetCachedValue().(*providertypes.MsgUpdateConsumer) - if isMsgUpdateConsumer { - // A `MsgUpdateConsumer` can only succeed if the owner of the consumer chain is the gov module. - // If that's not the case, we immediately fail the proposal. - // Note that someone could potentially change the owner of a chain to be that of the gov module - // while a proposal is active and before the proposal is executed. Even then, we still do not allow - // `MsgUpdateConsumer` proposals if the owner of the chain is not the gov module to avoid someone forgetting - // to change the owner address while the proposal is active. - ownerAddress, err := h.k.GetConsumerOwnerAddress(ctx, sdkMsg.ConsumerId) - if err != nil { - return fmt.Errorf("cannot find owner address for consumer with consumer id (%s): %s", sdkMsg.ConsumerId, err.Error()) - } else if ownerAddress != h.k.GetAuthority() { - return fmt.Errorf("owner address (%s) is not the gov module (%s)", ownerAddress, h.k.GetAuthority()) - } - - if hasUpdateConsumerMsg { - return fmt.Errorf("proposal can contain at most one `MsgUpdateConsumer` message") - } - hasUpdateConsumerMsg = true - h.k.SetProposalIdToConsumerId(ctx, proposalId, sdkMsg.ConsumerId) - } + err = DoesNotHaveDeprecatedMessage(&p) + if err != nil { + return err + } - // if the proposal contains a deprecated message, cancel the proposal - _, isMsgConsumerAddition := msg.GetCachedValue().(*providertypes.MsgConsumerAddition) - if isMsgConsumerAddition { - return fmt.Errorf("proposal cannot contain deprecated `MsgConsumerAddition`; use `MsgCreateConsumer` instead") - } + msgUpdateConsumer, err := h.k.HasAtMostOnceCorrectMsgUpdateConsumer(ctx, &p) + if err != nil { + return err + } - _, isMsgConsumerModification := msg.GetCachedValue().(*providertypes.MsgConsumerModification) - if isMsgConsumerModification { - return fmt.Errorf("proposal cannot contain deprecated `MsgConsumerModification`; use `MsgUpdateConsumer` instead") - } - _, isMsgConsumerRemoval := msg.GetCachedValue().(*providertypes.MsgConsumerRemoval) - if isMsgConsumerRemoval { - return fmt.Errorf("proposal cannot contain deprecated `MsgConsumerRemoval`; use `MsgRemoveConsumer` instead") - } + if msgUpdateConsumer != nil { + // a correctly set `MsgUpdateConsumer` was found + h.k.SetProposalIdToConsumerId(ctx, proposalId, msgUpdateConsumer.ConsumerId) } return nil diff --git a/x/ccv/provider/keeper/hooks_test.go b/x/ccv/provider/keeper/hooks_test.go index 8f7f90c948..bc6450923f 100644 --- a/x/ccv/provider/keeper/hooks_test.go +++ b/x/ccv/provider/keeper/hooks_test.go @@ -1,12 +1,14 @@ package keeper_test import ( + "testing" + sdk "github.com/cosmos/cosmos-sdk/types" cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "github.com/golang/mock/gomock" - "testing" ) func TestValidatorConsensusKeyInUse(t *testing.T) { @@ -30,7 +32,7 @@ func TestValidatorConsensusKeyInUse(t *testing.T) { name: "in use by another validator", setup: func(ctx sdk.Context, k providerkeeper.Keeper) { k.FetchAndIncrementConsumerId(ctx) - k.SetConsumerPhase(ctx, "0", providerkeeper.Initialized) + k.SetConsumerPhase(ctx, "0", types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // We are trying to add a new validator, but its address has already been used // by another validator @@ -47,8 +49,8 @@ func TestValidatorConsensusKeyInUse(t *testing.T) { setup: func(ctx sdk.Context, k providerkeeper.Keeper) { k.FetchAndIncrementConsumerId(ctx) k.FetchAndIncrementConsumerId(ctx) - k.SetConsumerPhase(ctx, "0", providerkeeper.Initialized) - k.SetConsumerPhase(ctx, "1", providerkeeper.Initialized) + k.SetConsumerPhase(ctx, "0", types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + k.SetConsumerPhase(ctx, "1", types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // We are trying to add a new validator, but its address has already been used // by another validator, of which there are several, across potentially several chains diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index 66df230b09..318fb7c90c 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -752,8 +752,10 @@ func (k Keeper) GetAllActiveConsumerIds(ctx sdk.Context) []string { consumerIds := []string{} for i := uint64(0); i < latestConsumerId; i++ { consumerId := fmt.Sprintf("%d", i) - phase, foundPhase := k.GetConsumerPhase(ctx, consumerId) - if !foundPhase || (phase != Registered && phase != Initialized && phase != Launched) { + phase := k.GetConsumerPhase(ctx, consumerId) + if phase != types.ConsumerPhase_CONSUMER_PHASE_REGISTERED && + phase != types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED && + phase != types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED { continue } consumerIds = append(consumerIds, consumerId) diff --git a/x/ccv/provider/keeper/key_assignment.go b/x/ccv/provider/keeper/key_assignment.go index 2e3846feb4..c01a061266 100644 --- a/x/ccv/provider/keeper/key_assignment.go +++ b/x/ccv/provider/keeper/key_assignment.go @@ -403,12 +403,14 @@ func (k Keeper) AssignConsumerKey( validator stakingtypes.Validator, consumerKey tmprotocrypto.PublicKey, ) error { - phase, found := k.GetConsumerPhase(ctx, consumerId) - if !found || phase == Stopped { - //check that the consumer chain is either registered, initialized, or launched + phase := k.GetConsumerPhase(ctx, consumerId) + if phase != types.ConsumerPhase_CONSUMER_PHASE_REGISTERED && + phase != types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED && + phase != types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED { + // check that the consumer chain is either registered, initialized, or launched return errorsmod.Wrapf( - types.ErrUnknownConsumerId, consumerId, - ) + types.ErrInvalidPhase, + "cannot assign a key to a consumer chain that is not in the registered, initialized, or launched phase: %s", consumerId) } consAddrTmp, err := ccvtypes.TMCryptoPublicKeyToConsAddr(consumerKey) @@ -460,7 +462,7 @@ func (k Keeper) AssignConsumerKey( oldConsumerAddr := types.NewConsumerConsAddress(oldConsumerAddrTmp) // check whether the consumer chain has already launched (i.e., a client to the consumer was already created) - if phase == Launched { + if phase == types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED { // mark the old consumer address as prunable once UnbondingPeriod elapses; // note: this state is removed on EndBlock unbondingPeriod, err := k.stakingKeeper.UnbondingTime(ctx) diff --git a/x/ccv/provider/keeper/key_assignment_test.go b/x/ccv/provider/keeper/key_assignment_test.go index 290b8a6048..9779b727ca 100644 --- a/x/ccv/provider/keeper/key_assignment_test.go +++ b/x/ccv/provider/keeper/key_assignment_test.go @@ -393,7 +393,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(ctx, consumerId, providerkeeper.Launched) + k.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) err := k.AssignConsumerKey(ctx, consumerId, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -420,7 +420,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(sdkCtx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(sdkCtx, consumerId, providerkeeper.Launched) + k.SetConsumerPhase(sdkCtx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) err := k.AssignConsumerKey(sdkCtx, consumerId, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -450,7 +450,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(ctx, consumerId, providerkeeper.Launched) + k.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) err := k.AssignConsumerKey(ctx, consumerId, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -477,7 +477,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(ctx, consumerId, providerkeeper.Launched) + k.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) err := k.AssignConsumerKey(ctx, consumerId, providerIdentities[1].SDKStakingValidator(), providerIdentities[0].TMProtoCryptoPublicKey(), @@ -495,7 +495,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(ctx, consumerId, providerkeeper.Initialized) + k.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) err := k.AssignConsumerKey(ctx, consumerId, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -520,7 +520,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(ctx, consumerId, providerkeeper.Initialized) + k.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) err := k.AssignConsumerKey(ctx, consumerId, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -550,7 +550,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(ctx, consumerId, providerkeeper.Initialized) + k.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) err := k.AssignConsumerKey(ctx, consumerId, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -577,7 +577,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerPhase(ctx, consumerId, providerkeeper.Initialized) + k.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) err := k.AssignConsumerKey(ctx, consumerId, providerIdentities[1].SDKStakingValidator(), providerIdentities[0].TMProtoCryptoPublicKey(), @@ -613,7 +613,7 @@ func TestCannotReassignDefaultKeyAssignment(t *testing.T) { providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - providerKeeper.SetConsumerPhase(ctx, "consumerId", providerkeeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, "consumerId", types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // Mock that the validator is validating with the single key, as confirmed by provider's staking keeper gomock.InOrder( diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index 9550b7d620..28e0ef24ba 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -2,8 +2,11 @@ package keeper import ( "context" - errorsmod "cosmossdk.io/errors" "fmt" + "strings" + "time" + + errorsmod "cosmossdk.io/errors" tmtypes "github.com/cometbft/cometbft/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,8 +14,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" - "strings" - "time" ) type msgServer struct { @@ -87,30 +88,32 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign } // RemoveConsumer defines an RPC handler method for MsgRemoveConsumer -func (k msgServer) RemoveConsumer( - goCtx context.Context, - msg *types.MsgRemoveConsumer) (*types.MsgRemoveConsumerResponse, error) { - if k.GetAuthority() != msg.Authority { - return nil, errorsmod.Wrapf(types.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Authority) - } - +func (k msgServer) RemoveConsumer(goCtx context.Context, msg *types.MsgRemoveConsumer) (*types.MsgRemoveConsumerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) consumerId := msg.ConsumerId + ownerAddress, err := k.Keeper.GetConsumerOwnerAddress(ctx, consumerId) + if err != nil { + return &types.MsgRemoveConsumerResponse{}, errorsmod.Wrapf(types.ErrNoOwnerAddress, "cannot retrieve owner address %s", ownerAddress) + } + + if msg.Signer != ownerAddress { + return &types.MsgRemoveConsumerResponse{}, errorsmod.Wrapf(types.ErrUnauthorized, "expected owner address %s, got %s", ownerAddress, msg.Signer) + } - phase, found := k.Keeper.GetConsumerPhase(ctx, consumerId) - if !found || phase != Launched { + phase := k.Keeper.GetConsumerPhase(ctx, consumerId) + if phase != types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED { return nil, errorsmod.Wrapf(types.ErrInvalidPhase, "chain with consumer id: %s has to be in its launched phase", consumerId) } previousStopTime, err := k.Keeper.GetConsumerStopTime(ctx, consumerId) if err == nil { - k.Keeper.RemoveConsumerFromToBeStoppedConsumers(ctx, consumerId, previousStopTime) + k.Keeper.RemoveConsumerToBeStoppedFromStopTime(ctx, consumerId, previousStopTime) } k.Keeper.SetConsumerStopTime(ctx, consumerId, msg.StopTime) - k.Keeper.AppendStopTimeForConsumerToBeStopped(ctx, consumerId, msg.StopTime) + k.Keeper.AppendConsumerToBeStoppedOnStopTime(ctx, consumerId, msg.StopTime) return &types.MsgRemoveConsumerResponse{}, nil } @@ -309,20 +312,20 @@ func (k msgServer) SetConsumerCommissionRate(goCtx context.Context, msg *types.M func (k msgServer) CreateConsumer(goCtx context.Context, msg *types.MsgCreateConsumer) (*types.MsgCreateConsumerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - consumerId := k.FetchAndIncrementConsumerId(ctx) + consumerId := k.Keeper.FetchAndIncrementConsumerId(ctx) - k.SetConsumerOwnerAddress(ctx, consumerId, msg.Signer) - k.SetConsumerChainId(ctx, consumerId, msg.ChainId) - k.SetConsumerPhase(ctx, consumerId, Registered) + k.Keeper.SetConsumerOwnerAddress(ctx, consumerId, msg.Signer) + k.Keeper.SetConsumerChainId(ctx, consumerId, msg.ChainId) + k.Keeper.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_REGISTERED) - if err := k.SetConsumerMetadata(ctx, consumerId, msg.Metadata); err != nil { + if err := k.Keeper.SetConsumerMetadata(ctx, consumerId, msg.Metadata); err != nil { return &types.MsgCreateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidConsumerMetadata, "cannot set consumer metadata: %s", err.Error()) } // initialization parameters are optional and hence could be nil if msg.InitializationParameters != nil { - if err := k.SetConsumerInitializationParameters(ctx, consumerId, *msg.InitializationParameters); err != nil { + if err := k.Keeper.SetConsumerInitializationParameters(ctx, consumerId, *msg.InitializationParameters); err != nil { return &types.MsgCreateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidConsumerInitializationParameters, "cannot set consumer initialization parameters: %s", err.Error()) } @@ -334,15 +337,18 @@ func (k msgServer) CreateConsumer(goCtx context.Context, msg *types.MsgCreateCon return &types.MsgCreateConsumerResponse{}, errorsmod.Wrap(types.ErrCannotCreateTopNChain, "cannot create a Top N chain using the `MsgCreateConsumer` message; use `MsgUpdateConsumer` instead") } - if err := k.SetConsumerPowerShapingParameters(ctx, consumerId, *msg.PowerShapingParameters); err != nil { + if err := k.Keeper.SetConsumerPowerShapingParameters(ctx, consumerId, *msg.PowerShapingParameters); err != nil { return &types.MsgCreateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidPowerShapingParameters, "cannot set power shaping parameters") } } - if spawnTime, canLaunch := k.CanLaunch(ctx, consumerId); canLaunch { - k.SetConsumerPhase(ctx, consumerId, Initialized) - k.PrepareConsumerForLaunch(ctx, consumerId, time.Time{}, spawnTime) + if spawnTime, canLaunch := k.Keeper.CanLaunch(ctx, consumerId); canLaunch { + k.Keeper.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + if err := k.Keeper.PrepareConsumerForLaunch(ctx, consumerId, time.Time{}, spawnTime); err != nil { + return &types.MsgCreateConsumerResponse{}, errorsmod.Wrapf(types.ErrCannotPrepareForLaunch, + "cannot prepare chain with consumer id (%s) for launch", consumerId) + } } return &types.MsgCreateConsumerResponse{ConsumerId: consumerId}, nil @@ -353,18 +359,12 @@ func (k msgServer) UpdateConsumer(goCtx context.Context, msg *types.MsgUpdateCon ctx := sdk.UnwrapSDKContext(goCtx) consumerId := msg.ConsumerId - phase, found := k.GetConsumerPhase(ctx, consumerId) - if found && phase == Stopped { + phase := k.Keeper.GetConsumerPhase(ctx, consumerId) + if phase != types.ConsumerPhase_CONSUMER_PHASE_REGISTERED && + phase != types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED && + phase != types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED { return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidPhase, - "cannot update consumer chain that is in the stopped phase: %s", consumerId) - } - - // The new owner address can be empty, in which case the consumer chain does not change its owner. - // However, if the new owner address is not empty, we verify that it's a valid account address. - if strings.TrimSpace(msg.NewOwnerAddress) != "" { - if _, err := k.accountKeeper.AddressCodec().StringToBytes(msg.NewOwnerAddress); err != nil { - return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidNewOwnerAddress, "invalid new owner address %s", msg.NewOwnerAddress) - } + "cannot update consumer chain that is not in the registered, initialized, or launched phase: %s", consumerId) } ownerAddress, err := k.Keeper.GetConsumerOwnerAddress(ctx, consumerId) @@ -376,12 +376,18 @@ func (k msgServer) UpdateConsumer(goCtx context.Context, msg *types.MsgUpdateCon return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrUnauthorized, "expected owner address %s, got %s", ownerAddress, msg.Signer) } + // The new owner address can be empty, in which case the consumer chain does not change its owner. + // However, if the new owner address is not empty, we verify that it's a valid account address. if strings.TrimSpace(msg.NewOwnerAddress) != "" { + if _, err := k.accountKeeper.AddressCodec().StringToBytes(msg.NewOwnerAddress); err != nil { + return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidNewOwnerAddress, "invalid new owner address %s", msg.NewOwnerAddress) + } + k.Keeper.SetConsumerOwnerAddress(ctx, consumerId, msg.NewOwnerAddress) } if msg.Metadata != nil { - if err := k.SetConsumerMetadata(ctx, consumerId, *msg.Metadata); err != nil { + if err := k.Keeper.SetConsumerMetadata(ctx, consumerId, *msg.Metadata); err != nil { return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidConsumerMetadata, "cannot set consumer metadata: %s", err.Error()) } @@ -389,7 +395,8 @@ func (k msgServer) UpdateConsumer(goCtx context.Context, msg *types.MsgUpdateCon // get the previous spawn time so that we can use it in `PrepareConsumerForLaunch` var previousSpawnTime time.Time - if previousInitializationParameters, err := k.Keeper.GetConsumerInitializationParameters(ctx, msg.ConsumerId); err != nil { + previousInitializationParameters, err := k.Keeper.GetConsumerInitializationParameters(ctx, msg.ConsumerId) + if err == nil { previousSpawnTime = previousInitializationParameters.SpawnTime } @@ -410,7 +417,7 @@ func (k msgServer) UpdateConsumer(goCtx context.Context, msg *types.MsgUpdateCon } oldTopN := k.Keeper.GetTopN(ctx, consumerId) - if err = k.SetConsumerPowerShapingParameters(ctx, consumerId, *msg.PowerShapingParameters); err != nil { + if err = k.Keeper.SetConsumerPowerShapingParameters(ctx, consumerId, *msg.PowerShapingParameters); err != nil { return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidPowerShapingParameters, "cannot set power shaping parameters") } @@ -426,12 +433,12 @@ func (k msgServer) UpdateConsumer(goCtx context.Context, msg *types.MsgUpdateCon // A Top N cannot change its owner address to something different from the gov module if the chain // remains a Top N chain. - currentOwnerAddress, err := k.GetConsumerOwnerAddress(ctx, consumerId) + currentOwnerAddress, err := k.Keeper.GetConsumerOwnerAddress(ctx, consumerId) if err != nil { return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrNoOwnerAddress, "cannot retrieve owner address %s: %s", ownerAddress, err.Error()) } - currentPowerShapingParameters, err := k.GetConsumerPowerShapingParameters(ctx, consumerId) + currentPowerShapingParameters, err := k.Keeper.GetConsumerPowerShapingParameters(ctx, consumerId) if err != nil { return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrInvalidPowerShapingParameters, "cannot retrieve power shaping parameters: %s", err.Error()) } @@ -441,9 +448,12 @@ func (k msgServer) UpdateConsumer(goCtx context.Context, msg *types.MsgUpdateCon "a move to a new owner address that is not the gov module can only be done if `Top N` is set to 0") } - if spawnTime, canLaunch := k.CanLaunch(ctx, consumerId); canLaunch { - k.SetConsumerPhase(ctx, consumerId, Initialized) - k.PrepareConsumerForLaunch(ctx, consumerId, previousSpawnTime, spawnTime) + if spawnTime, canLaunch := k.Keeper.CanLaunch(ctx, consumerId); canLaunch { + k.Keeper.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + if err := k.Keeper.PrepareConsumerForLaunch(ctx, consumerId, previousSpawnTime, spawnTime); err != nil { + return &types.MsgUpdateConsumerResponse{}, errorsmod.Wrapf(types.ErrCannotPrepareForLaunch, + "cannot prepare chain with consumer id (%s) for launch", consumerId) + } } return &types.MsgUpdateConsumerResponse{}, nil diff --git a/x/ccv/provider/keeper/msg_server_test.go b/x/ccv/provider/keeper/msg_server_test.go index 9dcf3942fe..fd353e38bf 100644 --- a/x/ccv/provider/keeper/msg_server_test.go +++ b/x/ccv/provider/keeper/msg_server_test.go @@ -1,11 +1,14 @@ package keeper_test import ( + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/codec/address" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "github.com/stretchr/testify/require" - "testing" ) func TestCreateConsumer(t *testing.T) { @@ -29,9 +32,8 @@ func TestCreateConsumer(t *testing.T) { require.Equal(t, consumerMetadata, actualMetadata) ownerAddress, err := providerKeeper.GetConsumerOwnerAddress(ctx, "0") require.Equal(t, "signer", ownerAddress) - phase, found := providerKeeper.GetConsumerPhase(ctx, "0") - require.True(t, found) - require.Equal(t, providerkeeper.Registered, phase) + phase := providerKeeper.GetConsumerPhase(ctx, "0") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_REGISTERED, phase) consumerMetadata = providertypes.ConsumerMetadata{ Name: "chain name", @@ -49,7 +51,114 @@ func TestCreateConsumer(t *testing.T) { require.Equal(t, consumerMetadata, actualMetadata) ownerAddress, err = providerKeeper.GetConsumerOwnerAddress(ctx, "1") require.Equal(t, "signer2", ownerAddress) - phase, found = providerKeeper.GetConsumerPhase(ctx, "1") - require.True(t, found) - require.Equal(t, providerkeeper.Registered, phase) + phase = providerKeeper.GetConsumerPhase(ctx, "1") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_REGISTERED, phase) +} + +func TestUpdateConsumer(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + msgServer := providerkeeper.NewMsgServerImpl(&providerKeeper) + + // try to update a non-existing (i.e., no consumer id exists) + _, err := msgServer.UpdateConsumer(ctx, + &providertypes.MsgUpdateConsumer{Signer: "signer", ConsumerId: "0", NewOwnerAddress: "cosmos1dkas8mu4kyhl5jrh4nzvm65qz588hy9qcz08la", + Metadata: nil, + InitializationParameters: nil, + PowerShapingParameters: nil, + }) + require.Error(t, err, "cannot update consumer chain") + + // create a chain before updating it + createConsumerResponse, err := msgServer.CreateConsumer(ctx, + &providertypes.MsgCreateConsumer{Signer: "signer", ChainId: "chainId", + Metadata: providertypes.ConsumerMetadata{ + Name: "name", + Description: "description", + Metadata: "metadata", + }, + InitializationParameters: nil, + PowerShapingParameters: nil, + }) + require.NoError(t, err) + consumerId := createConsumerResponse.ConsumerId + + mocks.MockAccountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() + _, err = msgServer.UpdateConsumer(ctx, + &providertypes.MsgUpdateConsumer{Signer: "wrong signer", ConsumerId: consumerId, NewOwnerAddress: "cosmos1dkas8mu4kyhl5jrh4nzvm65qz588hy9qcz08la", + Metadata: nil, + InitializationParameters: nil, + PowerShapingParameters: nil, + }) + require.Error(t, err, "expected owner address") + + expectedConsumerMetadata := providertypes.ConsumerMetadata{ + Name: "name2", + Description: "description2", + Metadata: "metadata2", + } + + expectedInitializationParameters := testkeeper.GetTestInitializationParameters() + expectedPowerShapingParameters := testkeeper.GetTestPowerShapingParameters() + + expectedOwnerAddress := "cosmos1dkas8mu4kyhl5jrh4nzvm65qz588hy9qcz08la" + _, err = msgServer.UpdateConsumer(ctx, + &providertypes.MsgUpdateConsumer{Signer: "signer", ConsumerId: consumerId, NewOwnerAddress: expectedOwnerAddress, + Metadata: &expectedConsumerMetadata, + InitializationParameters: &expectedInitializationParameters, + PowerShapingParameters: &expectedPowerShapingParameters}) + require.NoError(t, err) + + // assert that owner address was updated + ownerAddress, err := providerKeeper.GetConsumerOwnerAddress(ctx, consumerId) + require.NoError(t, err) + require.Equal(t, expectedOwnerAddress, ownerAddress) + + // assert that consumer metadata were updated + actualConsumerMetadata, err := providerKeeper.GetConsumerMetadata(ctx, consumerId) + require.NoError(t, err) + require.Equal(t, expectedConsumerMetadata, actualConsumerMetadata) + + // assert that initialization parameters were updated + actualInitializationParameters, err := providerKeeper.GetConsumerInitializationParameters(ctx, consumerId) + require.NoError(t, err) + require.Equal(t, expectedInitializationParameters, actualInitializationParameters) + + // assert that power-shaping parameters were updated + actualPowerShapingParameters, err := providerKeeper.GetConsumerPowerShapingParameters(ctx, consumerId) + require.NoError(t, err) + require.Equal(t, expectedPowerShapingParameters, actualPowerShapingParameters) + + // assert phase + phase := providerKeeper.GetConsumerPhase(ctx, consumerId) + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED, phase) + + // assert that chain is set to launch + consumerIds, err := providerKeeper.GetConsumersToBeLaunched(ctx, expectedInitializationParameters.SpawnTime) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{ + Ids: []string{consumerId}, + }, consumerIds) + + // re-update (change spawnTime) and verify that the chain is still to be launched at the new spawn time + previousSpawnTime := expectedInitializationParameters.SpawnTime + updatedSpawnTime := expectedInitializationParameters.SpawnTime.Add(time.Hour) + expectedInitializationParameters.SpawnTime = updatedSpawnTime + _, err = msgServer.UpdateConsumer(ctx, + &providertypes.MsgUpdateConsumer{Signer: expectedOwnerAddress, ConsumerId: consumerId, + Metadata: &expectedConsumerMetadata, + InitializationParameters: &expectedInitializationParameters, + PowerShapingParameters: &expectedPowerShapingParameters}) + require.NoError(t, err) + + consumerIds, err = providerKeeper.GetConsumersToBeLaunched(ctx, previousSpawnTime) + require.NoError(t, err) + require.Empty(t, consumerIds) + + consumerIds, err = providerKeeper.GetConsumersToBeLaunched(ctx, updatedSpawnTime) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{ + Ids: []string{consumerId}, + }, consumerIds) } diff --git a/x/ccv/provider/keeper/partial_set_security.go b/x/ccv/provider/keeper/partial_set_security.go index 305f0f358b..2a3152a27d 100644 --- a/x/ccv/provider/keeper/partial_set_security.go +++ b/x/ccv/provider/keeper/partial_set_security.go @@ -16,11 +16,13 @@ import ( // HandleOptIn prepares validator `providerAddr` to opt in to `consumerId` 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, consumerId string, providerAddr types.ProviderConsAddress, consumerKey string) error { - phase, found := k.GetConsumerPhase(ctx, consumerId) - if !found || phase == Stopped { + phase := k.GetConsumerPhase(ctx, consumerId) + if phase != types.ConsumerPhase_CONSUMER_PHASE_REGISTERED && + phase != types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED && + phase != types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED { return errorsmod.Wrapf( types.ErrInvalidPhase, - "opting in to an unknown (or stopped) consumer chain, with id: %s", consumerId) + "cannot opt in to a consumer chain that is not in the registered, initialized, or launched phase: %s", consumerId) } chainId, err := k.GetConsumerChainId(ctx, consumerId) @@ -137,7 +139,6 @@ func (k Keeper) OptInTopNValidators(ctx sdk.Context, consumerId string, bondedVa // if validator already exists it gets overwritten k.SetOptedIn(ctx, consumerId, types.NewProviderConsAddress(consAddr)) - k.SetOptedIn(ctx, consumerId, types.NewProviderConsAddress(consAddr)) } // else validators that do not belong to the top N validators but were opted in, remain opted in } } @@ -322,9 +323,17 @@ func NoMoreThanPercentOfTheSum(validators []types.ConsensusValidator, percent ui // CanValidateChain returns true if the validator `providerAddr` is opted-in to chain with `consumerId` and the allowlist // and denylist do not prevent the validator from validating the chain. -func (k Keeper) CanValidateChain(ctx sdk.Context, consumerId string, providerAddr types.ProviderConsAddress) bool { +func (k Keeper) CanValidateChain(ctx sdk.Context, consumerId string, providerAddr types.ProviderConsAddress, minPowerToOptIn int64) bool { + // check if the validator is already opted-in + optedIn := k.IsOptedIn(ctx, consumerId, providerAddr) + + // check if the validator is automatically opted-in for a topN chain + if !optedIn && k.GetTopN(ctx, consumerId) > 0 { + optedIn = k.HasMinPower(ctx, providerAddr, minPowerToOptIn) + } + // only consider opted-in validators - return k.IsOptedIn(ctx, consumerId, providerAddr) && + return optedIn && // if an allowlist is declared, only consider allowlisted validators (k.IsAllowlistEmpty(ctx, consumerId) || k.IsAllowlisted(ctx, consumerId, providerAddr)) && @@ -352,7 +361,7 @@ func (k Keeper) FulfillsMinStake(ctx sdk.Context, consumerId string, providerAdd } // ComputeNextValidators computes the validators for the upcoming epoch based on the currently `bondedValidators`. -func (k Keeper) ComputeNextValidators(ctx sdk.Context, consumerId string, bondedValidators []stakingtypes.Validator) []types.ConsensusValidator { +func (k Keeper) ComputeNextValidators(ctx sdk.Context, consumerId string, bondedValidators []stakingtypes.Validator, minPowerToOptIn int64) []types.ConsensusValidator { // sort the bonded validators by number of staked tokens in descending order sort.Slice(bondedValidators, func(i, j int) bool { return bondedValidators[i].GetBondedTokens().GT(bondedValidators[j].GetBondedTokens()) @@ -371,9 +380,49 @@ func (k Keeper) ComputeNextValidators(ctx sdk.Context, consumerId string, bonded nextValidators := k.FilterValidators(ctx, consumerId, bondedValidators, func(providerAddr types.ProviderConsAddress) bool { - return k.CanValidateChain(ctx, consumerId, providerAddr) && k.FulfillsMinStake(ctx, consumerId, providerAddr) + return k.CanValidateChain(ctx, consumerId, providerAddr, minPowerToOptIn) && k.FulfillsMinStake(ctx, consumerId, providerAddr) }) nextValidators = k.CapValidatorSet(ctx, consumerId, nextValidators) return k.CapValidatorsPower(ctx, consumerId, nextValidators) } + +// HasMinPower returns true if the `providerAddr` voting power is GTE than the given minimum power +func (k Keeper) HasMinPower(ctx sdk.Context, providerAddr types.ProviderConsAddress, minPower int64) bool { + val, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.Address) + if err != nil { + k.Logger(ctx).Error( + "cannot get last validator power", + "provider address", + providerAddr, + "error", + err, + ) + return false + } + + valAddr, err := sdk.ValAddressFromBech32(val.GetOperator()) + if err != nil { + k.Logger(ctx).Error( + "could not retrieve validator address", + "operator address", + val.GetOperator(), + "error", + err, + ) + return false + } + + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + k.Logger(ctx).Error("could not retrieve last power of validator address", + "operator address", + val.GetOperator(), + "error", + err, + ) + return false + } + + return power >= minPower +} diff --git a/x/ccv/provider/keeper/partial_set_security_test.go b/x/ccv/provider/keeper/partial_set_security_test.go index c710e7f299..cbccfe7e9e 100644 --- a/x/ccv/provider/keeper/partial_set_security_test.go +++ b/x/ccv/provider/keeper/partial_set_security_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "bytes" + "fmt" "sort" "testing" @@ -36,10 +37,10 @@ func TestHandleOptIn(t *testing.T) { require.Error(t, providerKeeper.HandleOptIn(ctx, "unknownConsumerId", providerAddr, "")) // trying to opt in to a stopped consumer chain - providerKeeper.SetConsumerPhase(ctx, "stoppedConsumerId", keeper.Stopped) + providerKeeper.SetConsumerPhase(ctx, "stoppedConsumerId", types.ConsumerPhase_CONSUMER_PHASE_STOPPED) require.Error(t, providerKeeper.HandleOptIn(ctx, "stoppedConsumerId", providerAddr, "")) - providerKeeper.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, "consumerId", types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) providerKeeper.SetConsumerChainId(ctx, "consumerId", "chainId") require.False(t, providerKeeper.IsOptedIn(ctx, "consumerId", providerAddr)) err := providerKeeper.HandleOptIn(ctx, "consumerId", providerAddr, "") @@ -48,7 +49,7 @@ func TestHandleOptIn(t *testing.T) { // validator tries to opt in to another chain with chain id ("chainId") while it is already opted in to // a different chain with the same chain id - providerKeeper.SetConsumerPhase(ctx, "consumerId2", keeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, "consumerId2", types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) providerKeeper.SetConsumerChainId(ctx, "consumerId2", "chainId") err = providerKeeper.HandleOptIn(ctx, "consumerId2", providerAddr, "") require.ErrorContains(t, err, "validator is already opted in to a chain") @@ -88,7 +89,7 @@ func TestHandleOptInWithConsumerKey(t *testing.T) { expectedConsumerPubKey, err := providerKeeper.ParseConsumerKey(consumerKey) require.NoError(t, err) - providerKeeper.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, "consumerId", types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) providerKeeper.SetConsumerChainId(ctx, "consumerId", "consumerId") err = providerKeeper.HandleOptIn(ctx, "consumerId", providerAddr, consumerKey) require.NoError(t, err) @@ -197,7 +198,7 @@ func TestHandleSetConsumerCommissionRate(t *testing.T) { // setup a pending consumer chain consumerId := "0" providerKeeper.FetchAndIncrementConsumerId(ctx) - providerKeeper.SetConsumerPhase(ctx, consumerId, keeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) providerKeeper.SetPendingConsumerAdditionProp(ctx, &types.ConsumerAdditionProposal{ChainId: consumerId}) // check that there's no commission rate set for the validator yet @@ -384,29 +385,45 @@ 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) + consumerID := "0" + + validator := createStakingValidator(ctx, mocks, 0, 1, 1) // adds GetLastValidatorPower expectation to mocks 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, "consumerId", providerAddr)) - providerKeeper.SetOptedIn(ctx, "consumerId", types.NewProviderConsAddress(consAddr)) - require.True(t, providerKeeper.CanValidateChain(ctx, "consumerId", providerAddr)) + require.False(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 0)) + + // with TopN chains, the validator can be considered, + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(gomock.Any(), providerAddr.Address).Return(validator, nil).Times(2) + providerKeeper.SetConsumerPowerShapingParameters(ctx, consumerID, types.PowerShapingParameters{Top_N: 50}) + // validator's power is LT the min power + require.False(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 2)) + // validator's power is GTE the min power + require.True(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 1)) + + // when validator is opted-in it can validate regardless of its min power + providerKeeper.SetOptedIn(ctx, consumerID, types.NewProviderConsAddress(consAddr)) + require.True(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 2)) + + // With OptIn chains, validator can validate only if it has already opted-in + providerKeeper.SetConsumerPowerShapingParameters(ctx, consumerID, types.PowerShapingParameters{Top_N: 0}) + require.True(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 2)) // 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, "consumerId", types.NewProviderConsAddress(consAddrA)) - require.False(t, providerKeeper.CanValidateChain(ctx, "consumerId", providerAddr)) - providerKeeper.SetAllowlist(ctx, "consumerId", types.NewProviderConsAddress(consAddr)) - require.True(t, providerKeeper.CanValidateChain(ctx, "consumerId", providerAddr)) + providerKeeper.SetAllowlist(ctx, consumerID, types.NewProviderConsAddress(consAddrA)) + require.False(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 1)) + providerKeeper.SetAllowlist(ctx, consumerID, types.NewProviderConsAddress(consAddr)) + require.True(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 1)) // create a denylist but do not add validator `providerAddr` to it - providerKeeper.SetDenylist(ctx, "consumerId", types.NewProviderConsAddress(consAddrA)) - require.True(t, providerKeeper.CanValidateChain(ctx, "consumerId", providerAddr)) + providerKeeper.SetDenylist(ctx, consumerID, types.NewProviderConsAddress(consAddrA)) + require.True(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 1)) // add validator `providerAddr` to the denylist - providerKeeper.SetDenylist(ctx, "consumerId", types.NewProviderConsAddress(consAddr)) - require.False(t, providerKeeper.CanValidateChain(ctx, "consumerId", providerAddr)) + providerKeeper.SetDenylist(ctx, consumerID, types.NewProviderConsAddress(consAddr)) + require.False(t, providerKeeper.CanValidateChain(ctx, consumerID, providerAddr, 1)) } func TestCapValidatorSet(t *testing.T) { @@ -820,7 +837,7 @@ func TestIfInactiveValsDisallowedProperty(t *testing.T) { providerKeeper.SetParams(ctx, params) // Compute the next validators - nextVals := providerKeeper.ComputeNextValidators(ctx, "consumerId", vals) + nextVals := providerKeeper.ComputeNextValidators(ctx, "consumerId", vals, 0) // Check that the length of nextVals is at most maxProviderConsensusVals require.LessOrEqual(r, len(nextVals), int(maxProviderConsensusVals), "The length of nextVals should be at most maxProviderConsensusVals") @@ -843,3 +860,73 @@ func TestIfInactiveValsDisallowedProperty(t *testing.T) { } }) } + +func TestHasMinPower(t *testing.T) { + pk, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerConsPubKey := ed25519.GenPrivKeyFromSecret([]byte{1}).PubKey() + consAddr := sdk.ConsAddress(providerConsPubKey.Address()) + providerAddr := types.NewProviderConsAddress(consAddr) + + testCases := []struct { + name string + minPower uint64 + expectation func(sdk.ConsAddress, testkeeper.MockedKeepers) + hasMinPower bool + }{ + { + name: "cannot find validator by cons address", + expectation: func(sdk.ConsAddress, testkeeper.MockedKeepers) { + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(gomock.Any(), consAddr). + Return(stakingtypes.Validator{}, fmt.Errorf("validator not found")).Times(1) + }, + hasMinPower: false, + }, { + name: "cannot convert validator operator address", + expectation: func(consAddr sdk.ConsAddress, mocks testkeeper.MockedKeepers) { + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(gomock.Any(), consAddr).Return(stakingtypes.Validator{OperatorAddress: "xxxx"}, nil).Times(1) + }, + hasMinPower: false, + }, { + name: "cannot find last validator power", + expectation: func(consAddr sdk.ConsAddress, mocks testkeeper.MockedKeepers) { + valAddr := sdk.ValAddress(providerAddr.Address.Bytes()) + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(gomock.Any(), consAddr). + Return(stakingtypes.Validator{OperatorAddress: valAddr.String()}, nil) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), valAddr). + Return(int64(0), fmt.Errorf("last power not found")).Times(1) + }, + hasMinPower: false, + }, { + name: "validator power is LT min power", + expectation: func(consAddr sdk.ConsAddress, mocks testkeeper.MockedKeepers) { + valAddr := sdk.ValAddress(providerAddr.Address.Bytes()) + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(gomock.Any(), consAddr). + Return(stakingtypes.Validator{OperatorAddress: valAddr.String()}, nil) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), valAddr). + Return(int64(5), nil).Times(1) + }, + hasMinPower: false, + }, { + name: "validator power is GTE min power", + expectation: func(consAddr sdk.ConsAddress, mocks testkeeper.MockedKeepers) { + valAddr := sdk.ValAddress(providerAddr.Address.Bytes()) + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(gomock.Any(), consAddr). + Return(stakingtypes.Validator{OperatorAddress: valAddr.String()}, nil) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), valAddr). + Return(int64(10), nil).Times(1) + }, + hasMinPower: true, + }, + } + + minPower := int64(10) + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tc.expectation(consAddr, mocks) + require.Equal(t, tc.hasMinPower, pk.HasMinPower(ctx, providerAddr, minPower)) + }) + } +} diff --git a/x/ccv/provider/keeper/permissionless.go b/x/ccv/provider/keeper/permissionless.go index 4b209d0358..e77d152bd2 100644 --- a/x/ccv/provider/keeper/permissionless.go +++ b/x/ccv/provider/keeper/permissionless.go @@ -1,9 +1,7 @@ package keeper import ( - "bytes" "encoding/binary" - "encoding/gob" "fmt" "strconv" "time" @@ -11,29 +9,10 @@ import ( errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) -// ConsumerPhase captures the phases of a consumer chain according to `docs/docs/adrs/adr-018-permissionless-ics.md` -type ConsumerPhase byte - -const ( - // Registered phase indicates the phase in which a consumer chain has been assigned a unique consumer id. This consumer - // id can be used to interact with the consumer chain (e.g., when a validator opts in to a chain). A chain in this - // phase cannot yet launch. It has to be initialized first. - Registered ConsumerPhase = iota - // Initialized phase indicates the phase in which a consumer chain has set all the needed parameters to launch but - // has not yet launched (e.g., because the `spawnTime` of the consumer chain has not yet been reached). - Initialized - // FailedToLaunch phase indicates that the chain attempted but failed to launch (e.g., due to no validator opting in). - FailedToLaunch - // Launched phase corresponds to the phase in which a consumer chain is running and consuming a subset of the validator - // set of the provider. - Launched - // Stopped phase corresponds to the phase in which a previously-launched chain has stopped. - Stopped -) - // setConsumerId sets the provided consumerId func (k Keeper) setConsumerId(ctx sdk.Context, consumerId uint64) { store := ctx.KVStore(k.storeKey) @@ -44,7 +23,7 @@ func (k Keeper) setConsumerId(ctx sdk.Context, consumerId uint64) { store.Set(types.ConsumerIdKey(), buf) } -// GetConsumerId returns the last registered consumer id +// GetConsumerId returns the next to-be-assigned consumer id func (k Keeper) GetConsumerId(ctx sdk.Context) (uint64, bool) { store := ctx.KVStore(k.storeKey) buf := store.Get(types.ConsumerIdKey()) @@ -152,11 +131,11 @@ func (k Keeper) GetConsumerInitializationParameters(ctx sdk.Context, consumerId } // SetConsumerInitializationParameters sets the initialization parameters associated with this consumer id -func (k Keeper) SetConsumerInitializationParameters(ctx sdk.Context, consumerId string, record types.ConsumerInitializationParameters) error { +func (k Keeper) SetConsumerInitializationParameters(ctx sdk.Context, consumerId string, parameters types.ConsumerInitializationParameters) error { store := ctx.KVStore(k.storeKey) - bz, err := record.Marshal() + bz, err := parameters.Marshal() if err != nil { - return fmt.Errorf("failed to marshal initialization record (%+v) for consumer id (%s): %w", record, consumerId, err) + return fmt.Errorf("failed to marshal initialization parameters (%+v) for consumer id (%s): %w", parameters, consumerId, err) } store.Set(types.ConsumerIdToInitializationParametersKey(consumerId), bz) return nil @@ -200,20 +179,22 @@ func (k Keeper) DeleteConsumerPowerShapingParameters(ctx sdk.Context, consumerId } // GetConsumerPhase returns the phase associated with this consumer id -func (k Keeper) GetConsumerPhase(ctx sdk.Context, consumerId string) (ConsumerPhase, bool) { +func (k Keeper) GetConsumerPhase(ctx sdk.Context, consumerId string) types.ConsumerPhase { store := ctx.KVStore(k.storeKey) buf := store.Get(types.ConsumerIdToPhaseKey(consumerId)) if buf == nil { - return ConsumerPhase(0), false + return types.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED } - return ConsumerPhase(buf[0]), true + phase := types.ConsumerPhase(binary.BigEndian.Uint32(buf)) + return phase } // SetConsumerPhase sets the phase associated with this consumer id -// TODO (PERMISSIONLESS): use this method when launching and when stopping a chain -func (k Keeper) SetConsumerPhase(ctx sdk.Context, consumerId string, phase ConsumerPhase) { +func (k Keeper) SetConsumerPhase(ctx sdk.Context, consumerId string, phase types.ConsumerPhase) { store := ctx.KVStore(k.storeKey) - store.Set(types.ConsumerIdToPhaseKey(consumerId), []byte{byte(phase)}) + phaseBytes := make([]byte, 8) + binary.BigEndian.PutUint32(phaseBytes, uint32(phase)) + store.Set(types.ConsumerIdToPhaseKey(consumerId), phaseBytes) } // DeleteConsumerPhase deletes the phase associated with this consumer id @@ -253,10 +234,10 @@ func (k Keeper) DeleteConsumerStopTime(ctx sdk.Context, consumerId string) { store.Delete(types.ConsumerIdToStopTimeKey(consumerId)) } -// GetConsumersToBeLaunched -func (k Keeper) GetConsumersToBeLaunched(ctx sdk.Context, spawnTime time.Time) (types.ConsumerIds, error) { +// getConsumerIdsBasedOnTime returns all the consumer ids stored under this specific `key(time)` +func (k Keeper) getConsumerIdsBasedOnTime(ctx sdk.Context, key func(time.Time) []byte, time time.Time) (types.ConsumerIds, error) { store := ctx.KVStore(k.storeKey) - bz := store.Get(types.SpawnTimeToConsumerIdsKey(spawnTime)) + bz := store.Get(key(time)) if bz == nil { return types.ConsumerIds{}, nil } @@ -269,233 +250,181 @@ func (k Keeper) GetConsumersToBeLaunched(ctx sdk.Context, spawnTime time.Time) ( return consumerIds, nil } -// AppendSpawnTimeForConsumerToBeLaunched -func (k Keeper) AppendSpawnTimeForConsumerToBeLaunched(ctx sdk.Context, consumerId string, spawnTime time.Time) error { +// appendConsumerIdOnTime appends the consumer id on all the other consumer ids under `key(time)` +func (k Keeper) appendConsumerIdOnTime(ctx sdk.Context, consumerId string, key func(time.Time) []byte, time time.Time) error { store := ctx.KVStore(k.storeKey) - consumerIdsSlice, err := k.GetConsumersToBeLaunched(ctx, spawnTime) + consumers, err := k.getConsumerIdsBasedOnTime(ctx, key, time) if err != nil { return err } - consumerIds := append(consumerIdsSlice.Ids, consumerId) - appendedConsumerIdsStr := types.ConsumerIds{ - Ids: consumerIds, + consumersWithAppend := types.ConsumerIds{ + Ids: append(consumers.Ids, consumerId), } - bz, err := appendedConsumerIdsStr.Marshal() + bz, err := consumersWithAppend.Marshal() if err != nil { return err } - store.Set(types.SpawnTimeToConsumerIdsKey(spawnTime), bz) + store.Set(key(time), bz) return nil } -// RemoveConsumerFromToBeLaunchedConsumers -func (k Keeper) RemoveConsumerFromToBeLaunchedConsumers(ctx sdk.Context, consumerId string, spawnTime time.Time) error { +// removeConsumerIdFromTime removes consumer id stored under `key(time)` +func (k Keeper) removeConsumerIdFromTime(ctx sdk.Context, consumerId string, key func(time.Time) []byte, time time.Time) error { store := ctx.KVStore(k.storeKey) - consumerIds, err := k.GetConsumersToBeLaunched(ctx, spawnTime) + consumers, err := k.getConsumerIdsBasedOnTime(ctx, key, time) if err != nil { return err } - if len(consumerIds.Ids) == 0 { - return fmt.Errorf("no consumer ids for spawn time: %s", spawnTime.String()) + if len(consumers.Ids) == 0 { + return fmt.Errorf("no consumer ids found for this time: %s", time.String()) } // find the index of the consumer we want to remove - index := 0 - for i := 0; i < len(consumerIds.Ids); i = i + 1 { - if consumerIds.Ids[i] == consumerId { + index := -1 + for i := 0; i < len(consumers.Ids); i = i + 1 { + if consumers.Ids[i] == consumerId { index = i break } } - if consumerIds.Ids[index] != consumerId { - return fmt.Errorf("failed to find consumer id (%s) in the chains to be launched", consumerId) + + if index == -1 { + return fmt.Errorf("failed to find consumer id (%s)", consumerId) } - if len(consumerIds.Ids) == 1 { - store.Delete(types.SpawnTimeToConsumerIdsKey(spawnTime)) + if len(consumers.Ids) == 1 { + store.Delete(key(time)) return nil } - updatedConsumerIds := append(consumerIds.Ids[:index], consumerIds.Ids[index+1:]...) - - updatedConsumerIdsStr := types.ConsumerIds{ - Ids: updatedConsumerIds, + consumersWithRemoval := types.ConsumerIds{ + Ids: append(consumers.Ids[:index], consumers.Ids[index+1:]...), } - bz, err := updatedConsumerIdsStr.Marshal() + bz, err := consumersWithRemoval.Marshal() if err != nil { return err } - store.Set(types.SpawnTimeToConsumerIdsKey(spawnTime), bz) + store.Set(key(time), bz) return nil } -// TODO (PERMISSIONLESS) merge the functions, they practically do the same - -// GetConsumersToBeStopped -func (k Keeper) GetConsumersToBeStopped(ctx sdk.Context, stopTime time.Time) (types.ConsumerIds, error) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.StopTimeToConsumerIdsKey(stopTime)) - if bz == nil { - return types.ConsumerIds{}, nil - } - - var consumerIds types.ConsumerIds - err := consumerIds.Unmarshal(bz) - if err != nil { - return types.ConsumerIds{}, err - } - return consumerIds, nil +// GetConsumersToBeLaunched returns all the consumer ids of chains stored under this spawn time +func (k Keeper) GetConsumersToBeLaunched(ctx sdk.Context, spawnTime time.Time) (types.ConsumerIds, error) { + return k.getConsumerIdsBasedOnTime(ctx, types.SpawnTimeToConsumerIdsKey, spawnTime) } -// AppendSpawnTimeForConsumerToBeStopped -func (k Keeper) AppendStopTimeForConsumerToBeStopped(ctx sdk.Context, consumerId string, stopTime time.Time) error { - store := ctx.KVStore(k.storeKey) - - consumerIdsStr, err := k.GetConsumersToBeStopped(ctx, stopTime) - if err != nil { - return err - } - consumerIds := append(consumerIdsStr.Ids, consumerId) - - consumerIdsNewStr := types.ConsumerIds{ - Ids: consumerIds, - } - - bz, err := consumerIdsNewStr.Marshal() - if err != nil { - return err - } - - store.Set(types.StopTimeToConsumerIdsKey(stopTime), bz) - return nil +// AppendConsumerToBeLaunchedOnSpawnTime appends the provider consumer id for the given spawn time +func (k Keeper) AppendConsumerToBeLaunchedOnSpawnTime(ctx sdk.Context, consumerId string, spawnTime time.Time) error { + return k.appendConsumerIdOnTime(ctx, consumerId, types.SpawnTimeToConsumerIdsKey, spawnTime) } -// RemoveConsumerFromToBeStoppedConsumers -func (k Keeper) RemoveConsumerFromToBeStoppedConsumers(ctx sdk.Context, consumerId string, stopTime time.Time) error { - store := ctx.KVStore(k.storeKey) - - consumerIds, err := k.GetConsumersToBeStopped(ctx, stopTime) - if err != nil { - return err - } - - if len(consumerIds.Ids) == 0 { - return fmt.Errorf("no consumer ids for stop time: %s", stopTime.String()) - } - - // find the index of the consumer we want to remove - index := 0 - for i := 0; i < len(consumerIds.Ids); i = i + 1 { - if consumerIds.Ids[i] == consumerId { - index = i - break - } - } - if consumerIds.Ids[index] != consumerId { - return fmt.Errorf("failed to find consumer id (%s) in the chains to be stopped", consumerId) - } +// RemoveConsumerToBeLaunchedFromSpawnTime removes consumer id from if stored for this specific spawn time +func (k Keeper) RemoveConsumerToBeLaunchedFromSpawnTime(ctx sdk.Context, consumerId string, spawnTime time.Time) error { + return k.removeConsumerIdFromTime(ctx, consumerId, types.SpawnTimeToConsumerIdsKey, spawnTime) +} - if len(consumerIds.Ids) == 1 { - store.Delete(types.StopTimeToConsumerIdsKey(stopTime)) - return nil - } +// GetConsumersToBeStopped returns all the consumer ids of chains stored under this stop time +func (k Keeper) GetConsumersToBeStopped(ctx sdk.Context, stopTime time.Time) (types.ConsumerIds, error) { + return k.getConsumerIdsBasedOnTime(ctx, types.StopTimeToConsumerIdsKey, stopTime) +} - updatedConsumerIds := append(consumerIds.Ids[:index], consumerIds.Ids[index+1:]...) - updatedConsumerIdsStr := types.ConsumerIds{ - Ids: updatedConsumerIds, - } - bz, err := updatedConsumerIdsStr.Marshal() - if err != nil { - return err - } +// AppendConsumerToBeStoppedOnStopTime appends the provider consumer id for the given stop time +func (k Keeper) AppendConsumerToBeStoppedOnStopTime(ctx sdk.Context, consumerId string, stopTime time.Time) error { + return k.appendConsumerIdOnTime(ctx, consumerId, types.StopTimeToConsumerIdsKey, stopTime) +} - store.Set(types.StopTimeToConsumerIdsKey(stopTime), bz) - return nil +// RemoveConsumerToBeStoppedFromStopTime removes consumer id from if stored for this specific stop time +func (k Keeper) RemoveConsumerToBeStoppedFromStopTime(ctx sdk.Context, consumerId string, stopTime time.Time) error { + return k.removeConsumerIdFromTime(ctx, consumerId, types.StopTimeToConsumerIdsKey, stopTime) } -// GetOptedInConsumerIds -func (k Keeper) GetOptedInConsumerIds(ctx sdk.Context, providerAddr types.ProviderConsAddress) ([]string, error) { +// GetOptedInConsumerIds returns all the consumer ids where the given validator is opted in +func (k Keeper) GetOptedInConsumerIds(ctx sdk.Context, providerAddr types.ProviderConsAddress) (types.ConsumerIds, error) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.ProviderConsAddrToOptedInConsumerIdsKey(providerAddr)) if bz == nil { - return []string{}, nil + return types.ConsumerIds{}, nil + } + + var consumerIds types.ConsumerIds + if err := consumerIds.Unmarshal(bz); err != nil { + return types.ConsumerIds{}, fmt.Errorf("failed to unmarshal consumer ids: %w", err) } - var consumerIds []string - buf := bytes.NewBuffer(bz) - dec := gob.NewDecoder(buf) - err := dec.Decode(&consumerIds) - return consumerIds, err + return consumerIds, nil } -// AppendOptedInConsumerId +// AppendOptedInConsumerId appends given consumer id to the list of consumers that validator has opted in func (k Keeper) AppendOptedInConsumerId(ctx sdk.Context, providerAddr types.ProviderConsAddress, consumerId string) error { store := ctx.KVStore(k.storeKey) - consumerIds, err := k.GetOptedInConsumerIds(ctx, providerAddr) + consumers, err := k.GetOptedInConsumerIds(ctx, providerAddr) if err != nil { return err } - consumerIds = append(consumerIds, consumerId) - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - err = enc.Encode(consumerIds) + consumersWithAppend := types.ConsumerIds{ + Ids: append(consumers.Ids, consumerId), + } + + bz, err := consumersWithAppend.Marshal() if err != nil { return err } - store.Set(types.ProviderConsAddrToOptedInConsumerIdsKey(providerAddr), buf.Bytes()) + store.Set(types.ProviderConsAddrToOptedInConsumerIdsKey(providerAddr), bz) return nil } -// RemoveOptedInConsumerId +// RemoveOptedInConsumerId removes the consumer id from this validator because it is not opted in anymore func (k Keeper) RemoveOptedInConsumerId(ctx sdk.Context, providerAddr types.ProviderConsAddress, consumerId string) error { store := ctx.KVStore(k.storeKey) - consumerIds, err := k.GetOptedInConsumerIds(ctx, providerAddr) + consumers, err := k.GetOptedInConsumerIds(ctx, providerAddr) if err != nil { return err } - if len(consumerIds) == 0 { - return fmt.Errorf("no consumer ids for provider consensus address: %s", providerAddr.String()) + if len(consumers.Ids) == 0 { + return fmt.Errorf("no consumer ids found for this provviderAddr: %s", providerAddr.String()) } // find the index of the consumer we want to remove - index := 0 - for i := 0; i < len(consumerIds); i = i + 1 { - if consumerIds[i] == consumerId { + index := -1 + for i := 0; i < len(consumers.Ids); i = i + 1 { + if consumers.Ids[i] == consumerId { index = i break } } - if consumerIds[index] != consumerId { - return fmt.Errorf("failed to find consumer id (%s) from the opted-in chains", consumerId) + + if index == -1 { + return fmt.Errorf("failed to find consumer id (%s)", consumerId) } - if len(consumerIds) == 1 { + if len(consumers.Ids) == 1 { store.Delete(types.ProviderConsAddrToOptedInConsumerIdsKey(providerAddr)) return nil } - updatedConsumerIds := append(consumerIds[:index], consumerIds[index+1:]...) - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - err = enc.Encode(updatedConsumerIds) + consumersWithRemoval := types.ConsumerIds{ + Ids: append(consumers.Ids[:index], consumers.Ids[index+1:]...), + } + + bz, err := consumersWithRemoval.Marshal() if err != nil { return err } - store.Set(types.ProviderConsAddrToOptedInConsumerIdsKey(providerAddr), buf.Bytes()) + store.Set(types.ProviderConsAddrToOptedInConsumerIdsKey(providerAddr), bz) return nil } @@ -564,6 +493,48 @@ func (k Keeper) GetInitializedConsumersReadyToLaunch(ctx sdk.Context, limit uint return result } +// GetLaunchedConsumersReadyToStop returns the consumer ids of the pending launched consumer chains +// that are ready to stop +func (k Keeper) GetLaunchedConsumersReadyToStop(ctx sdk.Context, limit uint32) []string { + store := ctx.KVStore(k.storeKey) + + stopTimeToConsumerIdsKeyPrefix := types.StopTimeToConsumerIdsKeyPrefix() + iterator := storetypes.KVStorePrefixIterator(store, []byte{stopTimeToConsumerIdsKeyPrefix}) + defer iterator.Close() + + result := []string{} + for ; iterator.Valid(); iterator.Next() { + stopTime, err := types.ParseTime(types.StopTimeToConsumerIdsKeyPrefix(), iterator.Key()) + if err != nil { + k.Logger(ctx).Error("failed to parse stop time", + "error", err) + continue + } + if stopTime.After(ctx.BlockTime()) { + return result + } + + consumers, err := k.GetConsumersToBeStopped(ctx, stopTime) + if err != nil { + k.Logger(ctx).Error("failed to retrieve consumers to stop", + "stop time", stopTime, + "error", err) + continue + } + if len(result)+len(consumers.Ids) >= int(limit) { + remainingConsumerIds := len(result) + len(consumers.Ids) - int(limit) + if len(consumers.Ids[:len(consumers.Ids)-remainingConsumerIds]) == 0 { + return result + } + return append(result, consumers.Ids[:len(consumers.Ids)-remainingConsumerIds]...) + } else { + result = append(result, consumers.Ids...) + } + } + + return result +} + // LaunchConsumer launches the chain with the provided consumer id by creating the consumer client and the respective // consumer genesis file func (k Keeper) LaunchConsumer(ctx sdk.Context, consumerId string) error { @@ -574,16 +545,13 @@ func (k Keeper) LaunchConsumer(ctx sdk.Context, consumerId string) error { consumerGenesis, found := k.GetConsumerGenesis(ctx, consumerId) if !found { - return errorsmod.Wrapf(types.ErrNoConsumerGenesis, "consumer genesis could not be found") + return errorsmod.Wrapf(types.ErrNoConsumerGenesis, "consumer genesis could not be found for consumer id: %s", consumerId) } if len(consumerGenesis.Provider.InitialValSet) == 0 { - return errorsmod.Wrapf(types.ErrInvalidConsumerGenesis, "consumer genesis initial validator set is empty - no validators opted in") + return errorsmod.Wrapf(types.ErrInvalidConsumerGenesis, "consumer genesis initial validator set is empty - no validators opted in consumer id: %s", consumerId) } - // The cached context is created with a new EventManager so we merge the event - // into the original context - ctx.EventManager().EmitEvents(ctx.EventManager().Events()) return nil } @@ -638,53 +606,11 @@ func (k Keeper) UpdateMinimumPowerInTopN(ctx sdk.Context, consumerId string, old return nil } -// GetLaunchedConsumersReadyToStop returns the consumer ids of the pending launched consumer chains -// that are ready to stop -func (k Keeper) GetLaunchedConsumersReadyToStop(ctx sdk.Context, limit uint32) []string { - store := ctx.KVStore(k.storeKey) - - stopTimeToConsumerIdsKeyPrefix := types.StopTimeToConsumerIdsKeyPrefix() - iterator := storetypes.KVStorePrefixIterator(store, []byte{stopTimeToConsumerIdsKeyPrefix}) - defer iterator.Close() - - result := []string{} - for ; iterator.Valid(); iterator.Next() { - stopTime, err := types.ParseTime(types.StopTimeToConsumerIdsKeyPrefix(), iterator.Key()) - if err != nil { - k.Logger(ctx).Error("failed to parse stop time", - "error", err) - continue - } - if stopTime.After(ctx.BlockTime()) { - return result - } - - consumerIds, err := k.GetConsumersToBeStopped(ctx, stopTime) - if err != nil { - k.Logger(ctx).Error("failed to retrieve consumers to stop", - "stop time", stopTime, - "error", err) - continue - } - if len(result)+len(consumerIds.Ids) >= int(limit) { - remainingConsumerIds := len(result) + len(consumerIds.Ids) - int(limit) - if len(consumerIds.Ids[:len(consumerIds.Ids)-remainingConsumerIds]) == 0 { - return result - } - return append(result, consumerIds.Ids[:len(consumerIds.Ids)-remainingConsumerIds]...) - } else { - result = append(result, consumerIds.Ids...) - } - } - - return result -} - // IsValidatorOptedInToChainId checks if the validator with `providerAddr` is opted into the chain with the specified `chainId`. // It returns `found == true` and the corresponding chain's `consumerId` if the validator is opted in. Otherwise, it returns an empty string // for `consumerId` and `found == false`. func (k Keeper) IsValidatorOptedInToChainId(ctx sdk.Context, providerAddr types.ProviderConsAddress, chainId string) (string, bool) { - consumerIds, err := k.GetOptedInConsumerIds(ctx, providerAddr) + consumers, err := k.GetOptedInConsumerIds(ctx, providerAddr) if err != nil { k.Logger(ctx).Error("failed to retrieve the consumer ids this validator is opted in to", "providerAddr", providerAddr, @@ -692,7 +618,7 @@ func (k Keeper) IsValidatorOptedInToChainId(ctx sdk.Context, providerAddr types. return "", false } - for _, consumerId := range consumerIds { + for _, consumerId := range consumers.Ids { consumerChainId, err := k.GetConsumerChainId(ctx, consumerId) if err != nil { k.Logger(ctx).Error("cannot find chain id", @@ -709,13 +635,18 @@ func (k Keeper) IsValidatorOptedInToChainId(ctx sdk.Context, providerAddr types. return "", false } -func (k Keeper) PrepareConsumerForLaunch(ctx sdk.Context, consumerId string, previousSpawnTime time.Time, spawnTime time.Time) { +// PrepareConsumerForLaunch prepares to move the launch of a consumer chain from the previous spawn time to spawn time. +// Previous spawn time can correspond to its zero value if the validator was not previously set for launch. +func (k Keeper) PrepareConsumerForLaunch(ctx sdk.Context, consumerId string, previousSpawnTime time.Time, spawnTime time.Time) error { if !previousSpawnTime.Equal(time.Time{}) { // if this is not the first initialization and hence `previousSpawnTime` does not contain the zero value of `Time` - // remove the consumer id from the old spawn time - k.RemoveConsumerFromToBeLaunchedConsumers(ctx, consumerId, previousSpawnTime) + // remove the consumer id from the previous spawn time + err := k.RemoveConsumerToBeLaunchedFromSpawnTime(ctx, consumerId, previousSpawnTime) + if err != nil { + return err + } } - k.AppendSpawnTimeForConsumerToBeLaunched(ctx, consumerId, spawnTime) + return k.AppendConsumerToBeLaunchedOnSpawnTime(ctx, consumerId, spawnTime) } // CanLaunch checks on whether the consumer with `consumerId` has set all the initialization parameters set and hence @@ -723,8 +654,8 @@ func (k Keeper) PrepareConsumerForLaunch(ctx sdk.Context, consumerId string, pre // TODO (PERMISSIONLESS): could remove, all fields should be there because we validate the initialization parameters func (k Keeper) CanLaunch(ctx sdk.Context, consumerId string) (time.Time, bool) { // a chain that is already launched or stopped cannot launch again - phase, found := k.GetConsumerPhase(ctx, consumerId) - if !found || phase == Launched || phase == Stopped { + phase := k.GetConsumerPhase(ctx, consumerId) + if phase == types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED || phase == types.ConsumerPhase_CONSUMER_PHASE_STOPPED { return time.Time{}, false } @@ -733,8 +664,7 @@ func (k Keeper) CanLaunch(ctx sdk.Context, consumerId string) (time.Time, bool) return time.Time{}, false } - // a chain can only launch if the spawn time is in the future - spawnTimeInTheFuture := initializationParameters.SpawnTime.After(ctx.BlockTime()) + spawnTimeIsNotZero := !initializationParameters.SpawnTime.Equal(time.Time{}) genesisHashSet := initializationParameters.GenesisHash != nil binaryHashSet := initializationParameters.BinaryHash != nil @@ -743,6 +673,57 @@ func (k Keeper) CanLaunch(ctx sdk.Context, consumerId string) (time.Time, bool) blocksPerDistributionTransmissionSet := initializationParameters.BlocksPerDistributionTransmission > 0 historicalEntriesSet := initializationParameters.HistoricalEntries > 0 - return initializationParameters.SpawnTime, spawnTimeInTheFuture && genesisHashSet && binaryHashSet && consumerRedistributionFractionSet && + return initializationParameters.SpawnTime, spawnTimeIsNotZero && genesisHashSet && binaryHashSet && consumerRedistributionFractionSet && blocksPerDistributionTransmissionSet && historicalEntriesSet } + +// HasAtMostOnceCorrectMsgUpdateConsumer checks that the proposal has at most one `MsgUpdateConsumer` that is +// correctly set (i.e., the owner address of the to-be-updated consumer corresponds to the gov module). Returns +// the single `MsgUpdateConsumer` message if only one correctly set exists. +func (k Keeper) HasAtMostOnceCorrectMsgUpdateConsumer(ctx sdk.Context, proposal *govv1.Proposal) (*types.MsgUpdateConsumer, error) { + var msgUpdateConsumer *types.MsgUpdateConsumer + for _, msg := range proposal.GetMessages() { + sdkMsg, isMsgUpdateConsumer := msg.GetCachedValue().(*types.MsgUpdateConsumer) + if isMsgUpdateConsumer { + // A `MsgUpdateConsumer` can only succeed if the owner of the consumer chain is the gov module. + // If that's not the case, we immediately fail the proposal. + // Note that someone could potentially change the owner of a chain to be that of the gov module + // while a proposal is active and before the proposal is executed. Even then, we still do not allow + // `MsgUpdateConsumer` proposals if the owner of the chain is not the gov module to avoid someone forgetting + // to change the owner address while the proposal is active. + ownerAddress, err := k.GetConsumerOwnerAddress(ctx, sdkMsg.ConsumerId) + if err != nil { + return nil, fmt.Errorf("cannot find owner address for consumer with consumer id (%s): %s", sdkMsg.ConsumerId, err.Error()) + } else if ownerAddress != k.GetAuthority() { + return nil, fmt.Errorf("owner address (%s) is not the gov module (%s)", ownerAddress, k.GetAuthority()) + } + + if msgUpdateConsumer != nil { + return nil, fmt.Errorf("proposal can contain at most one `MsgUpdateConsumer` message") + } + msgUpdateConsumer = sdkMsg + } + } + return msgUpdateConsumer, nil +} + +// DoesNotHaveDeprecatedMessage checks that the provided proposal does not contain any deprecated messages and returns +// an error if this is the case +func DoesNotHaveDeprecatedMessage(proposal *govv1.Proposal) error { + for _, msg := range proposal.GetMessages() { + // if the proposal contains a deprecated message, cancel the proposal + _, isMsgConsumerAddition := msg.GetCachedValue().(*types.MsgConsumerAddition) + if isMsgConsumerAddition { + return fmt.Errorf("proposal cannot contain deprecated `MsgConsumerAddition`; use `MsgCreateConsumer` instead") + } + _, isMsgConsumerModification := msg.GetCachedValue().(*types.MsgConsumerModification) + if isMsgConsumerModification { + return fmt.Errorf("proposal cannot contain deprecated `MsgConsumerModification`; use `MsgUpdateConsumer` instead") + } + _, isMsgConsumerRemoval := msg.GetCachedValue().(*types.MsgConsumerRemoval) + if isMsgConsumerRemoval { + return fmt.Errorf("proposal cannot contain deprecated `MsgConsumerRemoval`; use `MsgRemoveConsumer` instead") + } + } + return nil +} diff --git a/x/ccv/provider/keeper/permissionless_test.go b/x/ccv/provider/keeper/permissionless_test.go index 5819e355d0..da8412220e 100644 --- a/x/ccv/provider/keeper/permissionless_test.go +++ b/x/ccv/provider/keeper/permissionless_test.go @@ -1,7 +1,11 @@ package keeper_test import ( + "testing" + "time" + sdk "github.com/cosmos/cosmos-sdk/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" @@ -9,183 +13,239 @@ import ( providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "testing" - "time" ) -func TestFetchAndIncrementConsumerId(t *testing.T) { +// TestConsumerId tests setters and getters of consumer id (i.e., `FetchAndIncrementConsumerId` and `GetConsumerId`) +func TestConsumerId(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() + _, found := providerKeeper.GetConsumerId(ctx) + require.False(t, found) + consumerId := providerKeeper.FetchAndIncrementConsumerId(ctx) require.Equal(t, "0", consumerId) + consumerIdNum, found := providerKeeper.GetConsumerId(ctx) + require.Equal(t, uint64(1), consumerIdNum) + require.True(t, found) consumerId = providerKeeper.FetchAndIncrementConsumerId(ctx) require.Equal(t, "1", consumerId) + consumerIdNum, found = providerKeeper.GetConsumerId(ctx) + require.Equal(t, uint64(2), consumerIdNum) + require.True(t, found) +} - consumerId = providerKeeper.FetchAndIncrementConsumerId(ctx) - require.Equal(t, "2", consumerId) +// TestConsumerChainId tests the getter, setter, and deletion of the consumer to chain id methods +func TestConsumerChainId(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + _, err := providerKeeper.GetConsumerChainId(ctx, "chainId") + require.Error(t, err, "failed to retrieve chain id") + + providerKeeper.SetConsumerChainId(ctx, "chainId", "chainId") + chainId, err := providerKeeper.GetConsumerChainId(ctx, "chainId") + require.NoError(t, err) + require.Equal(t, "chainId", chainId) + + // write under a different key + providerKeeper.SetConsumerChainId(ctx, "consumerId2", "chainId") + chainId, err = providerKeeper.GetConsumerChainId(ctx, "consumerId2") + require.NoError(t, err) + require.Equal(t, "chainId", chainId) + + // assert that overwriting the current key works + providerKeeper.SetConsumerChainId(ctx, "chainId", "chainId2") + chainId, err = providerKeeper.GetConsumerChainId(ctx, "chainId") + require.NoError(t, err) + require.Equal(t, "chainId2", chainId) + + providerKeeper.DeleteConsumerChainId(ctx, "chainId") + _, err = providerKeeper.GetConsumerChainId(ctx, "chainId") + require.Error(t, err, "failed to retrieve chain id") } -// TestClientIdToConsumerId tests the getter, setter, and deletion methods of the client id to consumer id methods -func TestClientIdToConsumerId(t *testing.T) { +// TestConsumerOwnerAddress tests the getter, setter, and deletion of the consumer to owner address methods +func TestConsumerOwnerAddress(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - _, found := providerKeeper.GetClientIdToConsumerId(ctx, "clientId") - require.False(t, found) + _, err := providerKeeper.GetConsumerOwnerAddress(ctx, "ownerAddress") + require.Error(t, err, "failed to retrieve owner address") - providerKeeper.SetClientIdToConsumerId(ctx, "clientId", "consumerId") - consumerId, found := providerKeeper.GetClientIdToConsumerId(ctx, "clientId") - require.True(t, found) - require.Equal(t, "consumerId", consumerId) + providerKeeper.SetConsumerOwnerAddress(ctx, "consumerId", "owner address") + ownerAddress, err := providerKeeper.GetConsumerOwnerAddress(ctx, "consumerId") + require.NoError(t, err) + require.Equal(t, "owner address", ownerAddress) - // assert that overwriting the current consumer id record works - providerKeeper.SetClientIdToConsumerId(ctx, "clientId", "consumerId2") - consumerId, found = providerKeeper.GetClientIdToConsumerId(ctx, "clientId") - require.True(t, found) - require.Equal(t, "consumerId2", consumerId) + // write under a different key + providerKeeper.SetConsumerOwnerAddress(ctx, "consumerId2", "owner address") + ownerAddress, err = providerKeeper.GetConsumerOwnerAddress(ctx, "consumerId2") + require.NoError(t, err) + require.Equal(t, "owner address", ownerAddress) - providerKeeper.DeleteClientIdToConsumerId(ctx, "clientId") - consumerId, found = providerKeeper.GetClientIdToConsumerId(ctx, "clientId") - require.False(t, found) - require.Equal(t, "", consumerId) + // assert that overwriting the current key works + providerKeeper.SetConsumerOwnerAddress(ctx, "consumerId", "owner address2") + ownerAddress, err = providerKeeper.GetConsumerOwnerAddress(ctx, "consumerId") + require.NoError(t, err) + require.Equal(t, "owner address2", ownerAddress) + + providerKeeper.DeleteConsumerOwnerAddress(ctx, "consumerId") + _, err = providerKeeper.GetConsumerChainId(ctx, "consumerId") + require.Error(t, err, "failed to retrieve owner address") } -// TestConsumerIdToRegistrationRecord tests the getter, setter, and deletion methods of the consumer id to registration record methods -func TestConsumerIdToRegistrationRecord(t *testing.T) { +// TestConsumerMetadata tests the getter, setter, and deletion of the consumer id to consumer metadata methods +func TestConsumerMetadata(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() _, err := providerKeeper.GetConsumerMetadata(ctx, "consumerId") require.Error(t, err) - expectedRecord := providertypes.ConsumerMetadata{ + expectedMetadata := providertypes.ConsumerMetadata{ Name: "name", Description: "description", Metadata: "metadata", //ChainId: "chain_id", } - providerKeeper.SetConsumerMetadata(ctx, "consumerId", expectedRecord) - actualRecord, err := providerKeeper.GetConsumerMetadata(ctx, "consumerId") + providerKeeper.SetConsumerMetadata(ctx, "consumerId", expectedMetadata) + actualMetadata, err := providerKeeper.GetConsumerMetadata(ctx, "consumerId") require.NoError(t, err) - require.Equal(t, expectedRecord, actualRecord) + require.Equal(t, expectedMetadata, actualMetadata) // assert that overwriting the current registration record works - expectedRecord = providertypes.ConsumerMetadata{ + expectedMetadata = providertypes.ConsumerMetadata{ Name: "name 2", Description: "description 2", Metadata: "metadata 2", //ChainId: "chain_id2", } - providerKeeper.SetConsumerMetadata(ctx, "consumerId", expectedRecord) - actualRecord, err = providerKeeper.GetConsumerMetadata(ctx, "consumerId") + providerKeeper.SetConsumerMetadata(ctx, "consumerId", expectedMetadata) + actualMetadata, err = providerKeeper.GetConsumerMetadata(ctx, "consumerId") require.NoError(t, err) - require.Equal(t, expectedRecord, actualRecord) + require.Equal(t, expectedMetadata, actualMetadata) providerKeeper.DeleteConsumerMetadata(ctx, "consumerId") - actualRecord, err = providerKeeper.GetConsumerMetadata(ctx, "consumerId") + actualMetadata, err = providerKeeper.GetConsumerMetadata(ctx, "consumerId") require.Error(t, err) - require.Equal(t, providertypes.ConsumerMetadata{}, actualRecord) + require.Equal(t, providertypes.ConsumerMetadata{}, actualMetadata) } -// TestConsumerIdToInitializationRecord tests the getter, setter, and deletion methods of the consumer id to initialization record methods -func TestConsumerIdToInitializationRecord(t *testing.T) { +// TestConsumerInitializationParameters tests the getter, setter, and deletion of the consumer id to initialization parameters methods +func TestConsumerInitializationParameters(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() _, err := providerKeeper.GetConsumerInitializationParameters(ctx, "consumerId") require.Error(t, err) - spawnTime := time.Unix(1, 2).UTC() - unbondingPeriod := time.Duration(3456) - ccvTimeoutPeriod := time.Duration(789) - transferTimeoutPeriod := time.Duration(101112) - expectedRecord := providertypes.ConsumerInitializationParameters{ + expectedInitializationParameters := providertypes.ConsumerInitializationParameters{ InitialHeight: types.Height{RevisionNumber: 1, RevisionHeight: 2}, GenesisHash: []byte{0, 1}, BinaryHash: []byte{2, 3}, - SpawnTime: spawnTime, - UnbondingPeriod: unbondingPeriod, - CcvTimeoutPeriod: ccvTimeoutPeriod, - TransferTimeoutPeriod: transferTimeoutPeriod, + SpawnTime: time.Unix(1, 2).UTC(), + UnbondingPeriod: time.Duration(3456), + CcvTimeoutPeriod: time.Duration(789), + TransferTimeoutPeriod: time.Duration(101112), ConsumerRedistributionFraction: "consumer_redistribution_fraction", BlocksPerDistributionTransmission: 123, HistoricalEntries: 456, DistributionTransmissionChannel: "distribution_transmission_channel", } - providerKeeper.SetConsumerInitializationParameters(ctx, "consumerId", expectedRecord) - actualRecord, err := providerKeeper.GetConsumerInitializationParameters(ctx, "consumerId") + providerKeeper.SetConsumerInitializationParameters(ctx, "consumerId", expectedInitializationParameters) + actualInitializationParameters, err := providerKeeper.GetConsumerInitializationParameters(ctx, "consumerId") require.NoError(t, err) - require.Equal(t, expectedRecord, actualRecord) + require.Equal(t, expectedInitializationParameters, actualInitializationParameters) // assert that overwriting the current initialization record works - spawnTime = time.Unix(2, 3).UTC() - unbondingPeriod = time.Duration(789) - ccvTimeoutPeriod = time.Duration(101112) - transferTimeoutPeriod = time.Duration(131415) - expectedRecord = providertypes.ConsumerInitializationParameters{ + expectedInitializationParameters = providertypes.ConsumerInitializationParameters{ InitialHeight: types.Height{RevisionNumber: 2, RevisionHeight: 3}, GenesisHash: []byte{2, 3}, BinaryHash: []byte{4, 5}, - SpawnTime: spawnTime, - UnbondingPeriod: unbondingPeriod, - CcvTimeoutPeriod: ccvTimeoutPeriod, - TransferTimeoutPeriod: transferTimeoutPeriod, + SpawnTime: time.Unix(2, 3).UTC(), + UnbondingPeriod: time.Duration(789), + CcvTimeoutPeriod: time.Duration(101112), + TransferTimeoutPeriod: time.Duration(131415), ConsumerRedistributionFraction: "consumer_redistribution_fraction2", BlocksPerDistributionTransmission: 456, HistoricalEntries: 789, DistributionTransmissionChannel: "distribution_transmission_channel2", } - providerKeeper.SetConsumerInitializationParameters(ctx, "consumerId", expectedRecord) - actualRecord, err = providerKeeper.GetConsumerInitializationParameters(ctx, "consumerId") + providerKeeper.SetConsumerInitializationParameters(ctx, "consumerId", expectedInitializationParameters) + actualInitializationParameters, err = providerKeeper.GetConsumerInitializationParameters(ctx, "consumerId") require.NoError(t, err) - require.Equal(t, expectedRecord, actualRecord) + require.Equal(t, expectedInitializationParameters, actualInitializationParameters) providerKeeper.DeleteConsumerInitializationParameters(ctx, "consumerId") - actualRecord, err = providerKeeper.GetConsumerInitializationParameters(ctx, "consumerId") + actualInitializationParameters, err = providerKeeper.GetConsumerInitializationParameters(ctx, "consumerId") require.Error(t, err) - require.Equal(t, providertypes.ConsumerInitializationParameters{}, actualRecord) + require.Equal(t, providertypes.ConsumerInitializationParameters{}, actualInitializationParameters) } -// TestConsumerIdToOwnerAddress tests the getter, setter, and deletion methods of the owner address to registration record methods -func TestConsumerIdToOwnerAddress(t *testing.T) { +// TestConsumerPowerShapingParameters tests the getter, setter, and deletion of the consumer id to power-shaping parameters methods +func TestConsumerPowerShapingParameters(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - providerKeeper.SetConsumerOwnerAddress(ctx, "consumerId", "owner_address") - address, err := providerKeeper.GetConsumerOwnerAddress(ctx, "consumerId") + _, err := providerKeeper.GetConsumerPowerShapingParameters(ctx, "consumerId") + require.Error(t, err) + + expectedPowerShapingParameters := providertypes.PowerShapingParameters{ + Top_N: 10, + ValidatorsPowerCap: 34, + ValidatorSetCap: 10, + Allowlist: []string{"allowlist1", "allowlist2"}, + Denylist: []string{"denylist1", "denylist2"}, + MinStake: 234, + AllowInactiveVals: true, + } + providerKeeper.SetConsumerPowerShapingParameters(ctx, "consumerId", expectedPowerShapingParameters) + actualPowerShapingParameters, err := providerKeeper.GetConsumerPowerShapingParameters(ctx, "consumerId") require.NoError(t, err) - require.Equal(t, "owner_address", address) + require.Equal(t, expectedPowerShapingParameters, actualPowerShapingParameters) - // assert that overwriting the current owner address works - providerKeeper.SetConsumerOwnerAddress(ctx, "consumerId", "owner_address2") - address, err = providerKeeper.GetConsumerOwnerAddress(ctx, "consumerId") + // assert that overwriting the current initialization record works + expectedPowerShapingParameters = providertypes.PowerShapingParameters{ + Top_N: 12, + ValidatorsPowerCap: 67, + ValidatorSetCap: 20, + Allowlist: []string{"allowlist3", "allowlist4"}, + Denylist: []string{"denylist3", "denylist4"}, + MinStake: 567, + AllowInactiveVals: false, + } + providerKeeper.SetConsumerPowerShapingParameters(ctx, "consumerId", expectedPowerShapingParameters) + actualPowerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, "consumerId") require.NoError(t, err) - require.Equal(t, "owner_address2", address) + require.Equal(t, expectedPowerShapingParameters, actualPowerShapingParameters) + + providerKeeper.DeleteConsumerPowerShapingParameters(ctx, "consumerId") + actualPowerShapingParameters, err = providerKeeper.GetConsumerPowerShapingParameters(ctx, "consumerId") + require.Error(t, err) + require.Equal(t, providertypes.PowerShapingParameters{}, actualPowerShapingParameters) } -// TestConsumerIdToPhase tests the getter, setter, and deletion methods of the consumer id to phase methods -func TestConsumerIdToPhase(t *testing.T) { +// TestConsumerPhase tests the getter, setter, and deletion of the consumer id to phase methods +func TestConsumerPhase(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - _, found := providerKeeper.GetConsumerPhase(ctx, "consumerId") - require.False(t, found) + phase := providerKeeper.GetConsumerPhase(ctx, "consumerId") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED, phase) - providerKeeper.SetConsumerPhase(ctx, "consumerId", keeper.Initialized) - phase, found := providerKeeper.GetConsumerPhase(ctx, "consumerId") - require.True(t, found) - require.Equal(t, keeper.Initialized, phase) + providerKeeper.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + phase = providerKeeper.GetConsumerPhase(ctx, "consumerId") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED, phase) - providerKeeper.SetConsumerPhase(ctx, "consumerId", keeper.Launched) - phase, found = providerKeeper.GetConsumerPhase(ctx, "consumerId") - require.True(t, found) - require.Equal(t, keeper.Launched, phase) + providerKeeper.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) + phase = providerKeeper.GetConsumerPhase(ctx, "consumerId") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED, phase) } -// TestConsumerIdToStopTime tests the getter, setter, and deletion methods of the consumer id to stop times -func TestConsumerIdToStopTime(t *testing.T) { +// TestConsumerStopTime tests the getter, setter, and deletion of the consumer id to stop times methods +func TestConsumerStopTime(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() @@ -203,6 +263,209 @@ func TestConsumerIdToStopTime(t *testing.T) { require.Error(t, err) } +// TestConsumersToBeLaunched tests `AppendConsumerToBeLaunchedOnSpawnTime`, `GetConsumersToBeLaunched`, and `RemoveConsumerToBeLaunchedFromSpawnTime` +func TestConsumersToBeLaunched(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + spawnTime := time.Now() + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId1", spawnTime) + consumers, err := providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1"}, consumers.Ids) + + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId2", spawnTime) + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId2"}, consumers.Ids) + + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId3", spawnTime) + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId2", "consumerId3"}, consumers.Ids) + + err = providerKeeper.RemoveConsumerToBeLaunchedFromSpawnTime(ctx, "consumerId2", spawnTime) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId3"}, consumers.Ids) + + // also add consumer ids under a different spawn time and verify everything under the original spawn time is still there + spawnTimePlusOneHour := spawnTime.Add(time.Hour) + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId4", spawnTimePlusOneHour) + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTimePlusOneHour) + require.NoError(t, err) + require.Equal(t, []string{"consumerId4"}, consumers.Ids) + + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId3"}, consumers.Ids) + + // start removing all consumers from `spawnTime` + err = providerKeeper.RemoveConsumerToBeLaunchedFromSpawnTime(ctx, "consumerId3", spawnTime) + require.NoError(t, err) + err = providerKeeper.RemoveConsumerToBeLaunchedFromSpawnTime(ctx, "consumerId1", spawnTime) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Empty(t, consumers.Ids) + + // remove from `spawnTimePlusOneHour` + err = providerKeeper.RemoveConsumerToBeLaunchedFromSpawnTime(ctx, "consumerId4", spawnTimePlusOneHour) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTimePlusOneHour) + require.NoError(t, err) + require.Empty(t, consumers.Ids) + + // add another consumer for `spawnTime` + err = providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId5", spawnTime) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId5"}, consumers.Ids) +} + +// TestConsumersToBeStopped tests `AppendConsumerToBeLaunchedOnSpawnTime`, `GetConsumersToBeLaunched`, and `RemoveConsumerToBeLaunchedFromSpawnTime` +func TestConsumersToBeStopped(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + stopTime := time.Now() + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId1", stopTime) + consumers, err := providerKeeper.GetConsumersToBeStopped(ctx, stopTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1"}, consumers.Ids) + + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId2", stopTime) + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId2"}, consumers.Ids) + + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId3", stopTime) + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId2", "consumerId3"}, consumers.Ids) + + err = providerKeeper.RemoveConsumerToBeStoppedFromStopTime(ctx, "consumerId2", stopTime) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId3"}, consumers.Ids) + + // also add consumer ids under a different stop time and verify everything under the original stop time is still there + stopTimePlusOneHour := stopTime.Add(time.Hour) + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId4", stopTimePlusOneHour) + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTimePlusOneHour) + require.NoError(t, err) + require.Equal(t, []string{"consumerId4"}, consumers.Ids) + + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId1", "consumerId3"}, consumers.Ids) + + // start removing all consumers from `stopTime` + err = providerKeeper.RemoveConsumerToBeStoppedFromStopTime(ctx, "consumerId3", stopTime) + require.NoError(t, err) + err = providerKeeper.RemoveConsumerToBeStoppedFromStopTime(ctx, "consumerId1", stopTime) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTime) + require.NoError(t, err) + require.Empty(t, consumers.Ids) + + // remove from `stopTimePlusOneHour` + err = providerKeeper.RemoveConsumerToBeStoppedFromStopTime(ctx, "consumerId4", stopTimePlusOneHour) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTimePlusOneHour) + require.NoError(t, err) + require.Empty(t, consumers.Ids) + + // add another consumer for `stopTime` + err = providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId5", stopTime) + require.NoError(t, err) + consumers, err = providerKeeper.GetConsumersToBeStopped(ctx, stopTime) + require.NoError(t, err) + require.Equal(t, []string{"consumerId5"}, consumers.Ids) +} + +// TestOptedInConsumerIds tests the `GetOptedInConsumerIds`, `AppendOptedInConsumerId`, and `RemoveOptedInConsumerId` methods +func TestGetOptedInConsumerIds(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr := providertypes.NewProviderConsAddress([]byte("providerAddr")) + consumers, err := providerKeeper.GetOptedInConsumerIds(ctx, providerAddr) + require.NoError(t, err) + require.Empty(t, consumers) + + err = providerKeeper.AppendOptedInConsumerId(ctx, providerAddr, "consumerId1") + require.NoError(t, err) + consumers, err = providerKeeper.GetOptedInConsumerIds(ctx, providerAddr) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{ + Ids: []string{"consumerId1"}, + }, consumers) + + err = providerKeeper.AppendOptedInConsumerId(ctx, providerAddr, "consumerId2") + require.NoError(t, err) + consumers, err = providerKeeper.GetOptedInConsumerIds(ctx, providerAddr) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{ + Ids: []string{"consumerId1", "consumerId2"}, + }, consumers) + + err = providerKeeper.AppendOptedInConsumerId(ctx, providerAddr, "consumerId3") + require.NoError(t, err) + consumers, err = providerKeeper.GetOptedInConsumerIds(ctx, providerAddr) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{ + Ids: []string{"consumerId1", "consumerId2", "consumerId3"}, + }, consumers) + + // remove all the consumer ids + err = providerKeeper.RemoveOptedInConsumerId(ctx, providerAddr, "consumerId2") + require.NoError(t, err) + consumers, err = providerKeeper.GetOptedInConsumerIds(ctx, providerAddr) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{ + Ids: []string{"consumerId1", "consumerId3"}, + }, consumers) + + err = providerKeeper.RemoveOptedInConsumerId(ctx, providerAddr, "consumerId3") + require.NoError(t, err) + + err = providerKeeper.RemoveOptedInConsumerId(ctx, providerAddr, "consumerId1") + require.NoError(t, err) + + consumers, err = providerKeeper.GetOptedInConsumerIds(ctx, providerAddr) + require.NoError(t, err) + require.Empty(t, consumers) +} + +// TestConsumerChainId tests the getter, setter, and deletion of the client id to consumer id methods +func TestClientIdToConsumerId(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + _, found := providerKeeper.GetClientIdToConsumerId(ctx, "clientId") + require.False(t, found) + + providerKeeper.SetClientIdToConsumerId(ctx, "clientId", "consumerId") + consumerId, found := providerKeeper.GetClientIdToConsumerId(ctx, "clientId") + require.True(t, found) + require.Equal(t, "consumerId", consumerId) + + // assert that overwriting the current consumer id record works + providerKeeper.SetClientIdToConsumerId(ctx, "clientId", "consumerId2") + consumerId, found = providerKeeper.GetClientIdToConsumerId(ctx, "clientId") + require.True(t, found) + require.Equal(t, "consumerId2", consumerId) + + providerKeeper.DeleteClientIdToConsumerId(ctx, "clientId") + consumerId, found = providerKeeper.GetClientIdToConsumerId(ctx, "clientId") + require.False(t, found) + require.Equal(t, "", consumerId) +} + // TestGetInitializedConsumersReadyToLaunch tests that the ready to-be-launched consumer chains are returned func TestGetInitializedConsumersReadyToLaunch(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) @@ -211,9 +474,9 @@ func TestGetInitializedConsumersReadyToLaunch(t *testing.T) { // no chains to-be-launched exist require.Empty(t, providerKeeper.GetInitializedConsumersReadyToLaunch(ctx, 5)) - providerKeeper.AppendSpawnTimeForConsumerToBeLaunched(ctx, "consumerId1", time.Unix(10, 0)) - providerKeeper.AppendSpawnTimeForConsumerToBeLaunched(ctx, "consumerId2", time.Unix(20, 0)) - providerKeeper.AppendSpawnTimeForConsumerToBeLaunched(ctx, "consumerId3", time.Unix(30, 0)) + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId1", time.Unix(10, 0)) + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId2", time.Unix(20, 0)) + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, "consumerId3", time.Unix(30, 0)) // time has not yet reached the spawn time of "consumerId1" ctx = ctx.WithBlockTime(time.Unix(9, 999999999)) @@ -244,9 +507,9 @@ func TestGetLaunchedConsumersReadyToStop(t *testing.T) { // no chains to-be-stopped exist require.Empty(t, providerKeeper.GetLaunchedConsumersReadyToStop(ctx, 3)) - providerKeeper.AppendStopTimeForConsumerToBeStopped(ctx, "consumerId1", time.Unix(10, 0)) - providerKeeper.AppendStopTimeForConsumerToBeStopped(ctx, "consumerId2", time.Unix(20, 0)) - providerKeeper.AppendStopTimeForConsumerToBeStopped(ctx, "consumerId3", time.Unix(30, 0)) + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId1", time.Unix(10, 0)) + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId2", time.Unix(20, 0)) + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, "consumerId3", time.Unix(30, 0)) // time has not yet reached the stop time of "consumerId1" ctx = ctx.WithBlockTime(time.Unix(9, 999999999)) @@ -265,24 +528,6 @@ func TestGetLaunchedConsumersReadyToStop(t *testing.T) { require.Equal(t, []string{"consumerId1", "consumerId2", "consumerId3"}, providerKeeper.GetLaunchedConsumersReadyToStop(ctx, 3)) } -func TestIsValidatorOptedInToChain(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - chainId := "chainId" - providerAddr := providertypes.NewProviderConsAddress([]byte("providerAddr")) - _, found := providerKeeper.IsValidatorOptedInToChainId(ctx, providerAddr, chainId) - require.False(t, found) - - expectedConsumerId := "consumerId" - providerKeeper.SetConsumerChainId(ctx, expectedConsumerId, chainId) - providerKeeper.SetOptedIn(ctx, expectedConsumerId, providerAddr) - providerKeeper.AppendOptedInConsumerId(ctx, providerAddr, expectedConsumerId) - actualConsumerId, found := providerKeeper.IsValidatorOptedInToChainId(ctx, providerAddr, chainId) - require.True(t, found) - require.Equal(t, expectedConsumerId, actualConsumerId) -} - func TestUpdateAllowlist(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() @@ -302,7 +547,7 @@ func TestUpdateAllowlist(t *testing.T) { require.Equal(t, expectedAllowlist, providerKeeper.GetAllowList(ctx, consumerId)) } -func TestPopulateDenylist(t *testing.T) { +func TestUpdateDenylist(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() @@ -321,7 +566,7 @@ func TestPopulateDenylist(t *testing.T) { require.Equal(t, expectedDenylist, providerKeeper.GetDenyList(ctx, consumerId)) } -func TestPopulateMinimumPowerInTopN(t *testing.T) { +func TestUpdateMinimumPowerInTopN(t *testing.T) { providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() @@ -380,5 +625,145 @@ func TestPopulateMinimumPowerInTopN(t *testing.T) { minimumPowerInTopN, found = providerKeeper.GetMinimumPowerInTopN(ctx, consumerId) require.True(t, found) require.Equal(t, int64(10), minimumPowerInTopN) +} +func TestIsValidatorOptedInToChain(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainId := "chainId" + providerAddr := providertypes.NewProviderConsAddress([]byte("providerAddr")) + _, found := providerKeeper.IsValidatorOptedInToChainId(ctx, providerAddr, chainId) + require.False(t, found) + + expectedConsumerId := "consumerId" + providerKeeper.SetConsumerChainId(ctx, expectedConsumerId, chainId) + providerKeeper.SetOptedIn(ctx, expectedConsumerId, providerAddr) + providerKeeper.AppendOptedInConsumerId(ctx, providerAddr, expectedConsumerId) + actualConsumerId, found := providerKeeper.IsValidatorOptedInToChainId(ctx, providerAddr, chainId) + require.True(t, found) + require.Equal(t, expectedConsumerId, actualConsumerId) +} + +func TestPrepareConsumerForLaunch(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + spawnTime := time.Now().UTC() + err := providerKeeper.PrepareConsumerForLaunch(ctx, "consumerId", time.Time{}, spawnTime) + require.NoError(t, err) + + consumers, err := providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{Ids: []string{"consumerId"}}, consumers) + + nextSpawnTime := spawnTime.Add(time.Hour) + err = providerKeeper.PrepareConsumerForLaunch(ctx, "consumerId", spawnTime, nextSpawnTime) + require.NoError(t, err) + + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, spawnTime) + require.NoError(t, err) + require.Empty(t, consumers) + + consumers, err = providerKeeper.GetConsumersToBeLaunched(ctx, nextSpawnTime) + require.NoError(t, err) + require.Equal(t, providertypes.ConsumerIds{Ids: []string{"consumerId"}}, consumers) +} + +func TestCanLaunch(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // cannot launch an unknown chain + _, canLaunch := providerKeeper.CanLaunch(ctx, "consumerId") + require.False(t, canLaunch) + + // cannot launch a chain without initialization parameters + providerKeeper.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + _, canLaunch = providerKeeper.CanLaunch(ctx, "consumerId") + require.False(t, canLaunch) + + // set valid initialization parameters + initializationParameters := testkeeper.GetTestInitializationParameters() + err := providerKeeper.SetConsumerInitializationParameters(ctx, "consumerId", initializationParameters) + require.NoError(t, err) + + // cannot launch a launched chain + providerKeeper.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) + _, canLaunch = providerKeeper.CanLaunch(ctx, "consumerId") + require.False(t, canLaunch) + + // cannot launch a stopped chain + providerKeeper.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_STOPPED) + _, canLaunch = providerKeeper.CanLaunch(ctx, "consumerId") + require.False(t, canLaunch) + + // initialized chain can launch + providerKeeper.SetConsumerPhase(ctx, "consumerId", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + _, canLaunch = providerKeeper.CanLaunch(ctx, "consumerId") + require.True(t, canLaunch) + + // chain cannot launch without a genesis hash + initializationParameters.GenesisHash = nil + err = providerKeeper.SetConsumerInitializationParameters(ctx, "consumerId", initializationParameters) + _, canLaunch = providerKeeper.CanLaunch(ctx, "consumerId") + require.NoError(t, err) + require.False(t, canLaunch) +} + +func TestHasAtMostOnceCorrectMsgUpdateConsumer(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + expectedMsgUpdateConsumer := providertypes.MsgUpdateConsumer{Signer: "signer", ConsumerId: "consumerId", NewOwnerAddress: "new owner address"} + + proposal, err := govv1.NewProposal([]sdk.Msg{&expectedMsgUpdateConsumer}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", sdk.AccAddress{}, false) + require.NoError(t, err) + + _, err = providerKeeper.HasAtMostOnceCorrectMsgUpdateConsumer(ctx, &proposal) + require.ErrorContains(t, err, "cannot find owner address") + + // set owner address that is not the gov module + providerKeeper.SetConsumerOwnerAddress(ctx, "consumerId", "owner address") + _, err = providerKeeper.HasAtMostOnceCorrectMsgUpdateConsumer(ctx, &proposal) + require.ErrorContains(t, err, "is not the gov module") + + // set owner address that is the gov module + providerKeeper.SetConsumerOwnerAddress(ctx, "consumerId", "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn") + actualMsgUpdateConsumer, err := providerKeeper.HasAtMostOnceCorrectMsgUpdateConsumer(ctx, &proposal) + require.NoError(t, err) + require.Equal(t, expectedMsgUpdateConsumer, *actualMsgUpdateConsumer) + + // a proposal with 2 `MsgUpdateConsumer` messages + invalidProposal, err := govv1.NewProposal([]sdk.Msg{&expectedMsgUpdateConsumer, &expectedMsgUpdateConsumer}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", sdk.AccAddress{}, false) + actualMsgUpdateConsumer, err = providerKeeper.HasAtMostOnceCorrectMsgUpdateConsumer(ctx, &invalidProposal) + require.ErrorContains(t, err, "proposal can contain at most one") + require.Nil(t, actualMsgUpdateConsumer) +} + +func TestDoesNotHaveDeprecatedMessage(t *testing.T) { + msgConsumerAddition := providertypes.MsgConsumerAddition{} + proposal, err := govv1.NewProposal([]sdk.Msg{&msgConsumerAddition}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", sdk.AccAddress{}, false) + require.NoError(t, err) + err = keeper.DoesNotHaveDeprecatedMessage(&proposal) + require.ErrorContains(t, err, "cannot contain deprecated `MsgConsumerAddition`") + + msgConsumerModification := providertypes.MsgConsumerModification{} + proposal, err = govv1.NewProposal([]sdk.Msg{&msgConsumerModification}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", sdk.AccAddress{}, false) + require.NoError(t, err) + err = keeper.DoesNotHaveDeprecatedMessage(&proposal) + require.ErrorContains(t, err, "cannot contain deprecated `MsgConsumerModification`") + + msgConsumerRemoval := providertypes.MsgConsumerRemoval{} + proposal, err = govv1.NewProposal([]sdk.Msg{&msgConsumerRemoval}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", sdk.AccAddress{}, false) + require.NoError(t, err) + err = keeper.DoesNotHaveDeprecatedMessage(&proposal) + require.ErrorContains(t, err, "cannot contain deprecated `MsgConsumerRemoval`") + + // a proposal with no deprecated messages + msgUpdateConsumer := providertypes.MsgUpdateConsumer{Signer: "signer", ConsumerId: "consumerId", NewOwnerAddress: "new owner address"} + proposal, err = govv1.NewProposal([]sdk.Msg{&msgUpdateConsumer}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", sdk.AccAddress{}, false) + require.NoError(t, err) + err = keeper.DoesNotHaveDeprecatedMessage(&proposal) + require.Nil(t, err) } diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index d13ad3d2bd..a175518257 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -42,10 +42,10 @@ func (k Keeper) CreateConsumerClient(ctx sdk.Context, consumerId string) error { return err } - phase, found := k.GetConsumerPhase(ctx, consumerId) - if !found || phase != Initialized { + phase := k.GetConsumerPhase(ctx, consumerId) + if phase != types.ConsumerPhase_CONSUMER_PHASE_INITIALIZED { return errorsmod.Wrapf(types.ErrInvalidPhase, - "cannot create client for consumer chain that is not in the Initialized phase: %s", consumerId) + "cannot create client for consumer chain that is not in the Initialized phase but in phase %d: %s", phase, consumerId) } chainId, err := k.GetConsumerChainId(ctx, consumerId) @@ -94,7 +94,7 @@ func (k Keeper) CreateConsumerClient(ctx sdk.Context, consumerId string) error { k.SetConsumerClientId(ctx, consumerId, clientID) k.SetClientIdToConsumerId(ctx, clientID, consumerId) - k.Logger(ctx).Info("consumer chain registered (client created)", + k.Logger(ctx).Info("consumer chain launched (client created)", "consumer id", consumerId, "client id", clientID, ) @@ -232,6 +232,7 @@ func (k Keeper) MakeConsumerGenesis( return gen, nil, errorsmod.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting last bonded validators: %s", err) } + minPower := int64(0) if powerShapingParameters.Top_N > 0 { // get the consensus active validators // we do not want to base the power calculation for the top N @@ -243,7 +244,7 @@ func (k Keeper) MakeConsumerGenesis( } // in a Top-N chain, we automatically opt in all validators that belong to the top N - minPower, err := k.ComputeMinPowerInTopN(ctx, activeValidators, powerShapingParameters.Top_N) + minPower, err = k.ComputeMinPowerInTopN(ctx, activeValidators, powerShapingParameters.Top_N) if err != nil { return gen, nil, err } @@ -255,8 +256,9 @@ func (k Keeper) MakeConsumerGenesis( k.OptInTopNValidators(ctx, consumerId, activeValidators, minPower) k.SetMinimumPowerInTopN(ctx, consumerId, minPower) } + // need to use the bondedValidators, not activeValidators, here since the chain might be opt-in and allow inactive vals - nextValidators := k.ComputeNextValidators(ctx, consumerId, bondedValidators) + nextValidators := k.ComputeNextValidators(ctx, consumerId, bondedValidators, minPower) k.SetConsumerValSet(ctx, consumerId, nextValidators) // get the initial updates with the latest set consumer public keys @@ -345,7 +347,7 @@ func (k Keeper) BeginBlockInit(ctx sdk.Context) { } // Remove consumer to prevent re-trying launching this chain. // We would only try to re-launch this chain if a new `MsgUpdateConsumer` message is sent. - k.RemoveConsumerFromToBeLaunchedConsumers(ctx, consumerId, record.SpawnTime) + k.RemoveConsumerToBeLaunchedFromSpawnTime(ctx, consumerId, record.SpawnTime) cachedCtx, writeFn := ctx.CacheContext() err = k.LaunchConsumer(cachedCtx, consumerId) @@ -355,8 +357,10 @@ func (k Keeper) BeginBlockInit(ctx sdk.Context) { "error", err) continue } - k.SetConsumerPhase(cachedCtx, consumerId, Launched) + k.SetConsumerPhase(cachedCtx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) + // the cached context is created with a new EventManager, so we merge the events into the original context + ctx.EventManager().EmitEvents(cachedCtx.EventManager().Events()) writeFn() } } @@ -486,13 +490,13 @@ func (k Keeper) BeginBlockCCR(ctx sdk.Context) { "err", err.Error()) continue } - // The cached context is created with a new EventManager so we merge the event - // into the original context - // TODO (PERMISSIONLESS): verify this here and in the initialized chains to launch + + k.SetConsumerPhase(cachedCtx, consumerId, types.ConsumerPhase_CONSUMER_PHASE_STOPPED) + k.RemoveConsumerToBeStoppedFromStopTime(ctx, consumerId, stopTime) + + // The cached context is created with a new EventManager so we merge the event into the original context ctx.EventManager().EmitEvents(cachedCtx.EventManager().Events()) - k.SetConsumerPhase(cachedCtx, consumerId, Stopped) - k.RemoveConsumerFromToBeStoppedConsumers(ctx, consumerId, stopTime) writeFn() k.Logger(ctx).Info("executed consumer removal", diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index 1aef84957f..2386ab65f2 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -4,11 +4,12 @@ import ( "bytes" "encoding/json" "fmt" - cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" "sort" "testing" "time" + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "cosmossdk.io/math" @@ -45,7 +46,7 @@ func TestCreateConsumerClient(t *testing.T) { { description: "No state mutation, new client should be created", setup: func(providerKeeper *providerkeeper.Keeper, ctx sdk.Context, mocks *testkeeper.MockedKeepers) { - providerKeeper.SetConsumerPhase(ctx, "0", providerkeeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, "0", providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) // Valid client creation is asserted with mock expectations here testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 0, []stakingtypes.Validator{}, 1) // returns empty validator set @@ -58,7 +59,7 @@ func TestCreateConsumerClient(t *testing.T) { { description: "chain for this consumer id has already launched, and hence client was created, NO new one is created", setup: func(providerKeeper *providerkeeper.Keeper, ctx sdk.Context, mocks *testkeeper.MockedKeepers) { - providerKeeper.SetConsumerPhase(ctx, "0", providerkeeper.Launched) + providerKeeper.SetConsumerPhase(ctx, "0", providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) // Expect none of the client creation related calls to happen mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Times(0) @@ -804,8 +805,8 @@ func TestBeginBlockInit(t *testing.T) { for i, r := range initializationParameters { providerKeeper.SetConsumerInitializationParameters(ctx, fmt.Sprintf("%d", i), r) // set up the chains in their initialized phase, hence they could launch - providerKeeper.SetConsumerPhase(ctx, fmt.Sprintf("%d", i), providerkeeper.Initialized) - providerKeeper.AppendSpawnTimeForConsumerToBeLaunched(ctx, fmt.Sprintf("%d", i), r.SpawnTime) + providerKeeper.SetConsumerPhase(ctx, fmt.Sprintf("%d", i), providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) + providerKeeper.AppendConsumerToBeLaunchedOnSpawnTime(ctx, fmt.Sprintf("%d", i), r.SpawnTime) } for i, r := range powerShapingParameters { providerKeeper.SetConsumerPowerShapingParameters(ctx, fmt.Sprintf("%d", i), r) @@ -826,39 +827,34 @@ func TestBeginBlockInit(t *testing.T) { providerKeeper.BeginBlockInit(ctx) // first chain was successfully launched - phase, found := providerKeeper.GetConsumerPhase(ctx, "0") - require.True(t, found) - require.Equal(t, providerkeeper.Launched, phase) - _, found = providerKeeper.GetConsumerGenesis(ctx, "0") + phase := providerKeeper.GetConsumerPhase(ctx, "0") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED, phase) + _, found := providerKeeper.GetConsumerGenesis(ctx, "0") require.True(t, found) // second chain was successfully launched - phase, found = providerKeeper.GetConsumerPhase(ctx, "1") - require.True(t, found) - require.Equal(t, providerkeeper.Launched, phase) + phase = providerKeeper.GetConsumerPhase(ctx, "1") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED, phase) _, found = providerKeeper.GetConsumerGenesis(ctx, "1") require.True(t, found) // third chain was not launched because its spawn time has not passed - phase, found = providerKeeper.GetConsumerPhase(ctx, "2") - require.True(t, found) - require.Equal(t, providerkeeper.Initialized, phase) + phase = providerKeeper.GetConsumerPhase(ctx, "2") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED, phase) _, found = providerKeeper.GetConsumerGenesis(ctx, "2") require.False(t, found) // fourth chain corresponds to an Opt-In chain with one opted-in validator and hence the chain gets // successfully executed - phase, found = providerKeeper.GetConsumerPhase(ctx, "3") - require.True(t, found) - require.Equal(t, providerkeeper.Launched, phase) + phase = providerKeeper.GetConsumerPhase(ctx, "3") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED, phase) _, found = providerKeeper.GetConsumerGenesis(ctx, "3") require.True(t, found) // fifth chain corresponds to an Opt-In chain with no opted-in validators and hence the // chain launch is NOT successful - phase, found = providerKeeper.GetConsumerPhase(ctx, "4") - require.True(t, found) - require.Equal(t, providerkeeper.Initialized, phase) + phase = providerKeeper.GetConsumerPhase(ctx, "4") + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED, phase) _, found = providerKeeper.GetConsumerGenesis(ctx, "4") require.False(t, found) } @@ -875,11 +871,11 @@ func TestBeginBlockCCR(t *testing.T) { chainIds := []string{"chain1", "chain2", "chain3"} consumerIds := []string{"consumerId1", "consumerId2", "consumerId3"} providerKeeper.SetConsumerStopTime(ctx, consumerIds[0], now.Add(-time.Hour)) - providerKeeper.AppendStopTimeForConsumerToBeStopped(ctx, consumerIds[0], now.Add(-time.Hour)) + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, consumerIds[0], now.Add(-time.Hour)) providerKeeper.SetConsumerStopTime(ctx, consumerIds[1], now) - providerKeeper.AppendStopTimeForConsumerToBeStopped(ctx, consumerIds[1], now) + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, consumerIds[1], now) providerKeeper.SetConsumerStopTime(ctx, consumerIds[2], now.Add(time.Hour)) - providerKeeper.AppendStopTimeForConsumerToBeStopped(ctx, consumerIds[2], now.Add(time.Hour)) + providerKeeper.AppendConsumerToBeStoppedOnStopTime(ctx, consumerIds[2], now.Add(time.Hour)) // // Mock expectations @@ -912,7 +908,7 @@ func TestBeginBlockCCR(t *testing.T) { providerKeeper.SetConsumerMetadata(ctx, consumerId, registrationRecord) providerKeeper.SetConsumerInitializationParameters(ctx, consumerId, initializationRecord) providerKeeper.SetConsumerPowerShapingParameters(ctx, consumerId, testkeeper.GetTestPowerShapingParameters()) - providerKeeper.SetConsumerPhase(ctx, consumerId, providerkeeper.Initialized) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.ConsumerPhase_CONSUMER_PHASE_INITIALIZED) providerKeeper.SetClientIdToConsumerId(ctx, "clientID", consumerId) err := providerKeeper.CreateConsumerClient(ctx, consumerId) @@ -921,7 +917,7 @@ func TestBeginBlockCCR(t *testing.T) { require.NoError(t, err) // after we have created the consumer client, the chain is considered launched and hence we could later stop the chain - providerKeeper.SetConsumerPhase(ctx, consumerId, providerkeeper.Launched) + providerKeeper.SetConsumerPhase(ctx, consumerId, providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED) } // @@ -931,14 +927,11 @@ func TestBeginBlockCCR(t *testing.T) { providerKeeper.BeginBlockCCR(ctx) // Only the 3rd (final) proposal is still stored as pending - phase, found := providerKeeper.GetConsumerPhase(ctx, consumerIds[0]) - require.True(t, found) - require.Equal(t, providerkeeper.Stopped, phase) - phase, found = providerKeeper.GetConsumerPhase(ctx, consumerIds[1]) - require.True(t, found) - require.Equal(t, providerkeeper.Stopped, phase) + phase := providerKeeper.GetConsumerPhase(ctx, consumerIds[0]) + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_STOPPED, phase) + phase = providerKeeper.GetConsumerPhase(ctx, consumerIds[1]) + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_STOPPED, phase) // third chain had a stopTime in the future and hence did not stop - phase, found = providerKeeper.GetConsumerPhase(ctx, consumerIds[2]) - require.True(t, found) - require.Equal(t, providerkeeper.Launched, phase) + phase = providerKeeper.GetConsumerPhase(ctx, consumerIds[2]) + require.Equal(t, providertypes.ConsumerPhase_CONSUMER_PHASE_LAUNCHED, phase) } diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index b0e8bb4e83..cfa8ec5a9f 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -199,6 +199,7 @@ func (k Keeper) QueueVSCPackets(ctx sdk.Context) { } topN := k.GetTopN(ctx, consumerId) + minPower := int64(0) if topN > 0 { // in a Top-N chain, we automatically opt in all validators that belong to the top N // of the active validators @@ -208,7 +209,7 @@ func (k Keeper) QueueVSCPackets(ctx sdk.Context) { panic(fmt.Errorf("failed to get active validators: %w", err)) } - minPower, err := k.ComputeMinPowerInTopN(ctx, activeValidators, topN) + minPower, err = k.ComputeMinPowerInTopN(ctx, activeValidators, topN) if err != nil { // we panic, since the only way to proceed would be to opt in all validators, which is not the intended behavior panic(fmt.Errorf("failed to compute min power to opt in for chain %v: %w", consumerId, err)) @@ -220,7 +221,7 @@ func (k Keeper) QueueVSCPackets(ctx sdk.Context) { k.OptInTopNValidators(ctx, consumerId, activeValidators, minPower) } - nextValidators := k.ComputeNextValidators(ctx, consumerId, bondedValidators) + nextValidators := k.ComputeNextValidators(ctx, consumerId, bondedValidators, minPower) valUpdates := DiffValidators(currentValidators, nextValidators) k.SetConsumerValSet(ctx, consumerId, nextValidators) diff --git a/x/ccv/provider/types/errors.go b/x/ccv/provider/types/errors.go index 94e9e5669a..b7ab44d029 100644 --- a/x/ccv/provider/types/errors.go +++ b/x/ccv/provider/types/errors.go @@ -47,4 +47,5 @@ var ( ErrInvalidTransformToTopN = errorsmod.Register(ModuleName, 39, "invalid transform to Top N chain") ErrInvalidTransformToOptIn = errorsmod.Register(ModuleName, 40, "invalid transform to Opt In chain") ErrCannotCreateTopNChain = errorsmod.Register(ModuleName, 41, "cannot create Top N chain outside permissionlessly") + ErrCannotPrepareForLaunch = errorsmod.Register(ModuleName, 42, "cannot prepare chain for launch") ) diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 21b9173eca..08a4b516c9 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -3,11 +3,12 @@ package types import ( "encoding/json" "fmt" - cmttypes "github.com/cometbft/cometbft/types" "strconv" "strings" "time" + cmttypes "github.com/cometbft/cometbft/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" @@ -368,7 +369,7 @@ func (msg MsgUpdateConsumer) GetSigners() []sdk.AccAddress { // NewMsgRemoveConsumer creates a new MsgRemoveConsumer instance func NewMsgRemoveConsumer(signer string, consumerId string, stopTime time.Time) (*MsgRemoveConsumer, error) { return &MsgRemoveConsumer{ - Authority: signer, + Signer: signer, ConsumerId: consumerId, StopTime: stopTime, }, nil @@ -399,7 +400,7 @@ func (msg MsgRemoveConsumer) GetSignBytes() []byte { // GetSigners implements the sdk.Msg interface. It returns the address(es) that // must sign over msg.GetSignBytes(). func (msg MsgRemoveConsumer) GetSigners() []sdk.AccAddress { - valAddr, err := sdk.ValAddressFromBech32(msg.Authority) + valAddr, err := sdk.ValAddressFromBech32(msg.Signer) if err != nil { // same behavior as in cosmos-sdk panic(err) diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index a0d0fa1dd8..1c0755344d 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -37,6 +37,49 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// ConsumerPhase indicates the phases of a consumer chain according to ADR 019 +type ConsumerPhase int32 + +const ( + // UNSPECIFIED defines an empty phase. + ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED ConsumerPhase = 0 + // REGISTERED defines the phase in which a consumer chain has been assigned a unique consumer id. + // A chain in this phase cannot yet launch. + ConsumerPhase_CONSUMER_PHASE_REGISTERED ConsumerPhase = 1 + // INITIALIZED defines the phase in which a consumer chain has set all the needed parameters to launch but + // has not yet launched (e.g., because the `spawnTime` of the consumer chain has not yet been reached). + ConsumerPhase_CONSUMER_PHASE_INITIALIZED ConsumerPhase = 2 + // LAUNCHED defines the phase in which a consumer chain is running and consuming a subset of the validator + // set of the provider. + ConsumerPhase_CONSUMER_PHASE_LAUNCHED ConsumerPhase = 3 + // STOPPED defines the phase in which a previously-launched chain has stopped. + ConsumerPhase_CONSUMER_PHASE_STOPPED ConsumerPhase = 4 +) + +var ConsumerPhase_name = map[int32]string{ + 0: "CONSUMER_PHASE_UNSPECIFIED", + 1: "CONSUMER_PHASE_REGISTERED", + 2: "CONSUMER_PHASE_INITIALIZED", + 3: "CONSUMER_PHASE_LAUNCHED", + 4: "CONSUMER_PHASE_STOPPED", +} + +var ConsumerPhase_value = map[string]int32{ + "CONSUMER_PHASE_UNSPECIFIED": 0, + "CONSUMER_PHASE_REGISTERED": 1, + "CONSUMER_PHASE_INITIALIZED": 2, + "CONSUMER_PHASE_LAUNCHED": 3, + "CONSUMER_PHASE_STOPPED": 4, +} + +func (x ConsumerPhase) String() string { + return proto.EnumName(ConsumerPhase_name, int32(x)) +} + +func (ConsumerPhase) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_f22ec409a72b7b72, []int{0} +} + // WARNING: This message is deprecated in favor of `MsgCreateConsumer`. // ConsumerAdditionProposal is a governance proposal on the provider chain to // spawn a new consumer chain. If it passes, then all validators on the provider @@ -1752,6 +1795,7 @@ func (m *ConsumerIds) GetIds() []string { } func init() { + proto.RegisterEnum("interchain_security.ccv.provider.v1.ConsumerPhase", ConsumerPhase_name, ConsumerPhase_value) proto.RegisterType((*ConsumerAdditionProposal)(nil), "interchain_security.ccv.provider.v1.ConsumerAdditionProposal") proto.RegisterType((*ConsumerRemovalProposal)(nil), "interchain_security.ccv.provider.v1.ConsumerRemovalProposal") proto.RegisterType((*ConsumerModificationProposal)(nil), "interchain_security.ccv.provider.v1.ConsumerModificationProposal") @@ -1782,140 +1826,146 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 2119 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcf, 0x6f, 0x1b, 0xc7, - 0xf5, 0xd7, 0x8a, 0x94, 0x44, 0x0e, 0xf5, 0x83, 0x1a, 0x3b, 0xf6, 0x4a, 0xd1, 0x97, 0xa4, 0x37, - 0x5f, 0x1b, 0x6c, 0x5c, 0x2f, 0x23, 0x05, 0x05, 0x0c, 0xb7, 0x81, 0x21, 0x51, 0x4e, 0x2c, 0xa9, - 0x71, 0xd8, 0x95, 0xa0, 0x00, 0xe9, 0x61, 0x31, 0xdc, 0x1d, 0x91, 0x53, 0xed, 0xee, 0xac, 0x67, - 0x86, 0x2b, 0xb3, 0x87, 0x9e, 0x8b, 0x02, 0x05, 0xd2, 0x9e, 0x82, 0x5e, 0x9a, 0x63, 0xd1, 0x53, - 0x0f, 0x45, 0xff, 0x80, 0x9e, 0x82, 0x02, 0x45, 0x73, 0xec, 0x29, 0x29, 0xec, 0x43, 0x0f, 0x05, - 0x7a, 0xed, 0xb5, 0x98, 0xd9, 0x1f, 0x5c, 0xea, 0x97, 0x69, 0x58, 0xee, 0x45, 0xda, 0x79, 0xef, - 0xf3, 0xde, 0xbc, 0x99, 0x79, 0xbf, 0x66, 0x08, 0x36, 0x48, 0x20, 0x30, 0x73, 0xfa, 0x88, 0x04, - 0x36, 0xc7, 0xce, 0x80, 0x11, 0x31, 0x6c, 0x39, 0x4e, 0xd4, 0x0a, 0x19, 0x8d, 0x88, 0x8b, 0x59, - 0x2b, 0x5a, 0xcf, 0xbe, 0xcd, 0x90, 0x51, 0x41, 0xe1, 0x3b, 0xe7, 0xc8, 0x98, 0x8e, 0x13, 0x99, - 0x19, 0x2e, 0x5a, 0x5f, 0xbd, 0x7d, 0x91, 0xe2, 0x68, 0xbd, 0x75, 0x42, 0x18, 0x8e, 0x75, 0xad, - 0x5e, 0xef, 0xd1, 0x1e, 0x55, 0x9f, 0x2d, 0xf9, 0x95, 0x50, 0xeb, 0x3d, 0x4a, 0x7b, 0x1e, 0x6e, - 0xa9, 0x51, 0x77, 0x70, 0xd4, 0x12, 0xc4, 0xc7, 0x5c, 0x20, 0x3f, 0x4c, 0x00, 0xb5, 0xd3, 0x00, - 0x77, 0xc0, 0x90, 0x20, 0x34, 0x48, 0x15, 0x90, 0xae, 0xd3, 0x72, 0x28, 0xc3, 0x2d, 0xc7, 0x23, - 0x38, 0x10, 0x72, 0xd6, 0xf8, 0x2b, 0x01, 0xb4, 0x24, 0xc0, 0x23, 0xbd, 0xbe, 0x88, 0xc9, 0xbc, - 0x25, 0x70, 0xe0, 0x62, 0xe6, 0x93, 0x18, 0x3c, 0x1a, 0x25, 0x02, 0x6b, 0x39, 0xbe, 0xc3, 0x86, - 0xa1, 0xa0, 0xad, 0x63, 0x3c, 0xe4, 0x09, 0xf7, 0x8e, 0x43, 0xb9, 0x4f, 0x79, 0x0b, 0xcb, 0xf5, - 0x07, 0x0e, 0x6e, 0x45, 0xeb, 0x5d, 0x2c, 0xd0, 0x7a, 0x46, 0x48, 0xed, 0x4e, 0x70, 0x5d, 0xc4, - 0x47, 0x18, 0x87, 0x92, 0xd4, 0xee, 0x95, 0x98, 0x6f, 0xc7, 0x3b, 0x12, 0x0f, 0x12, 0xd6, 0x32, - 0xf2, 0x49, 0x40, 0x5b, 0xea, 0x6f, 0x4c, 0x32, 0xfe, 0x53, 0x02, 0x7a, 0x9b, 0x06, 0x7c, 0xe0, - 0x63, 0xb6, 0xe9, 0xba, 0x44, 0x6e, 0x40, 0x87, 0xd1, 0x90, 0x72, 0xe4, 0xc1, 0xeb, 0x60, 0x46, - 0x10, 0xe1, 0x61, 0x5d, 0x6b, 0x68, 0xcd, 0xb2, 0x15, 0x0f, 0x60, 0x03, 0x54, 0x5c, 0xcc, 0x1d, - 0x46, 0x42, 0x09, 0xd6, 0xa7, 0x15, 0x2f, 0x4f, 0x82, 0x2b, 0xa0, 0x14, 0x9f, 0x1a, 0x71, 0xf5, - 0x82, 0x62, 0xcf, 0xa9, 0xf1, 0x8e, 0x0b, 0x3f, 0x02, 0x8b, 0x24, 0x20, 0x82, 0x20, 0xcf, 0xee, - 0x63, 0xb9, 0x77, 0x7a, 0xb1, 0xa1, 0x35, 0x2b, 0x1b, 0xab, 0x26, 0xe9, 0x3a, 0xa6, 0xdc, 0x6e, - 0x33, 0xd9, 0xe4, 0x68, 0xdd, 0x7c, 0xac, 0x10, 0x5b, 0xc5, 0xaf, 0xbe, 0xa9, 0x4f, 0x59, 0x0b, - 0x89, 0x5c, 0x4c, 0x84, 0xb7, 0xc0, 0x7c, 0x0f, 0x07, 0x98, 0x13, 0x6e, 0xf7, 0x11, 0xef, 0xeb, - 0x33, 0x0d, 0xad, 0x39, 0x6f, 0x55, 0x12, 0xda, 0x63, 0xc4, 0xfb, 0xb0, 0x0e, 0x2a, 0x5d, 0x12, - 0x20, 0x36, 0x8c, 0x11, 0xb3, 0x0a, 0x01, 0x62, 0x92, 0x02, 0xb4, 0x01, 0xe0, 0x21, 0x3a, 0x09, - 0x6c, 0xe9, 0x1b, 0xfa, 0x5c, 0x62, 0x48, 0xec, 0x17, 0x66, 0xea, 0x17, 0xe6, 0x41, 0xea, 0x38, - 0x5b, 0x25, 0x69, 0xc8, 0xe7, 0xdf, 0xd6, 0x35, 0xab, 0xac, 0xe4, 0x24, 0x07, 0x3e, 0x01, 0xd5, - 0x41, 0xd0, 0xa5, 0x81, 0x4b, 0x82, 0x9e, 0x1d, 0x62, 0x46, 0xa8, 0xab, 0x97, 0x94, 0xaa, 0x95, - 0x33, 0xaa, 0xb6, 0x13, 0x17, 0x8b, 0x35, 0x7d, 0x21, 0x35, 0x2d, 0x65, 0xc2, 0x1d, 0x25, 0x0b, - 0x7f, 0x04, 0xa0, 0xe3, 0x44, 0xca, 0x24, 0x3a, 0x10, 0xa9, 0xc6, 0xf2, 0xe4, 0x1a, 0xab, 0x8e, - 0x13, 0x1d, 0xc4, 0xd2, 0x89, 0xca, 0x1f, 0x83, 0x9b, 0x82, 0xa1, 0x80, 0x1f, 0x61, 0x76, 0x5a, - 0x2f, 0x98, 0x5c, 0xef, 0x5b, 0xa9, 0x8e, 0x71, 0xe5, 0x8f, 0x41, 0xc3, 0x49, 0x1c, 0xc8, 0x66, - 0xd8, 0x25, 0x5c, 0x30, 0xd2, 0x1d, 0x48, 0x59, 0xfb, 0x88, 0x21, 0x47, 0xf9, 0x48, 0x45, 0x39, - 0x41, 0x2d, 0xc5, 0x59, 0x63, 0xb0, 0x0f, 0x13, 0x14, 0xfc, 0x04, 0xfc, 0x7f, 0xd7, 0xa3, 0xce, - 0x31, 0x97, 0xc6, 0xd9, 0x63, 0x9a, 0xd4, 0xd4, 0x3e, 0xe1, 0x5c, 0x6a, 0x9b, 0x6f, 0x68, 0xcd, - 0x82, 0x75, 0x2b, 0xc6, 0x76, 0x30, 0xdb, 0xce, 0x21, 0x0f, 0x72, 0x40, 0x78, 0x0f, 0xc0, 0x3e, - 0xe1, 0x82, 0x32, 0xe2, 0x20, 0xcf, 0xc6, 0x81, 0x60, 0x04, 0x73, 0x7d, 0x41, 0x89, 0x2f, 0x8f, - 0x38, 0x8f, 0x62, 0x06, 0xdc, 0x05, 0xb7, 0x2e, 0x9c, 0xd4, 0x76, 0xfa, 0x28, 0x08, 0xb0, 0xa7, - 0x2f, 0xaa, 0xa5, 0xd4, 0xdd, 0x0b, 0xe6, 0x6c, 0xc7, 0x30, 0x78, 0x0d, 0xcc, 0x08, 0x1a, 0xda, - 0x4f, 0xf4, 0xa5, 0x86, 0xd6, 0x5c, 0xb0, 0x8a, 0x82, 0x86, 0x4f, 0xe0, 0x7b, 0xe0, 0x7a, 0x84, - 0x3c, 0xe2, 0x22, 0x41, 0x19, 0xb7, 0x43, 0x7a, 0x82, 0x99, 0xed, 0xa0, 0x50, 0xaf, 0x2a, 0x0c, - 0x1c, 0xf1, 0x3a, 0x92, 0xd5, 0x46, 0x21, 0x7c, 0x17, 0x2c, 0x67, 0x54, 0x9b, 0x63, 0xa1, 0xe0, - 0xcb, 0x0a, 0xbe, 0x94, 0x31, 0xf6, 0xb1, 0x90, 0xd8, 0x35, 0x50, 0x46, 0x9e, 0x47, 0x4f, 0x3c, - 0xc2, 0x85, 0x0e, 0x1b, 0x85, 0x66, 0xd9, 0x1a, 0x11, 0xe0, 0x2a, 0x28, 0xb9, 0x38, 0x18, 0x2a, - 0xe6, 0x35, 0xc5, 0xcc, 0xc6, 0xf0, 0x6d, 0x50, 0xf6, 0x65, 0x8e, 0x15, 0xe8, 0x18, 0xeb, 0xd7, - 0x1b, 0x5a, 0xb3, 0x68, 0x95, 0x7c, 0x12, 0xec, 0xcb, 0x31, 0x34, 0xc1, 0x35, 0xa5, 0xc5, 0x26, - 0x81, 0x3c, 0xa7, 0x08, 0xdb, 0x11, 0xf2, 0xb8, 0xfe, 0x56, 0x43, 0x6b, 0x96, 0xac, 0x65, 0xc5, - 0xda, 0x49, 0x38, 0x87, 0xc8, 0xe3, 0x0f, 0xee, 0xfc, 0xfc, 0xcb, 0xfa, 0xd4, 0x17, 0x5f, 0xd6, - 0xa7, 0xfe, 0xf2, 0xc7, 0x7b, 0xab, 0x49, 0xfa, 0xe9, 0xd1, 0xc8, 0x4c, 0x52, 0x95, 0xd9, 0xa6, - 0x81, 0xc0, 0x81, 0x30, 0xfe, 0xa6, 0x81, 0x9b, 0xed, 0xcc, 0x21, 0x7c, 0x1a, 0x21, 0xef, 0x4d, - 0x26, 0x9e, 0x4d, 0x50, 0xe6, 0xf2, 0x44, 0x54, 0xa8, 0x17, 0x5f, 0x21, 0xd4, 0x4b, 0x52, 0x4c, - 0x32, 0x1e, 0xd4, 0x5e, 0xb2, 0xa2, 0x7f, 0x4d, 0x83, 0xb5, 0x74, 0x45, 0x1f, 0x53, 0x97, 0x1c, - 0x11, 0x07, 0xbd, 0xe9, 0x7c, 0x9a, 0xf9, 0x59, 0x71, 0x02, 0x3f, 0x9b, 0x79, 0x35, 0x3f, 0x9b, - 0x9d, 0xc0, 0xcf, 0xe6, 0x2e, 0xf3, 0xb3, 0xd2, 0x65, 0x7e, 0x56, 0x9e, 0xcc, 0xcf, 0xc0, 0x05, - 0x7e, 0x66, 0xfc, 0x56, 0x03, 0xd7, 0x1f, 0x3d, 0x1d, 0x90, 0x88, 0x5e, 0xd1, 0x2e, 0xef, 0x81, - 0x05, 0x9c, 0xd3, 0xc7, 0xf5, 0x42, 0xa3, 0xd0, 0xac, 0x6c, 0xdc, 0x36, 0x93, 0x23, 0xcf, 0xea, - 0x70, 0x7a, 0xee, 0xf9, 0xd9, 0xad, 0x71, 0xd9, 0x07, 0xd3, 0xba, 0x66, 0xfc, 0x59, 0x03, 0xab, - 0x32, 0x1f, 0xf4, 0xb0, 0x85, 0x4f, 0x10, 0x73, 0xb7, 0x71, 0x40, 0x7d, 0xfe, 0xda, 0x76, 0x1a, - 0x60, 0xc1, 0x55, 0x9a, 0x6c, 0x41, 0x6d, 0xe4, 0xba, 0xca, 0x4e, 0x85, 0x91, 0xc4, 0x03, 0xba, - 0xe9, 0xba, 0xb0, 0x09, 0xaa, 0x23, 0x0c, 0x93, 0xd1, 0x25, 0x9d, 0x5e, 0xc2, 0x16, 0x53, 0x98, - 0x8a, 0xb9, 0x09, 0x9c, 0x5a, 0x03, 0xd5, 0x8f, 0x3c, 0xda, 0x45, 0xde, 0xbe, 0x87, 0x78, 0x5f, - 0xe6, 0xca, 0xa1, 0x0c, 0x26, 0x86, 0x93, 0x22, 0xa5, 0xcc, 0x9f, 0x38, 0x98, 0xa4, 0x98, 0x2a, - 0x9b, 0x0f, 0xc1, 0x72, 0x56, 0x36, 0x32, 0xe7, 0x56, 0xab, 0xdd, 0xba, 0xf6, 0xfc, 0x9b, 0xfa, - 0x52, 0x1a, 0x48, 0x6d, 0xe5, 0xe8, 0xdb, 0xd6, 0x92, 0x33, 0x46, 0x70, 0x61, 0x0d, 0x54, 0x48, - 0xd7, 0xb1, 0x39, 0x7e, 0x6a, 0x07, 0x03, 0x5f, 0xc5, 0x45, 0xd1, 0x2a, 0x93, 0xae, 0xb3, 0x8f, - 0x9f, 0x3e, 0x19, 0xf8, 0xf0, 0x7d, 0x70, 0x23, 0x6d, 0x26, 0xa5, 0x27, 0xd9, 0x52, 0x5e, 0x6e, - 0x17, 0x53, 0xa1, 0x32, 0x6f, 0x5d, 0x4b, 0xb9, 0x87, 0xc8, 0x93, 0x93, 0x6d, 0xba, 0x2e, 0x33, - 0xfe, 0x3d, 0x03, 0x66, 0x3b, 0x88, 0x21, 0x9f, 0xc3, 0x03, 0xb0, 0x24, 0xb0, 0x1f, 0x7a, 0x48, - 0x60, 0x3b, 0x6e, 0x49, 0x92, 0x95, 0xde, 0x55, 0xad, 0x4a, 0xbe, 0xf1, 0x33, 0x73, 0xad, 0x5e, - 0xb4, 0x6e, 0xb6, 0x15, 0x75, 0x5f, 0x20, 0x81, 0xad, 0xc5, 0x54, 0x47, 0x4c, 0x84, 0xf7, 0x81, - 0x2e, 0xd8, 0x80, 0x8b, 0x51, 0xb3, 0x30, 0xaa, 0x92, 0xf1, 0x59, 0xdf, 0x48, 0xf9, 0x71, 0x7d, - 0xcd, 0xaa, 0xe3, 0xf9, 0x7d, 0x41, 0xe1, 0x75, 0xfa, 0x02, 0x17, 0xac, 0x71, 0x79, 0xa8, 0xb6, - 0x8f, 0x85, 0xaa, 0xde, 0xa1, 0x87, 0x03, 0xc2, 0xfb, 0xa9, 0xf2, 0xd9, 0xc9, 0x95, 0xaf, 0x28, - 0x45, 0x1f, 0x4b, 0x3d, 0x56, 0xaa, 0x26, 0x99, 0xa5, 0x0d, 0x6a, 0xe7, 0xcf, 0x92, 0x2d, 0x7c, - 0x4e, 0x2d, 0xfc, 0xed, 0x73, 0x54, 0x64, 0xab, 0xe7, 0xe0, 0x4e, 0xae, 0xcb, 0x90, 0xd1, 0x64, - 0x2b, 0x47, 0xb6, 0x19, 0xee, 0xc9, 0x52, 0x8c, 0xe2, 0x86, 0x03, 0xe3, 0xac, 0x53, 0x4a, 0x7c, - 0x5a, 0xb6, 0xc9, 0x39, 0xa7, 0x26, 0x41, 0xd2, 0x4e, 0x1a, 0xa3, 0x66, 0x24, 0x8b, 0x4d, 0x2b, - 0xa7, 0xeb, 0x43, 0x8c, 0x65, 0x14, 0xe5, 0x1a, 0x12, 0x1c, 0x52, 0xa7, 0xaf, 0xf2, 0x51, 0xc1, - 0x5a, 0xcc, 0x9a, 0x8f, 0x47, 0x92, 0x0a, 0x3f, 0x03, 0x77, 0x83, 0x81, 0xdf, 0xc5, 0xcc, 0xa6, - 0x47, 0x31, 0x50, 0x45, 0x1e, 0x17, 0x88, 0x09, 0x9b, 0x61, 0x07, 0x93, 0x48, 0x9e, 0x78, 0x6c, - 0x39, 0x57, 0xfd, 0x50, 0xc1, 0xba, 0x1d, 0x8b, 0x7c, 0x72, 0xa4, 0x74, 0xf0, 0x03, 0xba, 0x2f, - 0xe1, 0x56, 0x8a, 0x8e, 0x0d, 0xe3, 0x70, 0x07, 0xdc, 0xf2, 0xd1, 0x33, 0x3b, 0x73, 0x66, 0x69, - 0x38, 0x0e, 0xf8, 0x80, 0xdb, 0xa3, 0x44, 0x9e, 0xf4, 0x44, 0x35, 0x1f, 0x3d, 0xeb, 0x24, 0xb8, - 0x76, 0x0a, 0x3b, 0xcc, 0x50, 0xbb, 0xc5, 0x52, 0xb1, 0x3a, 0xb3, 0x5b, 0x2c, 0xcd, 0x54, 0x67, - 0x77, 0x8b, 0xa5, 0x52, 0xb5, 0x6c, 0x7c, 0x07, 0x94, 0x55, 0x5c, 0x6f, 0x3a, 0xc7, 0x5c, 0x65, - 0x76, 0xd7, 0x65, 0x98, 0x73, 0xcc, 0x75, 0x2d, 0xc9, 0xec, 0x29, 0xc1, 0x10, 0x60, 0xe5, 0xa2, - 0x9b, 0x02, 0x87, 0x9f, 0x82, 0xb9, 0x10, 0xab, 0x36, 0x56, 0x09, 0x56, 0x36, 0x3e, 0x30, 0x27, - 0xb8, 0xe2, 0x99, 0x17, 0x29, 0xb4, 0x52, 0x6d, 0x06, 0x1b, 0xdd, 0x4f, 0x4e, 0x75, 0x09, 0x1c, - 0x1e, 0x9e, 0x9e, 0xf4, 0x07, 0xaf, 0x34, 0xe9, 0x29, 0x7d, 0xa3, 0x39, 0xef, 0x82, 0xca, 0x66, - 0xbc, 0xec, 0x1f, 0xca, 0xb2, 0x75, 0x66, 0x5b, 0xe6, 0xf3, 0xdb, 0xb2, 0x0b, 0x16, 0x93, 0xa6, - 0xef, 0x80, 0xaa, 0xdc, 0x04, 0xff, 0x0f, 0x80, 0xa4, 0x5b, 0x94, 0x39, 0x2d, 0xce, 0xee, 0xe5, - 0x84, 0xb2, 0xe3, 0x8e, 0x55, 0xf3, 0xe9, 0xb1, 0x6a, 0x6e, 0x50, 0xb0, 0x72, 0x98, 0xaf, 0xb6, - 0xaa, 0x78, 0x74, 0x90, 0x73, 0x8c, 0x05, 0x87, 0x16, 0x28, 0xaa, 0xaa, 0x1a, 0x2f, 0xf5, 0xfe, - 0x85, 0x4b, 0x8d, 0xd6, 0xcd, 0x8b, 0x94, 0x6c, 0x23, 0x81, 0x12, 0xff, 0x57, 0xba, 0x8c, 0x5f, - 0x69, 0x40, 0xdf, 0xc3, 0xc3, 0x4d, 0xce, 0x49, 0x2f, 0xf0, 0x71, 0x20, 0x64, 0xe4, 0x21, 0x07, - 0xcb, 0x4f, 0xf8, 0x0e, 0x58, 0xc8, 0x9c, 0x4e, 0x25, 0x4e, 0x4d, 0x25, 0xce, 0xf9, 0x94, 0x28, - 0xf7, 0x08, 0x3e, 0x00, 0x20, 0x64, 0x38, 0xb2, 0x1d, 0xfb, 0x18, 0x0f, 0xd5, 0x7a, 0x2a, 0x1b, - 0x6b, 0xf9, 0x84, 0x18, 0xdf, 0x74, 0xcd, 0xce, 0xa0, 0xeb, 0x11, 0x67, 0x0f, 0x0f, 0xad, 0x92, - 0xc4, 0xb7, 0xf7, 0xf0, 0x50, 0x56, 0x40, 0xd5, 0x9c, 0xa8, 0x2c, 0x56, 0xb0, 0xe2, 0x81, 0xf1, - 0x1b, 0x0d, 0xdc, 0xcc, 0x16, 0x90, 0x9e, 0x55, 0x67, 0xd0, 0x95, 0x12, 0xf9, 0xbd, 0xd3, 0xc6, - 0x3b, 0xa1, 0x33, 0xd6, 0x4e, 0x9f, 0x63, 0xed, 0x43, 0x30, 0x9f, 0xa5, 0x11, 0x69, 0x6f, 0x61, - 0x02, 0x7b, 0x2b, 0xa9, 0xc4, 0x1e, 0x1e, 0x1a, 0x3f, 0xcb, 0xd9, 0xb6, 0x35, 0xcc, 0xb9, 0x2f, - 0x7b, 0x89, 0x6d, 0xd9, 0xb4, 0x79, 0xdb, 0x9c, 0xbc, 0xfc, 0x99, 0x05, 0x14, 0xce, 0x2e, 0xc0, - 0xf8, 0xab, 0x06, 0x6e, 0xe4, 0x67, 0xe5, 0x07, 0xb4, 0xc3, 0x06, 0x01, 0x3e, 0xdc, 0xb8, 0x6c, - 0xfe, 0x87, 0xa0, 0x14, 0x4a, 0x94, 0x2d, 0x78, 0x72, 0x44, 0x93, 0x95, 0xeb, 0x39, 0x25, 0x75, - 0x20, 0xc3, 0x7b, 0x71, 0x6c, 0x01, 0x3c, 0xd9, 0xb9, 0xf7, 0x26, 0x0a, 0xb8, 0x5c, 0x30, 0x59, - 0x0b, 0xf9, 0x35, 0x73, 0xe3, 0x4f, 0x1a, 0x80, 0x67, 0x33, 0x15, 0xfc, 0x2e, 0x80, 0x63, 0xf9, - 0x2e, 0xef, 0x7f, 0xd5, 0x30, 0x97, 0xe1, 0xd4, 0xce, 0x65, 0x7e, 0x34, 0x9d, 0xf3, 0x23, 0xf8, - 0x7d, 0x00, 0x42, 0x75, 0x88, 0x13, 0x9f, 0x74, 0x39, 0x4c, 0x3f, 0x61, 0x1d, 0x54, 0x7e, 0x42, - 0x49, 0x90, 0x7f, 0xa4, 0x28, 0x58, 0x40, 0x92, 0xe2, 0xf7, 0x07, 0xe3, 0x97, 0xda, 0x28, 0x1d, - 0x26, 0x99, 0x7a, 0xd3, 0xf3, 0x92, 0xfe, 0x0f, 0x86, 0x60, 0x2e, 0xcd, 0xf5, 0x71, 0xb8, 0xae, - 0x9d, 0x5b, 0x8f, 0xb6, 0xb1, 0xa3, 0x4a, 0xd2, 0x7d, 0xb9, 0xe3, 0xbf, 0xff, 0xb6, 0x7e, 0xb7, - 0x47, 0x44, 0x7f, 0xd0, 0x35, 0x1d, 0xea, 0x27, 0x2f, 0x37, 0xc9, 0xbf, 0x7b, 0xdc, 0x3d, 0x6e, - 0x89, 0x61, 0x88, 0x79, 0x2a, 0xc3, 0x7f, 0xf7, 0xcf, 0x3f, 0xbc, 0xab, 0x59, 0xe9, 0x34, 0x86, - 0x0b, 0xaa, 0xd9, 0xdd, 0x03, 0x0b, 0xe4, 0x22, 0x81, 0x20, 0x04, 0xc5, 0x00, 0xf9, 0x69, 0x83, - 0xa9, 0xbe, 0x27, 0xe8, 0x2f, 0x57, 0x41, 0xc9, 0x4f, 0x34, 0x24, 0xb7, 0x8d, 0x6c, 0x6c, 0xfc, - 0x62, 0x16, 0x34, 0xd2, 0x69, 0x76, 0xe2, 0xf7, 0x18, 0xf2, 0xd3, 0xb8, 0xfd, 0x96, 0x5d, 0x93, - 0xac, 0xdd, 0xfc, 0x9c, 0x37, 0x1e, 0xed, 0x6a, 0xde, 0x78, 0xa6, 0x5f, 0xfa, 0xc6, 0x53, 0x78, - 0xc9, 0x1b, 0x4f, 0xf1, 0xea, 0xde, 0x78, 0x66, 0xae, 0xfc, 0x8d, 0x67, 0xf6, 0x0d, 0xbd, 0xf1, - 0xcc, 0xfd, 0x4f, 0xde, 0x78, 0x4a, 0x57, 0xfa, 0xc6, 0x53, 0x7e, 0xbd, 0x37, 0x1e, 0xf0, 0x5a, - 0x6f, 0x3c, 0x95, 0x89, 0xde, 0x78, 0x8c, 0x5f, 0x4f, 0x83, 0x1b, 0xea, 0x06, 0xbd, 0xdf, 0x47, - 0xa1, 0x3c, 0xdc, 0x51, 0x08, 0x64, 0xd7, 0x72, 0x6d, 0x82, 0x6b, 0xf9, 0xf4, 0xab, 0x5d, 0xcb, - 0x0b, 0x13, 0x5c, 0xcb, 0x8b, 0x97, 0x5d, 0xcb, 0x67, 0x2e, 0xbb, 0x96, 0xcf, 0x4e, 0x76, 0x2d, - 0x9f, 0xbb, 0xe8, 0x5a, 0x5e, 0x07, 0x95, 0x2c, 0x41, 0xb8, 0x1c, 0x56, 0x41, 0x81, 0xb8, 0x69, - 0x33, 0x29, 0x3f, 0xb7, 0x3e, 0xfd, 0xea, 0x79, 0x4d, 0xfb, 0xfa, 0x79, 0x4d, 0xfb, 0xc7, 0xf3, - 0x9a, 0xf6, 0xf9, 0x8b, 0xda, 0xd4, 0xd7, 0x2f, 0x6a, 0x53, 0x7f, 0x7f, 0x51, 0x9b, 0xfa, 0xec, - 0x83, 0xb3, 0xd9, 0x6f, 0x54, 0x5d, 0xee, 0x65, 0xbf, 0x00, 0x44, 0xdf, 0x6b, 0x3d, 0x1b, 0xff, - 0x7d, 0x41, 0x25, 0xc6, 0xee, 0xac, 0x72, 0xec, 0xf7, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x45, - 0xe0, 0x33, 0x4d, 0x90, 0x18, 0x00, 0x00, + // 2220 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xbd, 0x6f, 0x1b, 0xc9, + 0x15, 0xd7, 0x8a, 0x94, 0x44, 0x3e, 0xea, 0x83, 0x1a, 0xfb, 0x6c, 0x4a, 0xd6, 0x51, 0x34, 0x2f, + 0x36, 0x14, 0x3b, 0x26, 0x4f, 0x3a, 0x04, 0x30, 0x9c, 0x1c, 0x0c, 0x99, 0xa4, 0x6d, 0xfa, 0x43, + 0x66, 0x96, 0xb4, 0x0e, 0x70, 0x8a, 0xc5, 0x70, 0x77, 0x44, 0x4e, 0xb4, 0xbb, 0xb3, 0xde, 0x19, + 0xd2, 0x66, 0x8a, 0xd4, 0x41, 0x80, 0x00, 0x97, 0x54, 0x87, 0x34, 0xb9, 0x2e, 0x41, 0xaa, 0x14, + 0x41, 0xfe, 0x80, 0x54, 0x87, 0x00, 0x41, 0xae, 0x4c, 0x75, 0x17, 0xd8, 0x45, 0x8a, 0x00, 0x69, + 0xd3, 0x06, 0x33, 0xfb, 0xc1, 0xa5, 0x3e, 0x6c, 0x1a, 0xb6, 0xd3, 0x48, 0x3b, 0xef, 0xfd, 0xde, + 0x9b, 0x37, 0x33, 0xef, 0x6b, 0x86, 0xb0, 0x43, 0x5d, 0x41, 0x7c, 0xb3, 0x8f, 0xa9, 0x6b, 0x70, + 0x62, 0x0e, 0x7c, 0x2a, 0x46, 0x55, 0xd3, 0x1c, 0x56, 0x3d, 0x9f, 0x0d, 0xa9, 0x45, 0xfc, 0xea, + 0x70, 0x3b, 0xfe, 0xae, 0x78, 0x3e, 0x13, 0x0c, 0x7d, 0x74, 0x82, 0x4c, 0xc5, 0x34, 0x87, 0x95, + 0x18, 0x37, 0xdc, 0x5e, 0xbf, 0x74, 0x9a, 0xe2, 0xe1, 0x76, 0xf5, 0x19, 0xf5, 0x49, 0xa0, 0x6b, + 0xfd, 0x6c, 0x8f, 0xf5, 0x98, 0xfa, 0xac, 0xca, 0xaf, 0x90, 0xba, 0xd9, 0x63, 0xac, 0x67, 0x93, + 0xaa, 0x1a, 0x75, 0x07, 0x07, 0x55, 0x41, 0x1d, 0xc2, 0x05, 0x76, 0xbc, 0x10, 0x50, 0x3c, 0x0a, + 0xb0, 0x06, 0x3e, 0x16, 0x94, 0xb9, 0x91, 0x02, 0xda, 0x35, 0xab, 0x26, 0xf3, 0x49, 0xd5, 0xb4, + 0x29, 0x71, 0x85, 0x9c, 0x35, 0xf8, 0x0a, 0x01, 0x55, 0x09, 0xb0, 0x69, 0xaf, 0x2f, 0x02, 0x32, + 0xaf, 0x0a, 0xe2, 0x5a, 0xc4, 0x77, 0x68, 0x00, 0x1e, 0x8f, 0x42, 0x81, 0x8d, 0x04, 0xdf, 0xf4, + 0x47, 0x9e, 0x60, 0xd5, 0x43, 0x32, 0xe2, 0x21, 0xf7, 0xb2, 0xc9, 0xb8, 0xc3, 0x78, 0x95, 0xc8, + 0xf5, 0xbb, 0x26, 0xa9, 0x0e, 0xb7, 0xbb, 0x44, 0xe0, 0xed, 0x98, 0x10, 0xd9, 0x1d, 0xe2, 0xba, + 0x98, 0x8f, 0x31, 0x26, 0xa3, 0x91, 0xdd, 0x6b, 0x01, 0xdf, 0x08, 0x76, 0x24, 0x18, 0x84, 0xac, + 0x55, 0xec, 0x50, 0x97, 0x55, 0xd5, 0xdf, 0x80, 0x54, 0xfe, 0x6f, 0x06, 0x0a, 0x35, 0xe6, 0xf2, + 0x81, 0x43, 0xfc, 0x5d, 0xcb, 0xa2, 0x72, 0x03, 0x5a, 0x3e, 0xf3, 0x18, 0xc7, 0x36, 0x3a, 0x0b, + 0x73, 0x82, 0x0a, 0x9b, 0x14, 0xb4, 0x92, 0xb6, 0x95, 0xd5, 0x83, 0x01, 0x2a, 0x41, 0xce, 0x22, + 0xdc, 0xf4, 0xa9, 0x27, 0xc1, 0x85, 0x59, 0xc5, 0x4b, 0x92, 0xd0, 0x1a, 0x64, 0x82, 0x53, 0xa3, + 0x56, 0x21, 0xa5, 0xd8, 0x0b, 0x6a, 0xdc, 0xb4, 0xd0, 0x1d, 0x58, 0xa6, 0x2e, 0x15, 0x14, 0xdb, + 0x46, 0x9f, 0xc8, 0xbd, 0x2b, 0xa4, 0x4b, 0xda, 0x56, 0x6e, 0x67, 0xbd, 0x42, 0xbb, 0x66, 0x45, + 0x6e, 0x77, 0x25, 0xdc, 0xe4, 0xe1, 0x76, 0xe5, 0xae, 0x42, 0xdc, 0x4a, 0x7f, 0xf5, 0xcd, 0xe6, + 0x8c, 0xbe, 0x14, 0xca, 0x05, 0x44, 0x74, 0x11, 0x16, 0x7b, 0xc4, 0x25, 0x9c, 0x72, 0xa3, 0x8f, + 0x79, 0xbf, 0x30, 0x57, 0xd2, 0xb6, 0x16, 0xf5, 0x5c, 0x48, 0xbb, 0x8b, 0x79, 0x1f, 0x6d, 0x42, + 0xae, 0x4b, 0x5d, 0xec, 0x8f, 0x02, 0xc4, 0xbc, 0x42, 0x40, 0x40, 0x52, 0x80, 0x1a, 0x00, 0xf7, + 0xf0, 0x33, 0xd7, 0x90, 0xbe, 0x51, 0x58, 0x08, 0x0d, 0x09, 0xfc, 0xa2, 0x12, 0xf9, 0x45, 0xa5, + 0x13, 0x39, 0xce, 0xad, 0x8c, 0x34, 0xe4, 0xf3, 0x6f, 0x37, 0x35, 0x3d, 0xab, 0xe4, 0x24, 0x07, + 0xed, 0x41, 0x7e, 0xe0, 0x76, 0x99, 0x6b, 0x51, 0xb7, 0x67, 0x78, 0xc4, 0xa7, 0xcc, 0x2a, 0x64, + 0x94, 0xaa, 0xb5, 0x63, 0xaa, 0xea, 0xa1, 0x8b, 0x05, 0x9a, 0xbe, 0x90, 0x9a, 0x56, 0x62, 0xe1, + 0x96, 0x92, 0x45, 0x3f, 0x02, 0x64, 0x9a, 0x43, 0x65, 0x12, 0x1b, 0x88, 0x48, 0x63, 0x76, 0x7a, + 0x8d, 0x79, 0xd3, 0x1c, 0x76, 0x02, 0xe9, 0x50, 0xe5, 0x8f, 0xe1, 0xbc, 0xf0, 0xb1, 0xcb, 0x0f, + 0x88, 0x7f, 0x54, 0x2f, 0x4c, 0xaf, 0xf7, 0x83, 0x48, 0xc7, 0xa4, 0xf2, 0xbb, 0x50, 0x32, 0x43, + 0x07, 0x32, 0x7c, 0x62, 0x51, 0x2e, 0x7c, 0xda, 0x1d, 0x48, 0x59, 0xe3, 0xc0, 0xc7, 0xa6, 0xf2, + 0x91, 0x9c, 0x72, 0x82, 0x62, 0x84, 0xd3, 0x27, 0x60, 0xb7, 0x43, 0x14, 0x7a, 0x04, 0xdf, 0xe9, + 0xda, 0xcc, 0x3c, 0xe4, 0xd2, 0x38, 0x63, 0x42, 0x93, 0x9a, 0xda, 0xa1, 0x9c, 0x4b, 0x6d, 0x8b, + 0x25, 0x6d, 0x2b, 0xa5, 0x5f, 0x0c, 0xb0, 0x2d, 0xe2, 0xd7, 0x13, 0xc8, 0x4e, 0x02, 0x88, 0xae, + 0x01, 0xea, 0x53, 0x2e, 0x98, 0x4f, 0x4d, 0x6c, 0x1b, 0xc4, 0x15, 0x3e, 0x25, 0xbc, 0xb0, 0xa4, + 0xc4, 0x57, 0xc7, 0x9c, 0x46, 0xc0, 0x40, 0xf7, 0xe0, 0xe2, 0xa9, 0x93, 0x1a, 0x66, 0x1f, 0xbb, + 0x2e, 0xb1, 0x0b, 0xcb, 0x6a, 0x29, 0x9b, 0xd6, 0x29, 0x73, 0xd6, 0x02, 0x18, 0x3a, 0x03, 0x73, + 0x82, 0x79, 0xc6, 0x5e, 0x61, 0xa5, 0xa4, 0x6d, 0x2d, 0xe9, 0x69, 0xc1, 0xbc, 0x3d, 0xf4, 0x31, + 0x9c, 0x1d, 0x62, 0x9b, 0x5a, 0x58, 0x30, 0x9f, 0x1b, 0x1e, 0x7b, 0x46, 0x7c, 0xc3, 0xc4, 0x5e, + 0x21, 0xaf, 0x30, 0x68, 0xcc, 0x6b, 0x49, 0x56, 0x0d, 0x7b, 0xe8, 0x0a, 0xac, 0xc6, 0x54, 0x83, + 0x13, 0xa1, 0xe0, 0xab, 0x0a, 0xbe, 0x12, 0x33, 0xda, 0x44, 0x48, 0xec, 0x06, 0x64, 0xb1, 0x6d, + 0xb3, 0x67, 0x36, 0xe5, 0xa2, 0x80, 0x4a, 0xa9, 0xad, 0xac, 0x3e, 0x26, 0xa0, 0x75, 0xc8, 0x58, + 0xc4, 0x1d, 0x29, 0xe6, 0x19, 0xc5, 0x8c, 0xc7, 0xe8, 0x02, 0x64, 0x1d, 0x99, 0x63, 0x05, 0x3e, + 0x24, 0x85, 0xb3, 0x25, 0x6d, 0x2b, 0xad, 0x67, 0x1c, 0xea, 0xb6, 0xe5, 0x18, 0x55, 0xe0, 0x8c, + 0xd2, 0x62, 0x50, 0x57, 0x9e, 0xd3, 0x90, 0x18, 0x43, 0x6c, 0xf3, 0xc2, 0x07, 0x25, 0x6d, 0x2b, + 0xa3, 0xaf, 0x2a, 0x56, 0x33, 0xe4, 0xec, 0x63, 0x9b, 0xdf, 0xb8, 0xfc, 0xf3, 0x2f, 0x37, 0x67, + 0xbe, 0xf8, 0x72, 0x73, 0xe6, 0xaf, 0x7f, 0xba, 0xb6, 0x1e, 0xa6, 0x9f, 0x1e, 0x1b, 0x56, 0xc2, + 0x54, 0x55, 0xa9, 0x31, 0x57, 0x10, 0x57, 0x94, 0xff, 0xae, 0xc1, 0xf9, 0x5a, 0xec, 0x10, 0x0e, + 0x1b, 0x62, 0xfb, 0x7d, 0x26, 0x9e, 0x5d, 0xc8, 0x72, 0x79, 0x22, 0x2a, 0xd4, 0xd3, 0x6f, 0x10, + 0xea, 0x19, 0x29, 0x26, 0x19, 0x37, 0x8a, 0xaf, 0x59, 0xd1, 0xbf, 0x67, 0x61, 0x23, 0x5a, 0xd1, + 0x43, 0x66, 0xd1, 0x03, 0x6a, 0xe2, 0xf7, 0x9d, 0x4f, 0x63, 0x3f, 0x4b, 0x4f, 0xe1, 0x67, 0x73, + 0x6f, 0xe6, 0x67, 0xf3, 0x53, 0xf8, 0xd9, 0xc2, 0xab, 0xfc, 0x2c, 0xf3, 0x2a, 0x3f, 0xcb, 0x4e, + 0xe7, 0x67, 0x70, 0x8a, 0x9f, 0x95, 0x7f, 0xab, 0xc1, 0xd9, 0xc6, 0xd3, 0x01, 0x1d, 0xb2, 0x77, + 0xb4, 0xcb, 0xf7, 0x61, 0x89, 0x24, 0xf4, 0xf1, 0x42, 0xaa, 0x94, 0xda, 0xca, 0xed, 0x5c, 0xaa, + 0x84, 0x47, 0x1e, 0xd7, 0xe1, 0xe8, 0xdc, 0x93, 0xb3, 0xeb, 0x93, 0xb2, 0x37, 0x66, 0x0b, 0x5a, + 0xf9, 0x2f, 0x1a, 0xac, 0xcb, 0x7c, 0xd0, 0x23, 0x3a, 0x79, 0x86, 0x7d, 0xab, 0x4e, 0x5c, 0xe6, + 0xf0, 0xb7, 0xb6, 0xb3, 0x0c, 0x4b, 0x96, 0xd2, 0x64, 0x08, 0x66, 0x60, 0xcb, 0x52, 0x76, 0x2a, + 0x8c, 0x24, 0x76, 0xd8, 0xae, 0x65, 0xa1, 0x2d, 0xc8, 0x8f, 0x31, 0xbe, 0x8c, 0x2e, 0xe9, 0xf4, + 0x12, 0xb6, 0x1c, 0xc1, 0x54, 0xcc, 0x4d, 0xe1, 0xd4, 0x1a, 0xe4, 0xef, 0xd8, 0xac, 0x8b, 0xed, + 0xb6, 0x8d, 0x79, 0x5f, 0xe6, 0xca, 0x91, 0x0c, 0x26, 0x9f, 0x84, 0x45, 0x4a, 0x99, 0x3f, 0x75, + 0x30, 0x49, 0x31, 0x55, 0x36, 0x6f, 0xc2, 0x6a, 0x5c, 0x36, 0x62, 0xe7, 0x56, 0xab, 0xbd, 0x75, + 0xe6, 0xc5, 0x37, 0x9b, 0x2b, 0x51, 0x20, 0xd5, 0x94, 0xa3, 0xd7, 0xf5, 0x15, 0x73, 0x82, 0x60, + 0xa1, 0x22, 0xe4, 0x68, 0xd7, 0x34, 0x38, 0x79, 0x6a, 0xb8, 0x03, 0x47, 0xc5, 0x45, 0x5a, 0xcf, + 0xd2, 0xae, 0xd9, 0x26, 0x4f, 0xf7, 0x06, 0x0e, 0xfa, 0x04, 0xce, 0x45, 0xcd, 0xa4, 0xf4, 0x24, + 0x43, 0xca, 0xcb, 0xed, 0xf2, 0x55, 0xa8, 0x2c, 0xea, 0x67, 0x22, 0xee, 0x3e, 0xb6, 0xe5, 0x64, + 0xbb, 0x96, 0xe5, 0x97, 0xff, 0x33, 0x07, 0xf3, 0x2d, 0xec, 0x63, 0x87, 0xa3, 0x0e, 0xac, 0x08, + 0xe2, 0x78, 0x36, 0x16, 0xc4, 0x08, 0x5a, 0x92, 0x70, 0xa5, 0x57, 0x55, 0xab, 0x92, 0x6c, 0xfc, + 0x2a, 0x89, 0x56, 0x6f, 0xb8, 0x5d, 0xa9, 0x29, 0x6a, 0x5b, 0x60, 0x41, 0xf4, 0xe5, 0x48, 0x47, + 0x40, 0x44, 0xd7, 0xa1, 0x20, 0xfc, 0x01, 0x17, 0xe3, 0x66, 0x61, 0x5c, 0x25, 0x83, 0xb3, 0x3e, + 0x17, 0xf1, 0x83, 0xfa, 0x1a, 0x57, 0xc7, 0x93, 0xfb, 0x82, 0xd4, 0xdb, 0xf4, 0x05, 0x16, 0x6c, + 0x70, 0x79, 0xa8, 0x86, 0x43, 0x84, 0xaa, 0xde, 0x9e, 0x4d, 0x5c, 0xca, 0xfb, 0x91, 0xf2, 0xf9, + 0xe9, 0x95, 0xaf, 0x29, 0x45, 0x0f, 0xa5, 0x1e, 0x3d, 0x52, 0x13, 0xce, 0x52, 0x83, 0xe2, 0xc9, + 0xb3, 0xc4, 0x0b, 0x5f, 0x50, 0x0b, 0xbf, 0x70, 0x82, 0x8a, 0x78, 0xf5, 0x1c, 0x2e, 0x27, 0xba, + 0x0c, 0x19, 0x4d, 0x86, 0x72, 0x64, 0xc3, 0x27, 0x3d, 0x59, 0x8a, 0x71, 0xd0, 0x70, 0x10, 0x12, + 0x77, 0x4a, 0xa1, 0x4f, 0xcb, 0x36, 0x39, 0xe1, 0xd4, 0xd4, 0x0d, 0xdb, 0xc9, 0xf2, 0xb8, 0x19, + 0x89, 0x63, 0x53, 0x4f, 0xe8, 0xba, 0x4d, 0x88, 0x8c, 0xa2, 0x44, 0x43, 0x42, 0x3c, 0x66, 0xf6, + 0x55, 0x3e, 0x4a, 0xe9, 0xcb, 0x71, 0xf3, 0xd1, 0x90, 0x54, 0xf4, 0x04, 0xae, 0xba, 0x03, 0xa7, + 0x4b, 0x7c, 0x83, 0x1d, 0x04, 0x40, 0x15, 0x79, 0x5c, 0x60, 0x5f, 0x18, 0x3e, 0x31, 0x09, 0x1d, + 0xca, 0x13, 0x0f, 0x2c, 0xe7, 0xaa, 0x1f, 0x4a, 0xe9, 0x97, 0x02, 0x91, 0x47, 0x07, 0x4a, 0x07, + 0xef, 0xb0, 0xb6, 0x84, 0xeb, 0x11, 0x3a, 0x30, 0x8c, 0xa3, 0x26, 0x5c, 0x74, 0xf0, 0x73, 0x23, + 0x76, 0x66, 0x69, 0x38, 0x71, 0xf9, 0x80, 0x1b, 0xe3, 0x44, 0x1e, 0xf6, 0x44, 0x45, 0x07, 0x3f, + 0x6f, 0x85, 0xb8, 0x5a, 0x04, 0xdb, 0x8f, 0x51, 0xf7, 0xd2, 0x99, 0x74, 0x7e, 0xee, 0x5e, 0x3a, + 0x33, 0x97, 0x9f, 0xbf, 0x97, 0xce, 0x64, 0xf2, 0xd9, 0xf2, 0x77, 0x21, 0xab, 0xe2, 0x7a, 0xd7, + 0x3c, 0xe4, 0x2a, 0xb3, 0x5b, 0x96, 0x4f, 0x38, 0x27, 0xbc, 0xa0, 0x85, 0x99, 0x3d, 0x22, 0x94, + 0x05, 0xac, 0x9d, 0x76, 0x53, 0xe0, 0xe8, 0x33, 0x58, 0xf0, 0x88, 0x6a, 0x63, 0x95, 0x60, 0x6e, + 0xe7, 0xd3, 0xca, 0x14, 0x57, 0xbc, 0xca, 0x69, 0x0a, 0xf5, 0x48, 0x5b, 0xd9, 0x1f, 0xdf, 0x4f, + 0x8e, 0x74, 0x09, 0x1c, 0xed, 0x1f, 0x9d, 0xf4, 0x87, 0x6f, 0x34, 0xe9, 0x11, 0x7d, 0xe3, 0x39, + 0xaf, 0x42, 0x6e, 0x37, 0x58, 0xf6, 0x03, 0x59, 0xb6, 0x8e, 0x6d, 0xcb, 0x62, 0x72, 0x5b, 0xee, + 0xc1, 0x72, 0xd8, 0xf4, 0x75, 0x98, 0xca, 0x4d, 0xe8, 0x43, 0x80, 0xb0, 0x5b, 0x94, 0x39, 0x2d, + 0xc8, 0xee, 0xd9, 0x90, 0xd2, 0xb4, 0x26, 0xaa, 0xf9, 0xec, 0x44, 0x35, 0x2f, 0x33, 0x58, 0xdb, + 0x4f, 0x56, 0x5b, 0x55, 0x3c, 0x5a, 0xd8, 0x3c, 0x24, 0x82, 0x23, 0x1d, 0xd2, 0xaa, 0xaa, 0x06, + 0x4b, 0xbd, 0x7e, 0xea, 0x52, 0x87, 0xdb, 0x95, 0xd3, 0x94, 0xd4, 0xb1, 0xc0, 0xa1, 0xff, 0x2b, + 0x5d, 0xe5, 0x5f, 0x69, 0x50, 0xb8, 0x4f, 0x46, 0xbb, 0x9c, 0xd3, 0x9e, 0xeb, 0x10, 0x57, 0xc8, + 0xc8, 0xc3, 0x26, 0x91, 0x9f, 0xe8, 0x23, 0x58, 0x8a, 0x9d, 0x4e, 0x25, 0x4e, 0x4d, 0x25, 0xce, + 0xc5, 0x88, 0x28, 0xf7, 0x08, 0xdd, 0x00, 0xf0, 0x7c, 0x32, 0x34, 0x4c, 0xe3, 0x90, 0x8c, 0xd4, + 0x7a, 0x72, 0x3b, 0x1b, 0xc9, 0x84, 0x18, 0xdc, 0x74, 0x2b, 0xad, 0x41, 0xd7, 0xa6, 0xe6, 0x7d, + 0x32, 0xd2, 0x33, 0x12, 0x5f, 0xbb, 0x4f, 0x46, 0xb2, 0x02, 0xaa, 0xe6, 0x44, 0x65, 0xb1, 0x94, + 0x1e, 0x0c, 0xca, 0xbf, 0xd1, 0xe0, 0x7c, 0xbc, 0x80, 0xe8, 0xac, 0x5a, 0x83, 0xae, 0x94, 0x48, + 0xee, 0x9d, 0x36, 0xd9, 0x09, 0x1d, 0xb3, 0x76, 0xf6, 0x04, 0x6b, 0x6f, 0xc2, 0x62, 0x9c, 0x46, + 0xa4, 0xbd, 0xa9, 0x29, 0xec, 0xcd, 0x45, 0x12, 0xf7, 0xc9, 0xa8, 0xfc, 0xb3, 0x84, 0x6d, 0xb7, + 0x46, 0x09, 0xf7, 0xf5, 0x5f, 0x63, 0x5b, 0x3c, 0x6d, 0xd2, 0x36, 0x33, 0x29, 0x7f, 0x6c, 0x01, + 0xa9, 0xe3, 0x0b, 0x28, 0xff, 0x4d, 0x83, 0x73, 0xc9, 0x59, 0x79, 0x87, 0xb5, 0xfc, 0x81, 0x4b, + 0xf6, 0x77, 0x5e, 0x35, 0xff, 0x4d, 0xc8, 0x78, 0x12, 0x65, 0x08, 0x1e, 0x1e, 0xd1, 0x74, 0xe5, + 0x7a, 0x41, 0x49, 0x75, 0x64, 0x78, 0x2f, 0x4f, 0x2c, 0x80, 0x87, 0x3b, 0xf7, 0xf1, 0x54, 0x01, + 0x97, 0x08, 0x26, 0x7d, 0x29, 0xb9, 0x66, 0x5e, 0xfe, 0xb3, 0x06, 0xe8, 0x78, 0xa6, 0x42, 0xdf, + 0x03, 0x34, 0x91, 0xef, 0x92, 0xfe, 0x97, 0xf7, 0x12, 0x19, 0x4e, 0xed, 0x5c, 0xec, 0x47, 0xb3, + 0x09, 0x3f, 0x42, 0x3f, 0x00, 0xf0, 0xd4, 0x21, 0x4e, 0x7d, 0xd2, 0x59, 0x2f, 0xfa, 0x44, 0x9b, + 0x90, 0xfb, 0x09, 0xa3, 0x6e, 0xf2, 0x91, 0x22, 0xa5, 0x83, 0x24, 0x05, 0xef, 0x0f, 0xe5, 0x5f, + 0x6a, 0xe3, 0x74, 0x18, 0x66, 0xea, 0x5d, 0xdb, 0x0e, 0xfb, 0x3f, 0xe4, 0xc1, 0x42, 0x94, 0xeb, + 0x83, 0x70, 0xdd, 0x38, 0xb1, 0x1e, 0xd5, 0x89, 0xa9, 0x4a, 0xd2, 0x75, 0xb9, 0xe3, 0x7f, 0xf8, + 0x76, 0xf3, 0x6a, 0x8f, 0x8a, 0xfe, 0xa0, 0x5b, 0x31, 0x99, 0x13, 0xbe, 0xdc, 0x84, 0xff, 0xae, + 0x71, 0xeb, 0xb0, 0x2a, 0x46, 0x1e, 0xe1, 0x91, 0x0c, 0xff, 0xfd, 0xbf, 0xfe, 0x78, 0x45, 0xd3, + 0xa3, 0x69, 0xca, 0x16, 0xe4, 0xe3, 0xbb, 0x07, 0x11, 0xd8, 0xc2, 0x02, 0x23, 0x04, 0x69, 0x17, + 0x3b, 0x51, 0x83, 0xa9, 0xbe, 0xa7, 0xe8, 0x2f, 0xd7, 0x21, 0xe3, 0x84, 0x1a, 0xc2, 0xdb, 0x46, + 0x3c, 0x2e, 0xff, 0x62, 0x1e, 0x4a, 0xd1, 0x34, 0xcd, 0xe0, 0x3d, 0x86, 0xfe, 0x34, 0x68, 0xbf, + 0x65, 0xd7, 0x24, 0x6b, 0x37, 0x3f, 0xe1, 0x8d, 0x47, 0x7b, 0x37, 0x6f, 0x3c, 0xb3, 0xaf, 0x7d, + 0xe3, 0x49, 0xbd, 0xe6, 0x8d, 0x27, 0xfd, 0xee, 0xde, 0x78, 0xe6, 0xde, 0xf9, 0x1b, 0xcf, 0xfc, + 0x7b, 0x7a, 0xe3, 0x59, 0xf8, 0xbf, 0xbc, 0xf1, 0x64, 0xde, 0xe9, 0x1b, 0x4f, 0xf6, 0xed, 0xde, + 0x78, 0xe0, 0xad, 0xde, 0x78, 0x72, 0x53, 0xbd, 0xf1, 0x94, 0x7f, 0x3d, 0x0b, 0xe7, 0xd4, 0x0d, + 0xba, 0xdd, 0xc7, 0x9e, 0x3c, 0xdc, 0x71, 0x08, 0xc4, 0xd7, 0x72, 0x6d, 0x8a, 0x6b, 0xf9, 0xec, + 0x9b, 0x5d, 0xcb, 0x53, 0x53, 0x5c, 0xcb, 0xd3, 0xaf, 0xba, 0x96, 0xcf, 0xbd, 0xea, 0x5a, 0x3e, + 0x3f, 0xdd, 0xb5, 0x7c, 0xe1, 0xb4, 0x6b, 0xf9, 0x26, 0xe4, 0xe2, 0x04, 0x61, 0x71, 0x94, 0x87, + 0x14, 0xb5, 0xa2, 0x66, 0x52, 0x7e, 0x5e, 0xf9, 0x9d, 0x06, 0x4b, 0x71, 0x55, 0xef, 0x63, 0x4e, + 0x50, 0x11, 0xd6, 0x6b, 0x8f, 0xf6, 0xda, 0x8f, 0x1f, 0x36, 0x74, 0xa3, 0x75, 0x77, 0xb7, 0xdd, + 0x30, 0x1e, 0xef, 0xb5, 0x5b, 0x8d, 0x5a, 0xf3, 0x76, 0xb3, 0x51, 0xcf, 0xcf, 0xa0, 0x0f, 0x61, + 0xed, 0x08, 0x5f, 0x6f, 0xdc, 0x69, 0xb6, 0x3b, 0x0d, 0xbd, 0x51, 0xcf, 0x6b, 0x27, 0x88, 0x37, + 0xf7, 0x9a, 0x9d, 0xe6, 0xee, 0x83, 0xe6, 0x93, 0x46, 0x3d, 0x3f, 0x8b, 0x2e, 0xc0, 0xf9, 0x23, + 0xfc, 0x07, 0xbb, 0x8f, 0xf7, 0x6a, 0x77, 0x1b, 0xf5, 0x7c, 0x0a, 0xad, 0xc3, 0xb9, 0x23, 0xcc, + 0x76, 0xe7, 0x51, 0xab, 0xd5, 0xa8, 0xe7, 0xd3, 0xb7, 0x3e, 0xfb, 0xea, 0x45, 0x51, 0xfb, 0xfa, + 0x45, 0x51, 0xfb, 0xe7, 0x8b, 0xa2, 0xf6, 0xf9, 0xcb, 0xe2, 0xcc, 0xd7, 0x2f, 0x8b, 0x33, 0xff, + 0x78, 0x59, 0x9c, 0x79, 0xf2, 0xe9, 0xf1, 0x3c, 0x3d, 0xae, 0x83, 0xd7, 0xe2, 0xdf, 0x2a, 0x86, + 0xdf, 0xaf, 0x3e, 0x9f, 0xfc, 0x25, 0x44, 0xa5, 0xf0, 0xee, 0xbc, 0x0a, 0xc1, 0x4f, 0xfe, 0x17, + 0x00, 0x00, 0xff, 0xff, 0x1d, 0xf2, 0xb2, 0x97, 0x3a, 0x19, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go index d2e06c125e..7c2e1b4ef3 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -141,11 +141,11 @@ type QueryConsumerChainsRequest struct { // the returned consumer chains FilterByPhase bool `protobuf:"varint,1,opt,name=filter_by_phase,json=filterByPhase,proto3" json:"filter_by_phase,omitempty"` // The phase of the consumer chains returned (optional) - // Registered=0|Initialized=1|FailedToLaunch=2|Launched=3|Stopped=4 - Phase uint32 `protobuf:"varint,2,opt,name=phase,proto3" json:"phase,omitempty"` - // The limit of consumer chains returned + // Registered=1|Initialized=2|Launched=3|Stopped=4 + Phase ConsumerPhase `protobuf:"varint,2,opt,name=phase,proto3,enum=interchain_security.ccv.provider.v1.ConsumerPhase" json:"phase,omitempty"` + // The limit of consumer chains returned (optional) // default is 100 - Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` } func (m *QueryConsumerChainsRequest) Reset() { *m = QueryConsumerChainsRequest{} } @@ -188,14 +188,14 @@ func (m *QueryConsumerChainsRequest) GetFilterByPhase() bool { return false } -func (m *QueryConsumerChainsRequest) GetPhase() uint32 { +func (m *QueryConsumerChainsRequest) GetPhase() ConsumerPhase { if m != nil { return m.Phase } - return 0 + return ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED } -func (m *QueryConsumerChainsRequest) GetLimit() uint32 { +func (m *QueryConsumerChainsRequest) GetLimit() int32 { if m != nil { return m.Limit } @@ -433,7 +433,7 @@ type Chain struct { // 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"` // The phase the consumer chain (Registered=0|Initialized=1|FailedToLaunch=2|Launched=3|Stopped=4) - Phase uint32 `protobuf:"varint,9,opt,name=phase,proto3" json:"phase,omitempty"` + Phase ConsumerPhase `protobuf:"varint,9,opt,name=phase,proto3,enum=interchain_security.ccv.provider.v1.ConsumerPhase" json:"phase,omitempty"` // The metadata of the consumer chain Metadata ConsumerMetadata `protobuf:"bytes,10,opt,name=metadata,proto3" json:"metadata"` } @@ -527,11 +527,11 @@ func (m *Chain) GetDenylist() []string { return nil } -func (m *Chain) GetPhase() uint32 { +func (m *Chain) GetPhase() ConsumerPhase { if m != nil { return m.Phase } - return 0 + return ConsumerPhase_CONSUMER_PHASE_UNSPECIFIED } func (m *Chain) GetMetadata() ConsumerMetadata { @@ -2059,163 +2059,164 @@ func init() { } var fileDescriptor_422512d7b7586cd7 = []byte{ - // 2495 bytes of a gzipped FileDescriptorProto + // 2505 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4d, 0x6c, 0xdc, 0xc6, - 0xf5, 0x17, 0x57, 0x1f, 0x96, 0x46, 0x96, 0x9c, 0x8c, 0x65, 0x7b, 0xbd, 0x92, 0xb5, 0x32, 0x6d, - 0xe7, 0x2f, 0x7f, 0x2d, 0x25, 0x05, 0xfe, 0x27, 0x76, 0xeb, 0xd8, 0xda, 0x95, 0x65, 0x2f, 0xfc, - 0xa5, 0xd0, 0xb2, 0x53, 0x28, 0x75, 0x69, 0x8a, 0x9c, 0xac, 0x58, 0x71, 0x49, 0x8a, 0x33, 0x5a, - 0x7b, 0x61, 0xf8, 0x90, 0x16, 0x68, 0x93, 0x1e, 0x0a, 0x17, 0x45, 0xef, 0xb9, 0x14, 0xe8, 0xa1, - 0xa7, 0x22, 0x68, 0xd1, 0x5b, 0x8e, 0xb9, 0x35, 0x4d, 0x2e, 0x45, 0x0b, 0xb8, 0x85, 0xdd, 0x43, - 0x51, 0xa0, 0x40, 0x91, 0xf6, 0x5a, 0xa0, 0xe0, 0xcc, 0xf0, 0x53, 0x5c, 0x2d, 0x77, 0x57, 0x87, - 0xde, 0xc4, 0x99, 0x37, 0xbf, 0xf7, 0x31, 0xef, 0xbd, 0x79, 0xef, 0xad, 0x80, 0x64, 0x58, 0x04, - 0xb9, 0xda, 0x86, 0x6a, 0x58, 0x0a, 0x46, 0xda, 0xb6, 0x6b, 0x90, 0xa6, 0xa4, 0x69, 0x0d, 0xc9, - 0x71, 0xed, 0x86, 0xa1, 0x23, 0x57, 0x6a, 0xcc, 0x4b, 0x5b, 0xdb, 0xc8, 0x6d, 0x96, 0x1c, 0xd7, - 0x26, 0x36, 0x3c, 0x91, 0x72, 0xa0, 0xa4, 0x69, 0x8d, 0x92, 0x7f, 0xa0, 0xd4, 0x98, 0x2f, 0x4c, - 0xd5, 0x6c, 0xbb, 0x66, 0x22, 0x49, 0x75, 0x0c, 0x49, 0xb5, 0x2c, 0x9b, 0xa8, 0xc4, 0xb0, 0x2d, - 0xcc, 0x20, 0x0a, 0x13, 0x35, 0xbb, 0x66, 0xd3, 0x3f, 0x25, 0xef, 0x2f, 0xbe, 0x5a, 0xe4, 0x67, - 0xe8, 0xd7, 0xfa, 0xf6, 0x07, 0x12, 0x31, 0xea, 0x08, 0x13, 0xb5, 0xee, 0x70, 0x82, 0x85, 0x2c, - 0xa2, 0x06, 0x52, 0xb0, 0x33, 0x73, 0xad, 0xce, 0x34, 0xe6, 0x25, 0xbc, 0xa1, 0xba, 0x48, 0x57, - 0x34, 0xdb, 0xc2, 0xdb, 0xf5, 0xe0, 0xc4, 0xa9, 0x5d, 0x4e, 0x3c, 0x36, 0x5c, 0xc4, 0xc9, 0xa6, - 0x08, 0xb2, 0x74, 0xe4, 0xd6, 0x0d, 0x8b, 0x48, 0x9a, 0xdb, 0x74, 0x88, 0x2d, 0x6d, 0xa2, 0xa6, - 0xaf, 0xe1, 0x51, 0xcd, 0xc6, 0x75, 0x1b, 0x2b, 0x4c, 0x49, 0xf6, 0xc1, 0xb7, 0x4e, 0xb2, 0x2f, - 0x09, 0x13, 0x75, 0xd3, 0xb0, 0x6a, 0x52, 0x63, 0x7e, 0x1d, 0x11, 0x75, 0xde, 0xff, 0x66, 0x54, - 0xe2, 0x43, 0x30, 0xf9, 0xae, 0x67, 0xf4, 0x0a, 0x17, 0xee, 0x3a, 0xb2, 0x10, 0x36, 0xb0, 0x8c, - 0xb6, 0xb6, 0x11, 0x26, 0xf0, 0x18, 0x18, 0x66, 0x12, 0x1a, 0x7a, 0x5e, 0x98, 0x11, 0x66, 0x47, - 0xca, 0xb9, 0xbc, 0x20, 0xef, 0xa3, 0x6b, 0x55, 0x1d, 0x16, 0xc1, 0xa8, 0xaf, 0x95, 0x47, 0x91, - 0xf3, 0x28, 0x64, 0xe0, 0x2f, 0x55, 0x75, 0xf1, 0x29, 0x98, 0x4a, 0x87, 0xc7, 0x8e, 0x6d, 0x61, - 0x04, 0xdf, 0x07, 0x63, 0x35, 0xb6, 0xa4, 0x60, 0xa2, 0x12, 0x44, 0x99, 0x8c, 0x2e, 0xcc, 0x95, - 0x5a, 0x5d, 0x7e, 0x63, 0xbe, 0x94, 0xc0, 0xba, 0xe7, 0x9d, 0x2b, 0x0f, 0x7c, 0xfe, 0xa2, 0xd8, - 0x27, 0xef, 0xaf, 0x45, 0xd6, 0x44, 0x07, 0x14, 0x62, 0xcc, 0x2b, 0x1e, 0x5c, 0xa0, 0xda, 0x1b, - 0xe0, 0xc0, 0x07, 0x86, 0x49, 0x90, 0xab, 0xac, 0x37, 0x15, 0x67, 0x43, 0xc5, 0x8c, 0xf9, 0xb0, - 0x3c, 0xc6, 0x96, 0xcb, 0xcd, 0x15, 0x6f, 0x11, 0x4e, 0x80, 0x41, 0xb6, 0xeb, 0x69, 0x37, 0x26, - 0xb3, 0x0f, 0x6f, 0xd5, 0x34, 0xea, 0x06, 0xc9, 0xf7, 0xb3, 0x55, 0xfa, 0x21, 0xaa, 0x09, 0x6b, - 0xfa, 0x1c, 0xb9, 0xb6, 0x65, 0x30, 0x44, 0x55, 0xc2, 0x79, 0x61, 0xa6, 0x7f, 0x76, 0x74, 0xe1, - 0x4c, 0x29, 0x83, 0x8f, 0x97, 0x28, 0x88, 0xcc, 0x4f, 0x8a, 0xa7, 0xc1, 0xff, 0xed, 0x64, 0x71, - 0x8f, 0xa8, 0x2e, 0x59, 0x71, 0x6d, 0xc7, 0xc6, 0xaa, 0xe9, 0x6b, 0x28, 0x7e, 0x24, 0x80, 0xd9, - 0xf6, 0xb4, 0x5c, 0xb6, 0x6f, 0x83, 0x11, 0xc7, 0x5f, 0xe4, 0xb7, 0xf0, 0x4e, 0x36, 0xf1, 0x38, - 0xf8, 0xa2, 0xae, 0x1b, 0x5e, 0xf0, 0x85, 0xd0, 0x21, 0xa0, 0x38, 0x0b, 0xde, 0x48, 0x93, 0xc4, - 0x76, 0x76, 0x08, 0xfd, 0x03, 0x21, 0x5d, 0xc1, 0x18, 0x69, 0xe0, 0x3d, 0x3b, 0x64, 0xbe, 0xdc, - 0x91, 0xcc, 0x32, 0xaa, 0xdb, 0x0d, 0xd5, 0x4c, 0x15, 0xf9, 0x87, 0xfd, 0x60, 0x90, 0xf2, 0x86, - 0x47, 0x93, 0x41, 0x10, 0x06, 0xc0, 0x24, 0x18, 0xd1, 0x4c, 0x03, 0x59, 0x24, 0x74, 0xff, 0x61, - 0xb6, 0x50, 0xd5, 0xe1, 0x41, 0x30, 0x48, 0x6c, 0x47, 0xb9, 0xc3, 0x7d, 0x64, 0x80, 0xd8, 0xce, - 0x1d, 0x78, 0x06, 0xc0, 0xba, 0x61, 0x29, 0x8e, 0xfd, 0xd8, 0x8b, 0x19, 0x4b, 0x61, 0x14, 0x03, - 0x33, 0xc2, 0x6c, 0xbf, 0x3c, 0x5e, 0x37, 0xac, 0x15, 0x6f, 0xa3, 0x6a, 0xad, 0x7a, 0xb4, 0x73, - 0x60, 0xa2, 0xa1, 0x9a, 0x86, 0xae, 0x12, 0xdb, 0xc5, 0xfc, 0x88, 0xa6, 0x3a, 0xf9, 0x41, 0x8a, - 0x07, 0xc3, 0x3d, 0x7a, 0xa8, 0xa2, 0x3a, 0xf0, 0x0c, 0x78, 0x3d, 0x58, 0x55, 0x30, 0x22, 0x94, - 0x7c, 0x88, 0x92, 0x1f, 0x08, 0x36, 0xee, 0x21, 0xe2, 0xd1, 0x4e, 0x81, 0x11, 0xd5, 0x34, 0xed, - 0xc7, 0xa6, 0x81, 0x49, 0x7e, 0xdf, 0x4c, 0xff, 0xec, 0x88, 0x1c, 0x2e, 0xc0, 0x02, 0x18, 0xd6, - 0x91, 0xd5, 0xa4, 0x9b, 0xc3, 0x74, 0x33, 0xf8, 0x0e, 0x43, 0x62, 0x24, 0x1a, 0x12, 0xef, 0x81, - 0xe1, 0x3a, 0x22, 0xaa, 0xae, 0x12, 0x35, 0x0f, 0xe8, 0x65, 0x5c, 0xe8, 0xe8, 0x32, 0x6e, 0xf3, - 0xc3, 0x3c, 0x96, 0x03, 0x30, 0xf1, 0x97, 0x02, 0x38, 0x4e, 0x5d, 0xe2, 0x81, 0xaf, 0x41, 0xc4, - 0xe7, 0xdc, 0x8c, 0xa9, 0xea, 0x32, 0x78, 0xcd, 0x67, 0xaa, 0xa8, 0xba, 0xee, 0x22, 0x8c, 0xd9, - 0x85, 0x95, 0xe1, 0xd7, 0x2f, 0x8a, 0xe3, 0x4d, 0xb5, 0x6e, 0x5e, 0x12, 0xf9, 0x86, 0x28, 0x1f, - 0xf0, 0x69, 0x17, 0xd9, 0x4a, 0x32, 0xd3, 0xf5, 0x27, 0x33, 0xdd, 0xa5, 0xe1, 0x8f, 0x3e, 0x29, - 0xf6, 0xfd, 0xed, 0x93, 0x62, 0x9f, 0x78, 0x17, 0x88, 0xbb, 0x49, 0xcb, 0x7d, 0xf7, 0x34, 0x78, - 0x2d, 0x00, 0xf4, 0xe5, 0x61, 0xce, 0x75, 0x40, 0x8b, 0xd0, 0x7b, 0xd2, 0xec, 0xd4, 0x7f, 0x25, - 0x22, 0x5d, 0x76, 0xfd, 0x77, 0xf0, 0xdb, 0x45, 0xff, 0x84, 0x0c, 0x3d, 0xe9, 0x1f, 0x97, 0x36, - 0xd4, 0x7f, 0xc7, 0x7d, 0x70, 0xfd, 0x13, 0xb6, 0x17, 0x27, 0xc1, 0x51, 0x0a, 0xb8, 0xba, 0xe1, - 0xda, 0x84, 0x98, 0x88, 0x66, 0x77, 0x3f, 0x5f, 0xfc, 0x5e, 0xe0, 0x59, 0x3e, 0xb1, 0xcb, 0xd9, - 0x14, 0xc1, 0x28, 0x36, 0x55, 0xbc, 0xa1, 0xd4, 0x11, 0x41, 0x2e, 0xe5, 0xd0, 0x2f, 0x03, 0xba, - 0x74, 0xdb, 0x5b, 0x81, 0x0b, 0xe0, 0x50, 0x84, 0x40, 0xa1, 0x01, 0xa0, 0x5a, 0x1a, 0x4b, 0xf7, - 0xfd, 0xf2, 0xc1, 0x90, 0x74, 0xd1, 0xdf, 0x82, 0xdf, 0x01, 0x79, 0x0b, 0x3d, 0x21, 0x8a, 0x8b, - 0x1c, 0x13, 0x59, 0x06, 0xde, 0x50, 0x34, 0xd5, 0xd2, 0x3d, 0x65, 0x11, 0xb5, 0xcc, 0xe8, 0x42, - 0xa1, 0xc4, 0x8a, 0x8c, 0x92, 0x5f, 0x64, 0x94, 0x56, 0xfd, 0x22, 0xa3, 0x3c, 0xec, 0xb9, 0xf7, - 0xf3, 0x3f, 0x17, 0x05, 0xf9, 0xb0, 0x87, 0x22, 0xfb, 0x20, 0x15, 0x1f, 0x43, 0x3c, 0x07, 0xce, - 0x50, 0x95, 0x64, 0x54, 0x33, 0x30, 0x41, 0x2e, 0xd2, 0xc3, 0x84, 0xf5, 0x58, 0x75, 0xf5, 0x25, - 0x64, 0xd9, 0xf5, 0x20, 0x63, 0x5e, 0x03, 0x67, 0x33, 0x51, 0x73, 0x8b, 0x1c, 0x06, 0x43, 0x3a, - 0x5d, 0xa1, 0x8f, 0xd0, 0x88, 0xcc, 0xbf, 0xc4, 0x69, 0xfe, 0x54, 0xb3, 0x64, 0x88, 0x74, 0x9a, - 0xfb, 0xaa, 0x4b, 0x01, 0x9b, 0x0f, 0x05, 0x70, 0xac, 0x05, 0x01, 0x47, 0x7e, 0x04, 0xc6, 0x9d, - 0xe8, 0x9e, 0xff, 0xcc, 0x2d, 0x64, 0x4a, 0x03, 0x31, 0x58, 0x9e, 0x03, 0x12, 0x78, 0xa2, 0x05, - 0xc6, 0x62, 0x64, 0x70, 0x0a, 0x70, 0x07, 0x5f, 0xda, 0xe9, 0xf3, 0x4b, 0x70, 0x1a, 0x00, 0x3f, - 0x9f, 0x57, 0x97, 0xe8, 0x85, 0x0e, 0xc8, 0x91, 0x95, 0xb6, 0x4e, 0x2d, 0x6e, 0x01, 0x89, 0xaa, - 0xbc, 0x68, 0x9a, 0x2b, 0xaa, 0xe1, 0xe2, 0x07, 0xaa, 0x59, 0xb1, 0x2d, 0xcf, 0x2f, 0xcb, 0xf1, - 0xf7, 0xa9, 0xba, 0xb4, 0x57, 0x15, 0xd3, 0xcf, 0x05, 0x30, 0x97, 0x9d, 0x27, 0xb7, 0xfc, 0x16, - 0x78, 0xdd, 0x51, 0x0d, 0x57, 0x69, 0xa8, 0xa6, 0x57, 0x66, 0xd2, 0x80, 0xe2, 0xc6, 0x5f, 0xce, - 0x66, 0x7c, 0xd5, 0x70, 0x43, 0x46, 0x41, 0xc0, 0x5a, 0xa1, 0x2b, 0x8d, 0x3b, 0x31, 0x12, 0xf1, - 0xdf, 0x02, 0x38, 0xde, 0xf6, 0x14, 0x5c, 0x6e, 0x15, 0xe5, 0xe5, 0xc9, 0xaf, 0x5f, 0x14, 0x8f, - 0xb0, 0xac, 0x93, 0xa4, 0x48, 0x49, 0xbf, 0xcb, 0x2d, 0xb3, 0x57, 0x04, 0x27, 0x49, 0x91, 0x92, - 0xc6, 0xae, 0x80, 0xfd, 0x01, 0xd5, 0x26, 0x6a, 0xf2, 0x68, 0x9d, 0x2a, 0x85, 0x45, 0x76, 0x89, - 0x15, 0xd9, 0xa5, 0x95, 0xed, 0x75, 0xd3, 0xd0, 0x6e, 0xa2, 0xa6, 0x1c, 0x5c, 0xd8, 0x4d, 0xd4, - 0x14, 0x27, 0x00, 0x64, 0x41, 0xa0, 0xba, 0x6a, 0x18, 0x82, 0x8f, 0xc0, 0xc1, 0xd8, 0x2a, 0xbf, - 0x96, 0x2a, 0x18, 0x72, 0xe8, 0x0a, 0x2f, 0x4e, 0xce, 0x66, 0xbc, 0x0b, 0xef, 0x08, 0x8f, 0x00, - 0x0e, 0x20, 0x9a, 0x3c, 0x25, 0xc4, 0x3c, 0xe0, 0xae, 0x43, 0x90, 0x5e, 0xb5, 0x82, 0x44, 0xbb, - 0x67, 0x65, 0xfb, 0x16, 0x4f, 0x29, 0xed, 0xb8, 0x05, 0x75, 0xed, 0xb1, 0x68, 0x9d, 0x92, 0xb8, - 0x4e, 0xe4, 0x67, 0x9a, 0xc9, 0x48, 0xc1, 0x12, 0xbf, 0x5f, 0x84, 0xc5, 0x47, 0x60, 0x3a, 0xc6, - 0x72, 0xef, 0x95, 0xfa, 0xc9, 0x3e, 0x30, 0xd3, 0x82, 0x45, 0xf0, 0x57, 0x6a, 0x99, 0x20, 0x64, - 0x2f, 0x13, 0x92, 0xfe, 0x95, 0xeb, 0xd0, 0xbf, 0x60, 0x1e, 0x0c, 0xd2, 0x3a, 0x8f, 0x7a, 0x66, - 0x3f, 0xd5, 0x90, 0x2d, 0xc0, 0x8b, 0x60, 0xc0, 0xf5, 0x1e, 0x98, 0x01, 0x2a, 0xcd, 0x29, 0xcf, - 0x3b, 0xfe, 0xf8, 0xa2, 0x38, 0xc9, 0xba, 0x3c, 0xac, 0x6f, 0x96, 0x0c, 0x5b, 0xaa, 0xab, 0x64, - 0xa3, 0x74, 0x0b, 0xd5, 0x54, 0xad, 0xb9, 0x84, 0xb4, 0xbc, 0x20, 0xd3, 0x23, 0xf0, 0x14, 0x18, - 0x0f, 0xa4, 0x62, 0xe8, 0x83, 0xf4, 0x71, 0x1b, 0xf3, 0x57, 0x69, 0xfd, 0x08, 0x1f, 0x82, 0x7c, - 0x40, 0xa6, 0xd9, 0xf5, 0xba, 0x81, 0xb1, 0x61, 0x5b, 0x0a, 0xe5, 0x3a, 0x44, 0xb9, 0x9e, 0xc8, - 0xc0, 0x55, 0x3e, 0xec, 0x83, 0x54, 0x02, 0x0c, 0xd9, 0x93, 0xe2, 0x21, 0xc8, 0x07, 0xa6, 0x4d, - 0xc2, 0xef, 0xeb, 0x00, 0xde, 0x07, 0x49, 0xc0, 0xdf, 0x04, 0xa3, 0x3a, 0xc2, 0x9a, 0x6b, 0x38, - 0x5e, 0x17, 0x92, 0x1f, 0xa6, 0x96, 0x3f, 0x51, 0xe2, 0x3d, 0xb1, 0xdf, 0xf5, 0xf2, 0x2e, 0xb8, - 0xb4, 0x14, 0x92, 0xf2, 0x48, 0x8b, 0x9e, 0x86, 0x0f, 0xc1, 0xd1, 0x40, 0x56, 0xdb, 0x41, 0x2e, - 0xad, 0xa7, 0x7d, 0x7f, 0x18, 0xa1, 0xc2, 0x1e, 0xff, 0xf2, 0xd3, 0xf3, 0xc7, 0x38, 0x7a, 0xe0, - 0x3f, 0xdc, 0x0f, 0xee, 0x11, 0xd7, 0xb0, 0x6a, 0xf2, 0x11, 0x1f, 0xe3, 0x2e, 0x87, 0xf0, 0xdd, - 0xe4, 0x30, 0x18, 0xfa, 0xae, 0x6a, 0x98, 0x48, 0xa7, 0x85, 0xf2, 0xb0, 0xcc, 0xbf, 0xe0, 0x25, - 0x30, 0xe4, 0xb5, 0xc1, 0xdb, 0x38, 0x3f, 0x3a, 0x23, 0xcc, 0x8e, 0x2f, 0x88, 0xad, 0xc4, 0x2f, - 0xdb, 0x96, 0x7e, 0x8f, 0x52, 0xca, 0xfc, 0x04, 0x5c, 0x05, 0x81, 0x37, 0x2a, 0xc4, 0xde, 0x44, - 0x16, 0xce, 0xef, 0xa7, 0x82, 0x9e, 0xe5, 0x56, 0x3d, 0xb4, 0xd3, 0xaa, 0x55, 0x8b, 0x7c, 0xf9, - 0xe9, 0x79, 0xc0, 0x99, 0x54, 0x2d, 0x42, 0x5f, 0x5c, 0x8a, 0xb1, 0x4a, 0x21, 0x3c, 0xd7, 0x09, - 0x50, 0x99, 0xeb, 0x8c, 0x31, 0xd7, 0xf1, 0x57, 0x99, 0xeb, 0xfc, 0x3f, 0x38, 0xc2, 0x83, 0x1b, - 0x61, 0x45, 0xdb, 0x76, 0x5d, 0xaf, 0x25, 0x42, 0x8e, 0xad, 0x6d, 0xe4, 0xc7, 0xa9, 0x86, 0x87, - 0x82, 0xed, 0x0a, 0xdb, 0xbd, 0xe6, 0x6d, 0x7a, 0x2d, 0x6a, 0xb1, 0x65, 0xd8, 0xf3, 0xec, 0x82, - 0x00, 0x08, 0x13, 0x07, 0x7f, 0xd5, 0xae, 0x65, 0xca, 0xa4, 0xed, 0xa2, 0x5d, 0x8e, 0x00, 0x8b, - 0x5b, 0xfc, 0xdd, 0x8d, 0xf7, 0xee, 0x01, 0xed, 0x0d, 0x15, 0xaf, 0xda, 0xfc, 0xcb, 0x2f, 0x3e, - 0x7b, 0xcc, 0x16, 0xa2, 0x0a, 0xe6, 0x3b, 0x60, 0xc9, 0xcd, 0x71, 0x0e, 0xc0, 0x30, 0x4a, 0x79, - 0x3e, 0xf4, 0x33, 0x6c, 0xf0, 0x48, 0xb2, 0x02, 0x41, 0xa7, 0xbd, 0xc3, 0xd9, 0xf4, 0x6e, 0x24, - 0x1e, 0x3e, 0xff, 0x1b, 0x5d, 0x94, 0x58, 0x03, 0xe7, 0xb2, 0x49, 0xcb, 0x8d, 0xf1, 0x16, 0x4f, - 0x8a, 0x42, 0xf6, 0xfc, 0x41, 0x0f, 0x88, 0x22, 0x7f, 0x0b, 0xca, 0xa6, 0xad, 0x6d, 0xe2, 0xfb, - 0x16, 0x31, 0xcc, 0x3b, 0xe8, 0x09, 0xf3, 0x4a, 0xff, 0x55, 0x5f, 0xe3, 0x6d, 0x57, 0x3a, 0x0d, - 0x97, 0xe0, 0x02, 0x38, 0xb2, 0x4e, 0xf7, 0x95, 0x6d, 0x8f, 0x40, 0xa1, 0x8d, 0x01, 0xf3, 0x7c, - 0x81, 0x16, 0x9c, 0x13, 0xeb, 0x29, 0xc7, 0xc5, 0x45, 0xde, 0x24, 0x55, 0x02, 0xdd, 0x97, 0x5d, - 0xbb, 0x5e, 0xe1, 0xa3, 0x03, 0xff, 0x36, 0x62, 0xe3, 0x05, 0x21, 0x3e, 0x5e, 0x10, 0x97, 0xc1, - 0x89, 0x5d, 0x21, 0xc2, 0x0e, 0x28, 0x6a, 0x73, 0x21, 0x69, 0xf3, 0x85, 0x8f, 0x4f, 0x82, 0x41, - 0x0a, 0x04, 0x7f, 0x91, 0x03, 0x13, 0x69, 0xe3, 0x3a, 0x78, 0xb5, 0xf3, 0x70, 0x8b, 0x0f, 0x12, - 0x0b, 0x8b, 0x3d, 0x20, 0x30, 0x45, 0xc4, 0x1f, 0x09, 0xdf, 0xfb, 0xea, 0xaf, 0x3f, 0xcd, 0x7d, - 0x5f, 0x58, 0x2b, 0xc3, 0xab, 0xed, 0xc7, 0xc9, 0x81, 0xd2, 0x7c, 0x26, 0x28, 0x3d, 0x8d, 0x98, - 0xe1, 0x19, 0xbc, 0xdc, 0x15, 0x02, 0x0f, 0x8d, 0x67, 0xf0, 0x2b, 0x81, 0x97, 0x7c, 0xf1, 0xd8, - 0x85, 0x57, 0x3a, 0xd7, 0x33, 0x36, 0x96, 0x2c, 0x5c, 0xed, 0x1e, 0x80, 0xdb, 0xe9, 0x22, 0x35, - 0xd3, 0x9b, 0x70, 0xbe, 0x03, 0x0d, 0xd9, 0x70, 0x11, 0x7e, 0x98, 0x03, 0xf9, 0x16, 0x13, 0x43, - 0x0c, 0x6f, 0x75, 0x29, 0x59, 0xea, 0x70, 0xb2, 0x70, 0x7b, 0x8f, 0xd0, 0xb8, 0xd2, 0x37, 0xa8, - 0xd2, 0x9d, 0x39, 0x06, 0x27, 0xf2, 0x00, 0x95, 0x60, 0xee, 0x07, 0xff, 0x23, 0x80, 0x23, 0xe9, - 0x03, 0x48, 0x0c, 0x6f, 0x76, 0x2d, 0xf4, 0xce, 0x49, 0x67, 0xe1, 0xd6, 0xde, 0x80, 0x71, 0x03, - 0x5c, 0xa7, 0x06, 0x58, 0x84, 0x57, 0xba, 0x30, 0x80, 0xed, 0x44, 0xf4, 0xff, 0xa7, 0x3f, 0x50, - 0x49, 0x9d, 0x5f, 0xc1, 0xe5, 0xec, 0x52, 0xef, 0x36, 0xae, 0x2b, 0x5c, 0xef, 0x19, 0x87, 0x2b, - 0xbe, 0x48, 0x15, 0xff, 0x06, 0xbc, 0x98, 0xe1, 0x17, 0xa6, 0x60, 0x34, 0x1a, 0x6b, 0x15, 0x53, - 0x54, 0x8e, 0xf6, 0x27, 0x5d, 0xa9, 0x9c, 0x32, 0xa1, 0xeb, 0x4a, 0xe5, 0xb4, 0xd9, 0x59, 0x77, - 0x2a, 0xc7, 0xde, 0x6d, 0xf8, 0x3b, 0x81, 0x37, 0xb2, 0xb1, 0xb1, 0x19, 0x7c, 0x27, 0xbb, 0x88, - 0x69, 0xd3, 0xb8, 0xc2, 0x95, 0xae, 0xcf, 0x73, 0xd5, 0xde, 0xa6, 0xaa, 0x2d, 0xc0, 0xb9, 0xf6, - 0xaa, 0x11, 0x0e, 0xc0, 0x7e, 0x39, 0x82, 0x3f, 0xcb, 0xf1, 0xf7, 0x70, 0xf7, 0x39, 0x18, 0xbc, - 0x9b, 0x5d, 0xc4, 0x4c, 0xf3, 0xb7, 0xc2, 0xca, 0xde, 0x01, 0x72, 0x23, 0xdc, 0xa4, 0x46, 0xb8, - 0x06, 0x2b, 0xed, 0x8d, 0xe0, 0x06, 0x88, 0xa1, 0x4f, 0xbb, 0x14, 0x53, 0x61, 0x73, 0x3d, 0xf8, - 0xf7, 0x1d, 0x73, 0xbb, 0xf8, 0x10, 0x09, 0xc3, 0x0e, 0xde, 0xe6, 0x16, 0xc3, 0xc1, 0x42, 0xb9, - 0x17, 0x08, 0xae, 0x75, 0x99, 0x6a, 0xfd, 0x4d, 0x78, 0xa9, 0xbd, 0xd6, 0xfe, 0x58, 0x50, 0x49, - 0x3e, 0x60, 0x9f, 0xe5, 0xf8, 0x4f, 0x5e, 0x19, 0xa6, 0x67, 0x70, 0x35, 0xbb, 0xd0, 0xd9, 0x07, - 0x80, 0x85, 0xfb, 0x7b, 0x8c, 0xca, 0xad, 0x53, 0xa3, 0xd6, 0x51, 0xd7, 0xe6, 0xa1, 0xd4, 0xde, - 0x3e, 0xf1, 0x52, 0xe7, 0x5c, 0x96, 0x03, 0x41, 0x65, 0xf3, 0x2b, 0x01, 0x8c, 0x46, 0x86, 0x59, - 0xf0, 0xad, 0x0e, 0xae, 0x36, 0x3a, 0x14, 0x2b, 0xbc, 0xdd, 0xf9, 0x41, 0xae, 0xeb, 0x1c, 0xd5, - 0xf5, 0x0c, 0x9c, 0xcd, 0xe0, 0x09, 0x4c, 0xc8, 0x3f, 0xe5, 0x12, 0xc5, 0x70, 0xfa, 0xc4, 0xaa, - 0x93, 0xe0, 0xcf, 0x34, 0x69, 0xeb, 0x24, 0xf8, 0xb3, 0x0d, 0xd3, 0xc4, 0xe7, 0xac, 0xcc, 0xfd, - 0x58, 0x58, 0xcb, 0x94, 0x00, 0x6c, 0x0f, 0x48, 0x31, 0x2c, 0x25, 0x6c, 0x65, 0x13, 0xd7, 0x7f, - 0xb5, 0x5b, 0x90, 0xc0, 0x25, 0x7e, 0x9d, 0x03, 0xa7, 0x33, 0x37, 0xaa, 0xf0, 0x7e, 0xb7, 0x15, - 0xec, 0xae, 0xbd, 0x76, 0xe1, 0xc1, 0x5e, 0xc3, 0x72, 0x7b, 0xaf, 0x51, 0x73, 0xaf, 0x42, 0xb9, - 0xe3, 0x72, 0x59, 0x71, 0x90, 0x1b, 0x5a, 0x4c, 0x7a, 0x9a, 0xec, 0x8c, 0x9f, 0xc1, 0x1f, 0xf7, - 0x83, 0x93, 0x59, 0xfa, 0x59, 0xb8, 0xd2, 0x43, 0x35, 0x94, 0xda, 0xc8, 0x17, 0xde, 0xdd, 0x43, - 0x44, 0x6e, 0xa9, 0xcf, 0x98, 0x67, 0xfe, 0x56, 0x58, 0x7b, 0x08, 0xdf, 0xef, 0xc4, 0x5a, 0xf1, - 0x61, 0x5f, 0xdc, 0x3d, 0xd3, 0xcc, 0xf6, 0xad, 0x9e, 0xc0, 0x7d, 0xb7, 0x4d, 0x43, 0xfe, 0x4d, - 0x2e, 0x51, 0xdc, 0x47, 0x72, 0x43, 0xa5, 0x97, 0x99, 0x92, 0x6f, 0xf6, 0xa5, 0xde, 0x40, 0xba, - 0xcb, 0x01, 0x81, 0x31, 0x7a, 0xc9, 0x01, 0xe9, 0x20, 0x41, 0x0e, 0xf8, 0x87, 0xc0, 0x7f, 0x85, - 0x4d, 0x9b, 0x86, 0xc0, 0x0e, 0xe6, 0x71, 0xbb, 0x4c, 0x5c, 0x0a, 0xcb, 0xbd, 0xc2, 0x74, 0x5e, - 0x20, 0xb7, 0x18, 0xde, 0xc0, 0x7f, 0x09, 0x89, 0xff, 0xe5, 0x89, 0x8f, 0x57, 0xe0, 0xf5, 0xce, - 0x2f, 0x3a, 0x75, 0xc6, 0x53, 0xb8, 0xd1, 0x3b, 0x50, 0xe7, 0x5a, 0x47, 0x9c, 0x43, 0x7a, 0x1a, - 0x8c, 0x98, 0x9e, 0x95, 0xdf, 0xfb, 0xfc, 0xe5, 0xb4, 0xf0, 0xc5, 0xcb, 0x69, 0xe1, 0x2f, 0x2f, - 0xa7, 0x85, 0xe7, 0xaf, 0xa6, 0xfb, 0xbe, 0x78, 0x35, 0xdd, 0xf7, 0x87, 0x57, 0xd3, 0x7d, 0x6b, - 0x97, 0x6b, 0x06, 0xd9, 0xd8, 0x5e, 0x2f, 0x69, 0x76, 0x9d, 0xff, 0x9f, 0x59, 0x84, 0xcb, 0xf9, - 0x80, 0x4b, 0xe3, 0x82, 0xf4, 0x24, 0x51, 0xa6, 0x37, 0x1d, 0x84, 0xd7, 0x87, 0xe8, 0x0f, 0xe1, - 0x6f, 0xfe, 0x37, 0x00, 0x00, 0xff, 0xff, 0xe9, 0xed, 0x8b, 0x5e, 0x07, 0x28, 0x00, 0x00, + 0x15, 0x16, 0xf5, 0x67, 0x69, 0x14, 0xc9, 0xc9, 0x58, 0xb6, 0xd7, 0x2b, 0x59, 0x2b, 0xd3, 0x76, + 0x2a, 0xff, 0x2d, 0x25, 0x05, 0x6e, 0x62, 0xb7, 0x8e, 0xad, 0x5d, 0x59, 0xf6, 0xc2, 0x7f, 0x0a, + 0x2d, 0x3b, 0x85, 0x52, 0x97, 0xa6, 0xc8, 0xc9, 0x8a, 0x15, 0x97, 0xa4, 0x38, 0xa3, 0xb5, 0x17, + 0x86, 0x0f, 0x69, 0x81, 0x22, 0xe9, 0xa1, 0x70, 0x51, 0xf4, 0x9e, 0x43, 0x0b, 0xf4, 0xd0, 0x53, + 0x11, 0xb4, 0x28, 0x7a, 0xc9, 0x31, 0xb7, 0xa6, 0xc9, 0xa5, 0x68, 0x01, 0xb7, 0xb0, 0x7b, 0x28, + 0x0a, 0x14, 0x28, 0xd2, 0x5e, 0x0b, 0x14, 0x9c, 0x19, 0xfe, 0x8a, 0x2b, 0x91, 0xbb, 0x3a, 0xf4, + 0x26, 0xce, 0xbc, 0xf9, 0xde, 0xcf, 0xbc, 0xf7, 0xe6, 0xbd, 0xb7, 0x02, 0x92, 0x61, 0x11, 0xe4, + 0x6a, 0xeb, 0xaa, 0x61, 0x29, 0x18, 0x69, 0x5b, 0xae, 0x41, 0x5a, 0x92, 0xa6, 0x35, 0x25, 0xc7, + 0xb5, 0x9b, 0x86, 0x8e, 0x5c, 0xa9, 0x39, 0x27, 0x6d, 0x6e, 0x21, 0xb7, 0x55, 0x76, 0x5c, 0x9b, + 0xd8, 0xf0, 0x78, 0xca, 0x81, 0xb2, 0xa6, 0x35, 0xcb, 0xfe, 0x81, 0x72, 0x73, 0xae, 0x38, 0x59, + 0xb7, 0xed, 0xba, 0x89, 0x24, 0xd5, 0x31, 0x24, 0xd5, 0xb2, 0x6c, 0xa2, 0x12, 0xc3, 0xb6, 0x30, + 0x83, 0x28, 0x8e, 0xd7, 0xed, 0xba, 0x4d, 0xff, 0x94, 0xbc, 0xbf, 0xf8, 0x6a, 0x89, 0x9f, 0xa1, + 0x5f, 0x6b, 0x5b, 0xef, 0x4b, 0xc4, 0x68, 0x20, 0x4c, 0xd4, 0x86, 0xc3, 0x09, 0xe6, 0xb3, 0x88, + 0x1a, 0x48, 0xc1, 0xce, 0xcc, 0xb6, 0x3b, 0xd3, 0x9c, 0x93, 0xf0, 0xba, 0xea, 0x22, 0x5d, 0xd1, + 0x6c, 0x0b, 0x6f, 0x35, 0x82, 0x13, 0x27, 0x77, 0x38, 0xf1, 0xc8, 0x70, 0x11, 0x27, 0x9b, 0x24, + 0xc8, 0xd2, 0x91, 0xdb, 0x30, 0x2c, 0x22, 0x69, 0x6e, 0xcb, 0x21, 0xb6, 0xb4, 0x81, 0x5a, 0xbe, + 0x86, 0x47, 0x34, 0x1b, 0x37, 0x6c, 0xac, 0x30, 0x25, 0xd9, 0x07, 0xdf, 0x3a, 0xc1, 0xbe, 0x24, + 0x4c, 0xd4, 0x0d, 0xc3, 0xaa, 0x4b, 0xcd, 0xb9, 0x35, 0x44, 0xd4, 0x39, 0xff, 0x9b, 0x51, 0x89, + 0x0f, 0xc0, 0xc4, 0x3b, 0x9e, 0xd1, 0xab, 0x5c, 0xb8, 0x6b, 0xc8, 0x42, 0xd8, 0xc0, 0x32, 0xda, + 0xdc, 0x42, 0x98, 0xc0, 0xa3, 0x60, 0x88, 0x49, 0x68, 0xe8, 0x05, 0x61, 0x5a, 0x98, 0x19, 0xae, + 0xf4, 0x16, 0x04, 0x79, 0x1f, 0x5d, 0xab, 0xe9, 0xb0, 0x04, 0x46, 0x7c, 0xad, 0x3c, 0x8a, 0x5e, + 0x8f, 0x42, 0x06, 0xfe, 0x52, 0x4d, 0x17, 0x9f, 0x80, 0xc9, 0x74, 0x78, 0xec, 0xd8, 0x16, 0x46, + 0xf0, 0x3d, 0x30, 0x5a, 0x67, 0x4b, 0x0a, 0x26, 0x2a, 0x41, 0x94, 0xc9, 0xc8, 0xfc, 0x6c, 0xb9, + 0xdd, 0xe5, 0x37, 0xe7, 0xca, 0x09, 0xac, 0xbb, 0xde, 0xb9, 0x4a, 0xff, 0x67, 0xcf, 0x4b, 0x3d, + 0xf2, 0x2b, 0xf5, 0xc8, 0x9a, 0xf8, 0x33, 0x01, 0x14, 0x63, 0xdc, 0xab, 0x1e, 0x5e, 0xa0, 0xdb, + 0xeb, 0x60, 0xff, 0xfb, 0x86, 0x49, 0x90, 0xab, 0xac, 0xb5, 0x14, 0x67, 0x5d, 0xc5, 0x8c, 0xfb, + 0x90, 0x3c, 0xca, 0x96, 0x2b, 0xad, 0x65, 0x6f, 0x11, 0x5e, 0x07, 0x03, 0x6c, 0xd7, 0x53, 0x6f, + 0x6c, 0x7e, 0xbe, 0x9c, 0xc1, 0x31, 0x03, 0x21, 0x29, 0x84, 0xcc, 0x00, 0xe0, 0x38, 0x18, 0x30, + 0x8d, 0x86, 0x41, 0x0a, 0x7d, 0xd3, 0xc2, 0xcc, 0x80, 0xcc, 0x3e, 0x44, 0x35, 0x71, 0x05, 0xbe, + 0x94, 0xdc, 0x44, 0x15, 0x30, 0x48, 0x79, 0xe1, 0x82, 0x30, 0xdd, 0x37, 0x33, 0x32, 0x7f, 0x3a, + 0x1b, 0x7f, 0x6f, 0x5b, 0xe6, 0x27, 0xc5, 0x53, 0xe0, 0x6b, 0xdb, 0x59, 0xdc, 0x25, 0xaa, 0x4b, + 0x96, 0x5d, 0xdb, 0xb1, 0xb1, 0x6a, 0xfa, 0x56, 0x11, 0x3f, 0x14, 0xc0, 0xcc, 0xee, 0xb4, 0x5c, + 0xb6, 0x6f, 0x83, 0x61, 0xc7, 0x5f, 0xe4, 0x57, 0xf7, 0x76, 0x2e, 0xf3, 0x2c, 0xe8, 0xba, 0xe1, + 0x45, 0x6c, 0x08, 0x1d, 0x02, 0x8a, 0x33, 0xe0, 0xf5, 0x34, 0x49, 0x6c, 0x67, 0x9b, 0xd0, 0x3f, + 0x10, 0xd2, 0x15, 0x8c, 0x91, 0x06, 0x2e, 0xb7, 0x4d, 0xe6, 0x4b, 0xb9, 0x64, 0x96, 0x51, 0xc3, + 0x6e, 0xaa, 0x66, 0xaa, 0xc8, 0xbf, 0xeb, 0x03, 0x03, 0x94, 0x37, 0x3c, 0x92, 0x8c, 0x9c, 0x30, + 0x6a, 0x26, 0xc0, 0xb0, 0x66, 0x1a, 0xc8, 0x22, 0x61, 0xcc, 0x0c, 0xb1, 0x85, 0x9a, 0x0e, 0x0f, + 0x80, 0x01, 0x62, 0x3b, 0xca, 0x6d, 0xea, 0x23, 0xa3, 0x72, 0x3f, 0xb1, 0x9d, 0xdb, 0xf0, 0x34, + 0x80, 0x0d, 0xc3, 0x52, 0x1c, 0xfb, 0x91, 0x17, 0x68, 0x96, 0xc2, 0x28, 0xfa, 0xa7, 0x85, 0x99, + 0x3e, 0x79, 0xac, 0x61, 0x58, 0xcb, 0xde, 0x46, 0xcd, 0x5a, 0xf1, 0x68, 0x67, 0xc1, 0x78, 0x53, + 0x35, 0x0d, 0x5d, 0x25, 0xb6, 0x8b, 0xf9, 0x11, 0x4d, 0x75, 0x0a, 0x03, 0x14, 0x0f, 0x86, 0x7b, + 0xf4, 0x50, 0x55, 0x75, 0xe0, 0x69, 0xf0, 0x5a, 0xb0, 0xaa, 0x60, 0x44, 0x28, 0xf9, 0x20, 0x25, + 0xdf, 0x1f, 0x6c, 0xdc, 0x45, 0xc4, 0xa3, 0x9d, 0x04, 0xc3, 0xaa, 0x69, 0xda, 0x8f, 0x4c, 0x03, + 0x93, 0xc2, 0xbe, 0xe9, 0xbe, 0x99, 0x61, 0x39, 0x5c, 0x80, 0x45, 0x30, 0xa4, 0x23, 0xab, 0x45, + 0x37, 0x87, 0xe8, 0x66, 0xf0, 0x1d, 0x86, 0xd1, 0x70, 0xb7, 0x61, 0xf4, 0x2e, 0x18, 0x6a, 0x20, + 0xa2, 0xea, 0x2a, 0x51, 0x0b, 0x80, 0x5e, 0xe0, 0xf9, 0x5c, 0x60, 0xb7, 0xf8, 0x61, 0x9e, 0x34, + 0x02, 0x30, 0xf1, 0x97, 0x02, 0x38, 0x46, 0xdd, 0xe8, 0xbe, 0xaf, 0x75, 0xc4, 0x4f, 0xdd, 0x8c, + 0x39, 0xf1, 0x12, 0x78, 0xd5, 0x67, 0xaa, 0xa8, 0xba, 0xee, 0x22, 0x8c, 0xd9, 0x25, 0x57, 0xe0, + 0x57, 0xcf, 0x4b, 0x63, 0x2d, 0xb5, 0x61, 0x5e, 0x14, 0xf9, 0x86, 0x28, 0xef, 0xf7, 0x69, 0x17, + 0xd8, 0x4a, 0x32, 0xa5, 0xf6, 0x25, 0x53, 0xea, 0xc5, 0xa1, 0x0f, 0x3f, 0x2e, 0xf5, 0xfc, 0xfd, + 0xe3, 0x52, 0x8f, 0x78, 0x07, 0x88, 0x3b, 0x49, 0xcb, 0xfd, 0xfd, 0x14, 0x78, 0x35, 0x00, 0xf4, + 0xe5, 0x61, 0x0e, 0xb9, 0x5f, 0x8b, 0xd0, 0x7b, 0xd2, 0x6c, 0xd7, 0x7f, 0x39, 0x22, 0x5d, 0x76, + 0xfd, 0xb7, 0xf1, 0xdb, 0x41, 0xff, 0x84, 0x0c, 0x5d, 0xe9, 0x1f, 0x97, 0x36, 0xd4, 0x7f, 0xdb, + 0x7d, 0x70, 0xfd, 0x13, 0xb6, 0x17, 0x27, 0xc0, 0x11, 0x0a, 0xb8, 0xb2, 0xee, 0xda, 0x84, 0x98, + 0x88, 0x3e, 0x23, 0x7e, 0x8e, 0xf9, 0x83, 0xff, 0x9a, 0x24, 0x76, 0x39, 0x9b, 0x12, 0x18, 0xc1, + 0xa6, 0x8a, 0xd7, 0x95, 0x06, 0x22, 0xc8, 0xa5, 0x1c, 0xfa, 0x64, 0x40, 0x97, 0x6e, 0x79, 0x2b, + 0x70, 0x1e, 0x1c, 0x8c, 0x10, 0x28, 0x34, 0x68, 0x54, 0x4b, 0x63, 0xcf, 0x4a, 0x9f, 0x7c, 0x20, + 0x24, 0x5d, 0xf0, 0xb7, 0xe0, 0x77, 0x40, 0xc1, 0x42, 0x8f, 0x89, 0xe2, 0x22, 0xc7, 0x44, 0x96, + 0x81, 0xd7, 0x15, 0x4d, 0xb5, 0x74, 0x4f, 0x59, 0x44, 0x2d, 0x33, 0x32, 0x5f, 0x2c, 0xb3, 0x6a, + 0xa6, 0xec, 0x57, 0x33, 0xe5, 0x15, 0xbf, 0x9a, 0xa9, 0x0c, 0x79, 0xee, 0xfd, 0xec, 0x2f, 0x25, + 0x41, 0x3e, 0xe4, 0xa1, 0xc8, 0x3e, 0x48, 0xd5, 0xc7, 0x10, 0xcf, 0x82, 0xd3, 0x54, 0x25, 0x19, + 0xd5, 0x0d, 0x4c, 0x90, 0x8b, 0xf4, 0x30, 0xc9, 0x3d, 0x52, 0x5d, 0x7d, 0x11, 0x59, 0x76, 0x23, + 0xc8, 0xb2, 0x57, 0xc1, 0x99, 0x4c, 0xd4, 0xdc, 0x22, 0x87, 0xc0, 0xa0, 0x4e, 0x57, 0xe8, 0xc3, + 0x35, 0x2c, 0xf3, 0x2f, 0x71, 0x8a, 0xd7, 0x04, 0x2c, 0x81, 0x22, 0x9d, 0xe6, 0xcb, 0xda, 0x62, + 0xc0, 0xe6, 0x03, 0x01, 0x1c, 0x6d, 0x43, 0xc0, 0x91, 0x1f, 0x82, 0x31, 0x27, 0xba, 0xe7, 0x3f, + 0x8d, 0xd9, 0x72, 0x4a, 0x0c, 0x96, 0xe7, 0x80, 0x04, 0x9e, 0x68, 0x81, 0xd1, 0x18, 0x19, 0x9c, + 0x04, 0xdc, 0xc1, 0x17, 0xb7, 0xfb, 0xfc, 0x22, 0x9c, 0x02, 0xc0, 0x7f, 0x03, 0x6a, 0x8b, 0xf4, + 0x42, 0xfb, 0xe5, 0xc8, 0xca, 0xae, 0x4e, 0x2d, 0x6e, 0x02, 0x89, 0xaa, 0xbc, 0x60, 0x9a, 0xcb, + 0xaa, 0xe1, 0xe2, 0xfb, 0xaa, 0x59, 0xb5, 0x2d, 0xcf, 0x2f, 0x2b, 0xf1, 0x37, 0xad, 0xb6, 0xb8, + 0x57, 0xa5, 0xd9, 0xcf, 0x05, 0x30, 0x9b, 0x9d, 0x27, 0xb7, 0xfc, 0x26, 0x78, 0xcd, 0x51, 0x0d, + 0x57, 0x69, 0xaa, 0xa6, 0x57, 0xcf, 0xd2, 0x80, 0xe2, 0xc6, 0x5f, 0xca, 0x66, 0x7c, 0xd5, 0x70, + 0x43, 0x46, 0x41, 0xc0, 0x5a, 0xa1, 0x2b, 0x8d, 0x39, 0x31, 0x12, 0xf1, 0x3f, 0x02, 0x38, 0xb6, + 0xeb, 0x29, 0xb8, 0xd4, 0x2e, 0xca, 0x2b, 0x13, 0x5f, 0x3d, 0x2f, 0x1d, 0x66, 0x59, 0x27, 0x49, + 0x91, 0x92, 0x7e, 0x97, 0xda, 0x66, 0xaf, 0x08, 0x4e, 0x92, 0x22, 0x25, 0x8d, 0x5d, 0x06, 0xaf, + 0x04, 0x54, 0x1b, 0xa8, 0xc5, 0xa3, 0x75, 0xb2, 0x1c, 0x56, 0xf3, 0x65, 0x56, 0xcd, 0x97, 0x97, + 0xb7, 0xd6, 0x4c, 0x43, 0xbb, 0x81, 0x5a, 0x72, 0x70, 0x61, 0x37, 0x50, 0x4b, 0x1c, 0x07, 0x90, + 0x05, 0x81, 0xea, 0xaa, 0x61, 0x08, 0x3e, 0x04, 0x07, 0x62, 0xab, 0xfc, 0x5a, 0x6a, 0x60, 0xd0, + 0xa1, 0x2b, 0xbc, 0xa0, 0x39, 0x93, 0xf1, 0x2e, 0xbc, 0x23, 0x3c, 0x02, 0x38, 0x80, 0x68, 0xf2, + 0x94, 0x10, 0xf3, 0x80, 0x3b, 0x0e, 0x41, 0x7a, 0xcd, 0x0a, 0x12, 0xed, 0x9e, 0xf5, 0x07, 0x9b, + 0x3c, 0xa5, 0xec, 0xc6, 0x2d, 0xa8, 0x85, 0x8f, 0x46, 0x6b, 0x9b, 0xc4, 0x75, 0x22, 0x3f, 0xd3, + 0x4c, 0x44, 0x8a, 0x9c, 0xf8, 0xfd, 0x22, 0x2c, 0x3e, 0x04, 0x53, 0x31, 0x96, 0x7b, 0xaf, 0xd4, + 0x8f, 0xf7, 0x81, 0xe9, 0x36, 0x2c, 0x82, 0xbf, 0x52, 0xcb, 0x04, 0x21, 0x7b, 0x99, 0x90, 0xf4, + 0xaf, 0xde, 0x9c, 0xfe, 0x05, 0x0b, 0x60, 0x80, 0xd6, 0x86, 0xd4, 0x33, 0xfb, 0xa8, 0x86, 0x6c, + 0x01, 0x5e, 0x00, 0xfd, 0xae, 0xf7, 0xc0, 0xf4, 0x53, 0x69, 0x4e, 0x7a, 0xde, 0xf1, 0xa7, 0xe7, + 0xa5, 0x09, 0xd6, 0x4e, 0x62, 0x7d, 0xa3, 0x6c, 0xd8, 0x52, 0x43, 0x25, 0xeb, 0xe5, 0x9b, 0xa8, + 0xae, 0x6a, 0xad, 0x45, 0xa4, 0x15, 0x04, 0x99, 0x1e, 0x81, 0x27, 0xc1, 0x58, 0x20, 0x15, 0x43, + 0x1f, 0xa0, 0x8f, 0xdb, 0xa8, 0xbf, 0x4a, 0x6b, 0x4e, 0xf8, 0x00, 0x14, 0x02, 0x32, 0xcd, 0x6e, + 0x34, 0x0c, 0x8c, 0x0d, 0xdb, 0x52, 0x28, 0xd7, 0x41, 0xca, 0xf5, 0x78, 0x06, 0xae, 0xf2, 0x21, + 0x1f, 0xa4, 0x1a, 0x60, 0xc8, 0x9e, 0x14, 0x0f, 0x40, 0x21, 0x30, 0x6d, 0x12, 0x7e, 0x5f, 0x0e, + 0x78, 0x1f, 0x24, 0x01, 0x7f, 0x03, 0x8c, 0xe8, 0x08, 0x6b, 0xae, 0xe1, 0x78, 0x9d, 0x4b, 0x61, + 0x88, 0x5a, 0xfe, 0x78, 0x99, 0x37, 0xdf, 0x7e, 0x7b, 0xcd, 0xdb, 0xed, 0xf2, 0x62, 0x48, 0xca, + 0x23, 0x2d, 0x7a, 0x1a, 0x3e, 0x00, 0x47, 0x02, 0x59, 0x6d, 0x07, 0xb9, 0xb4, 0x06, 0xf7, 0xfd, + 0x61, 0x98, 0x0a, 0x7b, 0xec, 0x8b, 0x4f, 0xce, 0x1d, 0xe5, 0xe8, 0x81, 0xff, 0x70, 0x3f, 0xb8, + 0x4b, 0x5c, 0xc3, 0xaa, 0xcb, 0x87, 0x7d, 0x8c, 0x3b, 0x1c, 0xc2, 0x77, 0x93, 0x43, 0x60, 0xf0, + 0xbb, 0xaa, 0x61, 0x22, 0x9d, 0x16, 0xca, 0x43, 0x32, 0xff, 0x82, 0x17, 0xc1, 0xa0, 0xd7, 0x6f, + 0x6f, 0xe1, 0xc2, 0x08, 0xad, 0xc6, 0xc5, 0x76, 0xe2, 0x57, 0x6c, 0x4b, 0xbf, 0x4b, 0x29, 0x65, + 0x7e, 0x02, 0xae, 0x80, 0xc0, 0x1b, 0x15, 0x62, 0x6f, 0x20, 0x0b, 0x17, 0x5e, 0xa1, 0x82, 0x9e, + 0xe1, 0x56, 0x3d, 0xb8, 0xdd, 0xaa, 0x35, 0x8b, 0x7c, 0xf1, 0xc9, 0x39, 0xc0, 0x99, 0xd4, 0x2c, + 0x42, 0x5f, 0x5c, 0x8a, 0xb1, 0x42, 0x21, 0x3c, 0xd7, 0x09, 0x50, 0x99, 0xeb, 0x8c, 0x32, 0xd7, + 0xf1, 0x57, 0x99, 0xeb, 0x7c, 0x1d, 0x1c, 0xe6, 0xc1, 0x8d, 0xb0, 0xa2, 0x6d, 0xb9, 0xae, 0xd7, + 0x46, 0x21, 0xc7, 0xd6, 0xd6, 0x0b, 0x63, 0x54, 0xc3, 0x83, 0xc1, 0x76, 0x95, 0xed, 0x5e, 0xf5, + 0x36, 0xbd, 0xb6, 0xb6, 0xd4, 0x36, 0xec, 0x79, 0x76, 0x41, 0x00, 0x84, 0x89, 0x83, 0xbf, 0x6a, + 0x57, 0x33, 0x65, 0xd2, 0xdd, 0xa2, 0x5d, 0x8e, 0x00, 0x8b, 0x9b, 0xfc, 0xdd, 0x8d, 0xf7, 0xfb, + 0x01, 0xed, 0x75, 0x15, 0xaf, 0xd8, 0xfc, 0xcb, 0x2f, 0x3e, 0xbb, 0xcc, 0x16, 0xa2, 0x0a, 0xe6, + 0x72, 0xb0, 0xe4, 0xe6, 0x38, 0x0b, 0x60, 0x18, 0xa5, 0x3c, 0x1f, 0xfa, 0x19, 0x36, 0x78, 0x24, + 0x59, 0x81, 0xa0, 0xd3, 0xde, 0xe1, 0x4c, 0x7a, 0x37, 0x12, 0x0f, 0x9f, 0xff, 0x8f, 0x2e, 0x4a, + 0xac, 0x83, 0xb3, 0xd9, 0xa4, 0xe5, 0xc6, 0x78, 0x93, 0x27, 0x45, 0x21, 0x7b, 0xfe, 0xa0, 0x07, + 0x44, 0x91, 0xbf, 0x05, 0x15, 0xd3, 0xd6, 0x36, 0xf0, 0x3d, 0x8b, 0x18, 0xe6, 0x6d, 0xf4, 0x98, + 0x79, 0xa5, 0xff, 0xaa, 0xaf, 0xf2, 0xb6, 0x2b, 0x9d, 0x86, 0x4b, 0x70, 0x1e, 0x1c, 0x5e, 0xa3, + 0xfb, 0xca, 0x96, 0x47, 0xa0, 0xd0, 0xc6, 0x80, 0x79, 0xbe, 0x40, 0x0b, 0xce, 0xf1, 0xb5, 0x94, + 0xe3, 0xe2, 0x02, 0x6f, 0x92, 0xaa, 0x81, 0xee, 0x4b, 0xae, 0xdd, 0xa8, 0xf2, 0x71, 0x83, 0x7f, + 0x1b, 0xb1, 0x91, 0x84, 0x10, 0x1f, 0x49, 0x88, 0x4b, 0xe0, 0xf8, 0x8e, 0x10, 0x61, 0x07, 0x14, + 0xb5, 0xb9, 0x90, 0xb4, 0xf9, 0xfc, 0x47, 0x27, 0xc0, 0x00, 0x05, 0x82, 0xbf, 0xe8, 0x05, 0xe3, + 0x69, 0x73, 0x41, 0x78, 0x25, 0x7f, 0xb8, 0xc5, 0x27, 0x96, 0xc5, 0x85, 0x2e, 0x10, 0x98, 0x22, + 0xe2, 0x0f, 0x85, 0xef, 0x7d, 0xf9, 0xb7, 0x9f, 0xf4, 0x7e, 0x5f, 0x58, 0xad, 0xc0, 0x2b, 0xbb, + 0xcf, 0xad, 0x03, 0xa5, 0xf9, 0xf0, 0x51, 0x7a, 0x12, 0x31, 0xc3, 0x53, 0x78, 0xa9, 0x23, 0x04, + 0x1e, 0x1a, 0x4f, 0xe1, 0x97, 0x02, 0x2f, 0xf9, 0xe2, 0xb1, 0x0b, 0x2f, 0xe7, 0xd7, 0x33, 0x36, + 0xfe, 0x2c, 0x5e, 0xe9, 0x1c, 0x80, 0xdb, 0xe9, 0x02, 0x35, 0xd3, 0x1b, 0x70, 0x2e, 0x87, 0x86, + 0x6c, 0x20, 0x09, 0x3f, 0xe8, 0x05, 0x85, 0x36, 0x53, 0x46, 0x0c, 0x6f, 0x76, 0x28, 0x59, 0xea, + 0x40, 0xb3, 0x78, 0x6b, 0x8f, 0xd0, 0xb8, 0xd2, 0xd7, 0xa9, 0xd2, 0xf9, 0x1c, 0x83, 0x13, 0x79, + 0x80, 0x4a, 0x30, 0x2b, 0x84, 0xff, 0x15, 0xc0, 0xe1, 0xf4, 0xa1, 0x25, 0x86, 0x37, 0x3a, 0x16, + 0x7a, 0xfb, 0x74, 0xb4, 0x78, 0x73, 0x6f, 0xc0, 0xb8, 0x01, 0xae, 0x51, 0x03, 0x2c, 0xc0, 0xcb, + 0x1d, 0x18, 0xc0, 0x76, 0x22, 0xfa, 0xff, 0xcb, 0x1f, 0xa8, 0xa4, 0xce, 0xaf, 0xe0, 0x52, 0x76, + 0xa9, 0x77, 0x1a, 0xd7, 0x15, 0xaf, 0x75, 0x8d, 0xc3, 0x15, 0x5f, 0xa0, 0x8a, 0x7f, 0x03, 0x5e, + 0xc8, 0xf0, 0x53, 0x56, 0x30, 0x4e, 0x8d, 0xb5, 0x8a, 0x29, 0x2a, 0x47, 0xfb, 0x93, 0x8e, 0x54, + 0x4e, 0x99, 0xd0, 0x75, 0xa4, 0x72, 0xda, 0xec, 0xac, 0x33, 0x95, 0x63, 0xef, 0x36, 0xfc, 0xbd, + 0xc0, 0x1b, 0xd9, 0xd8, 0xd8, 0x0c, 0xbe, 0x9d, 0x5d, 0xc4, 0xb4, 0x69, 0x5c, 0xf1, 0x72, 0xc7, + 0xe7, 0xb9, 0x6a, 0x6f, 0x51, 0xd5, 0xe6, 0xe1, 0xec, 0xee, 0xaa, 0x11, 0x0e, 0xc0, 0x7e, 0xa2, + 0x82, 0x3f, 0xed, 0xe5, 0xef, 0xe1, 0xce, 0x73, 0x30, 0x78, 0x27, 0xbb, 0x88, 0x99, 0xe6, 0x6f, + 0xc5, 0xe5, 0xbd, 0x03, 0xe4, 0x46, 0xb8, 0x41, 0x8d, 0x70, 0x15, 0x56, 0x77, 0x37, 0x82, 0x1b, + 0x20, 0x86, 0x3e, 0xed, 0x52, 0x4c, 0x85, 0xcd, 0xf5, 0xe0, 0x3f, 0xb6, 0xcd, 0xed, 0xe2, 0x43, + 0x24, 0x0c, 0x73, 0xbc, 0xcd, 0x6d, 0x86, 0x83, 0xc5, 0x4a, 0x37, 0x10, 0x5c, 0xeb, 0x0a, 0xd5, + 0xfa, 0x9b, 0xf0, 0xe2, 0xee, 0x5a, 0xfb, 0x63, 0x41, 0x25, 0xf9, 0x80, 0x7d, 0xda, 0xcb, 0x7f, + 0x26, 0xcb, 0x30, 0x3d, 0x83, 0x2b, 0xd9, 0x85, 0xce, 0x3e, 0x00, 0x2c, 0xde, 0xdb, 0x63, 0x54, + 0x6e, 0x9d, 0x3a, 0xb5, 0x8e, 0xba, 0x3a, 0x07, 0xa5, 0xdd, 0xed, 0x13, 0x2f, 0x75, 0xce, 0x66, + 0x39, 0x10, 0x54, 0x36, 0xbf, 0x12, 0xc0, 0x48, 0x64, 0x98, 0x05, 0xdf, 0xcc, 0x71, 0xb5, 0xd1, + 0xa1, 0x58, 0xf1, 0xad, 0xfc, 0x07, 0xb9, 0xae, 0xb3, 0x54, 0xd7, 0xd3, 0x70, 0x26, 0x83, 0x27, + 0x30, 0x21, 0xff, 0xdc, 0x9b, 0x28, 0x86, 0xd3, 0x27, 0x56, 0x79, 0x82, 0x3f, 0xd3, 0xa4, 0x2d, + 0x4f, 0xf0, 0x67, 0x1b, 0xa6, 0x89, 0xcf, 0x58, 0x99, 0xfb, 0x91, 0xb0, 0x9a, 0x29, 0x01, 0xd8, + 0x1e, 0x90, 0x62, 0x58, 0x4a, 0xd8, 0xca, 0x26, 0xae, 0xff, 0x4a, 0xa7, 0x20, 0x81, 0x4b, 0xfc, + 0xba, 0x17, 0x9c, 0xca, 0xdc, 0xa8, 0xc2, 0x7b, 0x9d, 0x56, 0xb0, 0x3b, 0xf6, 0xda, 0xc5, 0xfb, + 0x7b, 0x0d, 0xcb, 0xed, 0xbd, 0x4a, 0xcd, 0xbd, 0x02, 0xe5, 0xdc, 0xe5, 0xb2, 0xe2, 0x20, 0x37, + 0xb4, 0x98, 0xf4, 0x24, 0xd9, 0x19, 0x3f, 0x85, 0x3f, 0xea, 0x03, 0x27, 0xb2, 0xf4, 0xb3, 0x70, + 0xb9, 0x8b, 0x6a, 0x28, 0xb5, 0x91, 0x2f, 0xbe, 0xb3, 0x87, 0x88, 0xdc, 0x52, 0x9f, 0x32, 0xcf, + 0xfc, 0xad, 0xb0, 0xfa, 0x00, 0xbe, 0x97, 0xc7, 0x5a, 0xf1, 0x61, 0x5f, 0xdc, 0x3d, 0xd3, 0xcc, + 0xf6, 0xad, 0xae, 0xc0, 0x7d, 0xb7, 0x4d, 0x43, 0xfe, 0x4d, 0x6f, 0xa2, 0xb8, 0x8f, 0xe4, 0x86, + 0x6a, 0x37, 0x33, 0x25, 0xdf, 0xec, 0x8b, 0xdd, 0x81, 0x74, 0x96, 0x03, 0x02, 0x63, 0x74, 0x93, + 0x03, 0xd2, 0x41, 0x82, 0x1c, 0xf0, 0x4f, 0x81, 0xff, 0x0a, 0x9b, 0x36, 0x0d, 0x81, 0x39, 0xe6, + 0x71, 0x3b, 0x4c, 0x5c, 0x8a, 0x4b, 0xdd, 0xc2, 0xe4, 0x2f, 0x90, 0xdb, 0x0c, 0x6f, 0xe0, 0xbf, + 0x85, 0xc4, 0xff, 0xff, 0xc4, 0xc7, 0x2b, 0xf0, 0x5a, 0xfe, 0x8b, 0x4e, 0x9d, 0xf1, 0x14, 0xaf, + 0x77, 0x0f, 0x94, 0x5f, 0xeb, 0x88, 0x73, 0x48, 0x4f, 0x82, 0x11, 0xd3, 0xd3, 0xca, 0xbb, 0x9f, + 0xbd, 0x98, 0x12, 0x3e, 0x7f, 0x31, 0x25, 0xfc, 0xf5, 0xc5, 0x94, 0xf0, 0xec, 0xe5, 0x54, 0xcf, + 0xe7, 0x2f, 0xa7, 0x7a, 0xfe, 0xf8, 0x72, 0xaa, 0x67, 0xf5, 0x52, 0xdd, 0x20, 0xeb, 0x5b, 0x6b, + 0x65, 0xcd, 0x6e, 0xf0, 0x7f, 0x68, 0x8b, 0x70, 0x39, 0x17, 0x70, 0x69, 0x9e, 0x97, 0x1e, 0x27, + 0xca, 0xf4, 0x96, 0x83, 0xf0, 0xda, 0x20, 0xfd, 0x21, 0xfc, 0x8d, 0xff, 0x05, 0x00, 0x00, 0xff, + 0xff, 0x06, 0x2d, 0xfc, 0x01, 0x70, 0x28, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -5257,7 +5258,7 @@ func (m *QueryConsumerChainsRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Phase |= uint32(b&0x7F) << shift + m.Phase |= ConsumerPhase(b&0x7F) << shift if b < 0x80 { break } @@ -5276,7 +5277,7 @@ func (m *QueryConsumerChainsRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Limit |= uint32(b&0x7F) << shift + m.Limit |= int32(b&0x7F) << shift if b < 0x80 { break } @@ -5905,7 +5906,7 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Phase |= uint32(b&0x7F) << shift + m.Phase |= ConsumerPhase(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/ccv/provider/types/tx.pb.go b/x/ccv/provider/types/tx.pb.go index 08e7c4c278..447ce8d15c 100644 --- a/x/ccv/provider/types/tx.pb.go +++ b/x/ccv/provider/types/tx.pb.go @@ -775,7 +775,7 @@ type MsgRemoveConsumer struct { // stop their consumer chain validator node StopTime time.Time `protobuf:"bytes,2,opt,name=stop_time,json=stopTime,proto3,stdtime" json:"stop_time"` // signer address - Authority string `protobuf:"bytes,3,opt,name=authority,proto3" json:"authority,omitempty"` + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgRemoveConsumer) Reset() { *m = MsgRemoveConsumer{} } @@ -825,9 +825,9 @@ func (m *MsgRemoveConsumer) GetStopTime() time.Time { return time.Time{} } -func (m *MsgRemoveConsumer) GetAuthority() string { +func (m *MsgRemoveConsumer) GetSigner() string { if m != nil { - return m.Authority + return m.Signer } return "" } @@ -1692,136 +1692,138 @@ func init() { } var fileDescriptor_43221a4391e9fbf4 = []byte{ - // 2061 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x59, 0x4d, 0x6c, 0x1c, 0x49, - 0xf5, 0x77, 0xcf, 0x8c, 0x9d, 0x99, 0x1a, 0x7f, 0xb6, 0x9d, 0x75, 0x7b, 0x92, 0x78, 0x1c, 0xff, - 0xf7, 0xbf, 0x6b, 0x85, 0x75, 0xcf, 0xc6, 0x90, 0x2c, 0x84, 0xf0, 0xe1, 0x8f, 0x40, 0xbc, 0xe0, - 0xd8, 0xdb, 0x0e, 0x59, 0x09, 0x24, 0x5a, 0x35, 0xdd, 0x95, 0x9e, 0x52, 0xa6, 0xbb, 0x5a, 0x5d, - 0x35, 0xe3, 0x35, 0x27, 0xb4, 0xa7, 0x1c, 0x83, 0xb8, 0x70, 0x63, 0x0f, 0x70, 0x40, 0x02, 0xb4, - 0x87, 0x3d, 0x71, 0x41, 0xe2, 0xb4, 0x12, 0x97, 0x65, 0x4f, 0x68, 0x0f, 0x01, 0x25, 0x87, 0xe5, - 0xc2, 0x85, 0x1b, 0x12, 0x07, 0x54, 0x1f, 0xdd, 0xd3, 0x3d, 0x33, 0x76, 0xda, 0x63, 0x58, 0x90, - 0xb8, 0x58, 0xee, 0x7a, 0xbf, 0xf7, 0x7b, 0x1f, 0xf5, 0xea, 0xbd, 0xae, 0x1e, 0xf0, 0x1a, 0x0e, - 0x18, 0x8a, 0x9c, 0x16, 0xc4, 0x81, 0x4d, 0x91, 0xd3, 0x89, 0x30, 0x3b, 0x6e, 0x38, 0x4e, 0xb7, - 0x11, 0x46, 0xa4, 0x8b, 0x5d, 0x14, 0x35, 0xba, 0xd7, 0x1b, 0xec, 0x1d, 0x33, 0x8c, 0x08, 0x23, - 0xfa, 0xff, 0x0d, 0x41, 0x9b, 0x8e, 0xd3, 0x35, 0x63, 0xb4, 0xd9, 0xbd, 0x5e, 0x9b, 0x83, 0x3e, - 0x0e, 0x48, 0x43, 0xfc, 0x95, 0x7a, 0xb5, 0xcb, 0x1e, 0x21, 0x5e, 0x1b, 0x35, 0x60, 0x88, 0x1b, - 0x30, 0x08, 0x08, 0x83, 0x0c, 0x93, 0x80, 0x2a, 0x69, 0x5d, 0x49, 0xc5, 0x53, 0xb3, 0xf3, 0xb0, - 0xc1, 0xb0, 0x8f, 0x28, 0x83, 0x7e, 0xa8, 0x00, 0xcb, 0xfd, 0x00, 0xb7, 0x13, 0x09, 0x06, 0x25, - 0x5f, 0xea, 0x97, 0xc3, 0xe0, 0x58, 0x89, 0x16, 0x3c, 0xe2, 0x11, 0xf1, 0x6f, 0x83, 0xff, 0x17, - 0x2b, 0x38, 0x84, 0xfa, 0x84, 0xda, 0x52, 0x20, 0x1f, 0x94, 0x68, 0x51, 0x3e, 0x35, 0x7c, 0xea, - 0xf1, 0xd0, 0x7d, 0xea, 0xc5, 0x5e, 0xe2, 0xa6, 0xd3, 0x70, 0x48, 0x84, 0x1a, 0x4e, 0x1b, 0xa3, - 0x80, 0x71, 0xa9, 0xfc, 0x4f, 0x01, 0x36, 0xf2, 0xa4, 0x32, 0x49, 0x94, 0xd4, 0x69, 0x70, 0xd2, - 0x36, 0xf6, 0x5a, 0x4c, 0x52, 0xd1, 0x06, 0x43, 0x81, 0x8b, 0x22, 0x1f, 0x4b, 0x03, 0xbd, 0xa7, - 0xd8, 0x8b, 0x94, 0x9c, 0x1d, 0x87, 0x88, 0x36, 0x10, 0xe7, 0x0b, 0x1c, 0x24, 0x01, 0xab, 0x7f, - 0xd7, 0xc0, 0xc2, 0x1e, 0xf5, 0x36, 0x29, 0xc5, 0x5e, 0xb0, 0x4d, 0x02, 0xda, 0xf1, 0x51, 0xf4, - 0x2d, 0x74, 0xac, 0x5f, 0x01, 0x65, 0xe9, 0x1b, 0x76, 0x0d, 0x6d, 0x45, 0x5b, 0xab, 0x6c, 0x15, - 0x0c, 0xcd, 0xba, 0x20, 0xd6, 0x76, 0x5d, 0xfd, 0x0d, 0x30, 0x15, 0xfb, 0x66, 0x43, 0xd7, 0x8d, - 0x8c, 0x82, 0xc0, 0xe8, 0x7f, 0x7b, 0x5a, 0x9f, 0x3e, 0x86, 0x7e, 0xfb, 0xd6, 0x2a, 0x5f, 0x45, - 0x94, 0xae, 0x5a, 0x93, 0x31, 0x70, 0xd3, 0x75, 0x23, 0xfd, 0x2a, 0x98, 0x74, 0x94, 0x19, 0xfb, - 0x11, 0x3a, 0x36, 0x8a, 0x5c, 0xcf, 0xaa, 0x3a, 0x29, 0xd3, 0xaf, 0x83, 0x09, 0xee, 0x0d, 0x8a, - 0x8c, 0x92, 0x20, 0x35, 0x3e, 0xfe, 0x60, 0x7d, 0x41, 0x65, 0x7d, 0x53, 0xb2, 0x1e, 0xb2, 0x08, - 0x07, 0x9e, 0xa5, 0x70, 0x7a, 0x1d, 0x24, 0x04, 0xdc, 0xdf, 0x71, 0xc1, 0x09, 0xe2, 0xa5, 0x5d, - 0xf7, 0xd6, 0xfc, 0xe3, 0xf7, 0xea, 0x63, 0x7f, 0x79, 0xaf, 0x3e, 0xf6, 0xee, 0xa7, 0xef, 0x5f, - 0x53, 0x5a, 0xab, 0xcb, 0xe0, 0xf2, 0xb0, 0xd0, 0x2d, 0x44, 0x43, 0x12, 0x50, 0xb4, 0xfa, 0x4c, - 0x03, 0x57, 0xf6, 0xa8, 0x77, 0xd8, 0x69, 0xfa, 0x98, 0xc5, 0x80, 0x3d, 0x4c, 0x9b, 0xa8, 0x05, - 0xbb, 0x98, 0x74, 0x22, 0xfd, 0x26, 0xa8, 0x50, 0x21, 0x65, 0x28, 0x52, 0x59, 0x3a, 0xd9, 0xd9, - 0x1e, 0x54, 0x3f, 0x00, 0x93, 0x7e, 0x8a, 0x47, 0x24, 0xaf, 0xba, 0xf1, 0x9a, 0x89, 0x9b, 0x8e, - 0x99, 0xde, 0x5e, 0x33, 0xb5, 0xa1, 0xdd, 0xeb, 0x66, 0xda, 0xb6, 0x95, 0x61, 0xe8, 0xcf, 0x40, - 0x71, 0x20, 0x03, 0x2f, 0xa5, 0x33, 0xd0, 0x73, 0x65, 0xf5, 0x55, 0xf0, 0xff, 0xa7, 0xc6, 0x98, - 0x64, 0xe3, 0x0f, 0x85, 0x21, 0xd9, 0xd8, 0x21, 0x9d, 0x66, 0x1b, 0x3d, 0x20, 0x0c, 0x07, 0xde, - 0xc8, 0xd9, 0xb0, 0xc1, 0xa2, 0xdb, 0x09, 0xdb, 0xd8, 0x81, 0x0c, 0xd9, 0x5d, 0xc2, 0x90, 0x1d, - 0x17, 0xa9, 0x4a, 0xcc, 0xab, 0xe9, 0x3c, 0x88, 0x32, 0x36, 0x77, 0x62, 0x85, 0x07, 0x84, 0xa1, - 0x3b, 0x0a, 0x6e, 0x5d, 0x74, 0x87, 0x2d, 0xeb, 0xdf, 0x07, 0x8b, 0x38, 0x78, 0x18, 0x41, 0x87, - 0x37, 0x01, 0xbb, 0xd9, 0x26, 0xce, 0x23, 0xbb, 0x85, 0xa0, 0x8b, 0x22, 0x91, 0xa8, 0xea, 0xc6, - 0x2b, 0x2f, 0xca, 0xfc, 0x5d, 0x81, 0xb6, 0x2e, 0xf6, 0x68, 0xb6, 0x38, 0x8b, 0x5c, 0xee, 0x4f, - 0x7e, 0xe9, 0x5c, 0xc9, 0x4f, 0xa7, 0x34, 0x49, 0xfe, 0xcf, 0x34, 0x30, 0xb3, 0x47, 0xbd, 0xef, - 0x84, 0x2e, 0x64, 0xe8, 0x00, 0x46, 0xd0, 0xa7, 0x3c, 0xdd, 0xb0, 0xc3, 0x5a, 0x84, 0x37, 0x8e, - 0x17, 0xa7, 0x3b, 0x81, 0xea, 0xbb, 0x60, 0x22, 0x14, 0x0c, 0x2a, 0xbb, 0x9f, 0x33, 0x73, 0xb4, - 0x69, 0x53, 0x1a, 0xdd, 0x2a, 0x7d, 0xf8, 0xb4, 0x3e, 0x66, 0x29, 0x82, 0x5b, 0xd3, 0x22, 0x9e, - 0x84, 0x7a, 0x75, 0x09, 0x2c, 0xf6, 0x79, 0x99, 0x44, 0xf0, 0x49, 0x19, 0xcc, 0xef, 0x51, 0x2f, - 0x8e, 0x72, 0xd3, 0x75, 0x31, 0x4f, 0xa3, 0xbe, 0xd4, 0xdf, 0x67, 0x7a, 0x3d, 0xe6, 0x9b, 0x60, - 0x1a, 0x07, 0x98, 0x61, 0xd8, 0xb6, 0x5b, 0x88, 0xef, 0x8d, 0x72, 0xb8, 0x26, 0x76, 0x8b, 0xf7, - 0x56, 0x53, 0x75, 0x54, 0xb1, 0x43, 0x1c, 0xa1, 0xfc, 0x9b, 0x52, 0x7a, 0x72, 0x91, 0xf7, 0x1c, - 0x0f, 0x05, 0x88, 0x62, 0x6a, 0xb7, 0x20, 0x6d, 0x89, 0x4d, 0x9f, 0xb4, 0xaa, 0x6a, 0xed, 0x2e, - 0xa4, 0x2d, 0xbe, 0x85, 0x4d, 0x1c, 0xc0, 0xe8, 0x58, 0x22, 0x4a, 0x02, 0x01, 0xe4, 0x92, 0x00, - 0x6c, 0x03, 0x40, 0x43, 0x78, 0x14, 0xd8, 0x7c, 0xda, 0x88, 0x0e, 0xc3, 0x1d, 0x91, 0x93, 0xc4, - 0x8c, 0x27, 0x89, 0x79, 0x3f, 0x1e, 0x45, 0x5b, 0x65, 0xee, 0xc8, 0x93, 0x3f, 0xd5, 0x35, 0xab, - 0x22, 0xf4, 0xb8, 0x44, 0xbf, 0x07, 0x66, 0x3b, 0x41, 0x93, 0x04, 0x2e, 0x0e, 0x3c, 0x3b, 0x44, - 0x11, 0x26, 0xae, 0x31, 0x21, 0xa8, 0x96, 0x06, 0xa8, 0x76, 0xd4, 0xd0, 0x92, 0x4c, 0x3f, 0xe1, - 0x4c, 0x33, 0x89, 0xf2, 0x81, 0xd0, 0xd5, 0xdf, 0x02, 0xba, 0xe3, 0x74, 0x85, 0x4b, 0xa4, 0xc3, - 0x62, 0xc6, 0x0b, 0xf9, 0x19, 0x67, 0x1d, 0xa7, 0x7b, 0x5f, 0x6a, 0x2b, 0xca, 0xef, 0x81, 0x45, - 0x16, 0xc1, 0x80, 0x3e, 0x44, 0x51, 0x3f, 0x6f, 0x39, 0x3f, 0xef, 0xc5, 0x98, 0x23, 0x4b, 0x7e, - 0x17, 0xac, 0x24, 0x07, 0x25, 0x42, 0x2e, 0xa6, 0x2c, 0xc2, 0xcd, 0x8e, 0x38, 0x95, 0xf1, 0xb9, - 0x32, 0x2a, 0xa2, 0x08, 0x96, 0x63, 0x9c, 0x95, 0x81, 0x7d, 0x43, 0xa1, 0xf4, 0x7d, 0xf0, 0xb2, - 0x38, 0xc7, 0x94, 0x3b, 0x67, 0x67, 0x98, 0x84, 0x69, 0x1f, 0x53, 0xca, 0xd9, 0xc0, 0x8a, 0xb6, - 0x56, 0xb4, 0xae, 0x4a, 0xec, 0x01, 0x8a, 0x76, 0x52, 0xc8, 0xfb, 0x29, 0xa0, 0xbe, 0x0e, 0xf4, - 0x16, 0xa6, 0x8c, 0x44, 0xd8, 0x81, 0x6d, 0x1b, 0x05, 0x2c, 0xc2, 0x88, 0x1a, 0x55, 0xa1, 0x3e, - 0xd7, 0x93, 0xdc, 0x91, 0x02, 0xfd, 0x4d, 0x70, 0xf5, 0x44, 0xa3, 0xb6, 0xd3, 0x82, 0x41, 0x80, - 0xda, 0xc6, 0xa4, 0x08, 0xa5, 0xee, 0x9e, 0x60, 0x73, 0x5b, 0xc2, 0xf4, 0x79, 0x30, 0xce, 0x48, - 0x68, 0xdf, 0x33, 0xa6, 0x56, 0xb4, 0xb5, 0x29, 0xab, 0xc4, 0x48, 0x78, 0x4f, 0x7f, 0x1d, 0x2c, - 0x74, 0x61, 0x1b, 0xbb, 0x90, 0x91, 0x88, 0xda, 0x21, 0x39, 0x42, 0x91, 0xed, 0xc0, 0xd0, 0x98, - 0x16, 0x18, 0xbd, 0x27, 0x3b, 0xe0, 0xa2, 0x6d, 0x18, 0xea, 0xd7, 0xc0, 0x5c, 0xb2, 0x6a, 0x53, - 0xc4, 0x04, 0x7c, 0x46, 0xc0, 0x67, 0x12, 0xc1, 0x21, 0x62, 0x1c, 0x7b, 0x19, 0x54, 0x60, 0xbb, - 0x4d, 0x8e, 0xda, 0x98, 0x32, 0x63, 0x76, 0xa5, 0xb8, 0x56, 0xb1, 0x7a, 0x0b, 0x7a, 0x0d, 0x94, - 0x5d, 0x14, 0x1c, 0x0b, 0xe1, 0x9c, 0x10, 0x26, 0xcf, 0xd9, 0xae, 0xa3, 0xe7, 0xef, 0x3a, 0x97, - 0x40, 0xc5, 0xe7, 0xfd, 0x85, 0xc1, 0x47, 0xc8, 0x98, 0x5f, 0xd1, 0xd6, 0x4a, 0x56, 0xd9, 0xc7, - 0xc1, 0x21, 0x7f, 0xd6, 0x4d, 0x30, 0x2f, 0xac, 0xdb, 0x38, 0xe0, 0xfb, 0xdb, 0x45, 0x76, 0x17, - 0xb6, 0xa9, 0xb1, 0xb0, 0xa2, 0xad, 0x95, 0xad, 0x39, 0x21, 0xda, 0x55, 0x92, 0x07, 0xb0, 0x3d, - 0xd8, 0x77, 0xae, 0x80, 0x4b, 0x43, 0x7a, 0x4b, 0xd2, 0x7b, 0x7e, 0xa3, 0x01, 0x3d, 0x25, 0xb7, - 0x90, 0x4f, 0xba, 0xb0, 0x7d, 0x5a, 0xeb, 0xd9, 0x04, 0x15, 0xca, 0xf7, 0x44, 0x1c, 0xf6, 0xc2, - 0x19, 0x0e, 0x7b, 0x99, 0xab, 0x89, 0xb3, 0x9e, 0x49, 0x54, 0x31, 0x77, 0xa2, 0x06, 0x62, 0xbb, - 0x0c, 0x6a, 0x83, 0xbe, 0x27, 0xa1, 0xfd, 0x56, 0x03, 0x73, 0x7b, 0xd4, 0x13, 0xcb, 0x28, 0x06, - 0xf5, 0x0f, 0x24, 0xad, 0x7f, 0x20, 0xfd, 0x37, 0xc5, 0x77, 0x09, 0x2c, 0x0d, 0x04, 0x90, 0x84, - 0xf7, 0x2b, 0x0d, 0x5c, 0xe4, 0xd1, 0xb7, 0x60, 0xe0, 0x21, 0x0b, 0x1d, 0xc1, 0xc8, 0xdd, 0x41, - 0x01, 0xf1, 0xa9, 0xbe, 0x0a, 0xa6, 0x5c, 0xf1, 0x9f, 0xcd, 0x08, 0x7f, 0x03, 0x35, 0x34, 0x51, - 0xa8, 0x55, 0xb9, 0x78, 0x9f, 0x6c, 0xba, 0xae, 0xbe, 0x06, 0x66, 0x7b, 0x98, 0x48, 0x58, 0x30, - 0x0a, 0x02, 0x36, 0x1d, 0xc3, 0xa4, 0xdd, 0x7f, 0x59, 0x30, 0x75, 0xf1, 0x8e, 0x34, 0xe8, 0x6e, - 0x12, 0xd0, 0x5f, 0x35, 0x50, 0xde, 0xa3, 0xde, 0x7e, 0xc8, 0x76, 0x83, 0xff, 0x85, 0x77, 0x6c, - 0x1d, 0xcc, 0xc6, 0xe1, 0x26, 0x39, 0xf8, 0xbd, 0x06, 0x2a, 0x72, 0x71, 0xbf, 0xc3, 0xfe, 0x6d, - 0x49, 0xe8, 0x45, 0x58, 0x1c, 0x2d, 0xc2, 0x52, 0xbe, 0x08, 0xe7, 0xc5, 0x01, 0x94, 0xc1, 0x24, - 0x21, 0xfe, 0xbc, 0x20, 0xee, 0x16, 0xbc, 0xdb, 0x2a, 0xf5, 0x6d, 0xe2, 0xab, 0xb6, 0x6f, 0x41, - 0x86, 0x06, 0xc3, 0xd2, 0x72, 0x86, 0x95, 0x4e, 0x57, 0x61, 0x30, 0x5d, 0x77, 0x40, 0x29, 0x82, - 0x0c, 0xa9, 0x98, 0xaf, 0xf3, 0x73, 0xfb, 0xc9, 0xd3, 0xfa, 0x25, 0x19, 0x37, 0x75, 0x1f, 0x99, - 0x98, 0x34, 0x7c, 0xc8, 0x5a, 0xe6, 0xb7, 0x91, 0x07, 0x9d, 0xe3, 0x1d, 0xe4, 0x7c, 0xfc, 0xc1, - 0x3a, 0x50, 0x69, 0xd9, 0x41, 0x8e, 0x25, 0xd4, 0x3f, 0xb3, 0xf2, 0x78, 0x05, 0xbc, 0x7c, 0x5a, - 0x9a, 0x92, 0x7c, 0xfe, 0xba, 0x28, 0xde, 0x2c, 0x93, 0x0b, 0x0a, 0x71, 0xf1, 0x43, 0xfe, 0x9e, - 0xcf, 0x27, 0xf7, 0x02, 0x18, 0x67, 0x98, 0xb5, 0x91, 0x6a, 0x73, 0xf2, 0x41, 0x5f, 0x01, 0x55, - 0x17, 0x51, 0x27, 0xc2, 0xa1, 0x78, 0xab, 0x28, 0xc8, 0x23, 0x90, 0x5a, 0xca, 0xb4, 0xff, 0x62, - 0xb6, 0xfd, 0x27, 0x13, 0xb9, 0x94, 0x63, 0x22, 0x8f, 0x9f, 0x6d, 0x22, 0x4f, 0xe4, 0x98, 0xc8, - 0x17, 0x4e, 0x9b, 0xc8, 0xe5, 0xd3, 0x26, 0x72, 0x65, 0xc4, 0x89, 0x0c, 0xf2, 0x4d, 0xe4, 0x6a, - 0xde, 0x89, 0x7c, 0x15, 0xd4, 0x4f, 0xd8, 0xaf, 0x64, 0x4f, 0x7f, 0x57, 0x14, 0x27, 0x67, 0x3b, - 0x42, 0x90, 0xf5, 0x46, 0x57, 0xaf, 0xf2, 0xb4, 0x9c, 0x95, 0xb7, 0xd4, 0x7f, 0x22, 0x7a, 0xfb, - 0xf8, 0x36, 0x28, 0xfb, 0x88, 0x41, 0x17, 0x32, 0xa8, 0x6e, 0x7a, 0x37, 0x72, 0x5d, 0x76, 0x12, - 0xbf, 0x95, 0xb2, 0xba, 0x56, 0x24, 0x64, 0xfa, 0xbb, 0x1a, 0x58, 0x52, 0x77, 0x0c, 0xfc, 0x03, - 0x11, 0x96, 0x2d, 0xae, 0x44, 0x88, 0xa1, 0x88, 0x8a, 0xaa, 0xa9, 0x6e, 0xdc, 0x39, 0x93, 0xa9, - 0xdd, 0x0c, 0xdb, 0x41, 0x42, 0x66, 0x19, 0xf8, 0x04, 0x89, 0xde, 0x01, 0x86, 0xac, 0x42, 0xda, - 0x82, 0xa1, 0xb8, 0x51, 0xf4, 0x5c, 0x90, 0x17, 0x94, 0x2f, 0xe7, 0xbb, 0xda, 0x71, 0x92, 0x43, - 0xc9, 0x91, 0x32, 0xfc, 0x52, 0x38, 0x74, 0xfd, 0x56, 0x35, 0x7d, 0x80, 0x6f, 0x8b, 0xe9, 0x9d, - 0xdd, 0xc3, 0x78, 0x87, 0x5f, 0xf8, 0x1a, 0xb2, 0xfa, 0xb8, 0x24, 0x4a, 0x40, 0x5e, 0x18, 0xcf, - 0x51, 0x02, 0x7d, 0x86, 0x0a, 0x03, 0xef, 0x3b, 0x3b, 0x60, 0x2e, 0x40, 0x47, 0x36, 0x39, 0x0a, - 0x54, 0xbf, 0x45, 0x94, 0xbe, 0x70, 0x2e, 0xcc, 0x04, 0xe8, 0x68, 0x9f, 0x6b, 0xa8, 0x65, 0xfd, - 0xad, 0x54, 0x39, 0x95, 0xce, 0x51, 0x4e, 0xb9, 0x0b, 0x69, 0xfc, 0x3f, 0x5f, 0x48, 0x13, 0x9f, - 0x51, 0x21, 0xc9, 0xd7, 0xc0, 0x6c, 0x25, 0xc4, 0x85, 0xb4, 0xf1, 0x8f, 0x69, 0x50, 0xdc, 0xa3, - 0x9e, 0xfe, 0x23, 0x0d, 0xcc, 0x0d, 0x7e, 0xaa, 0xfc, 0x52, 0x2e, 0xe7, 0x86, 0x7d, 0xea, 0xab, - 0x6d, 0x8e, 0xac, 0x9a, 0x14, 0xf9, 0x2f, 0x35, 0x50, 0x3b, 0xe5, 0x13, 0xe1, 0x56, 0x5e, 0x0b, - 0x27, 0x73, 0xd4, 0xde, 0x3c, 0x3f, 0xc7, 0x29, 0xee, 0x66, 0xbe, 0xe1, 0x8d, 0xe8, 0x6e, 0x9a, - 0x63, 0x54, 0x77, 0x87, 0x7d, 0xf8, 0xd2, 0x7f, 0xac, 0x81, 0xd9, 0x81, 0x6f, 0x46, 0x5f, 0xcc, - 0x6b, 0xa0, 0x5f, 0xb3, 0xf6, 0xf5, 0x51, 0x35, 0x93, 0xa9, 0x55, 0x7c, 0x5c, 0xd0, 0xf4, 0x27, - 0x1a, 0x98, 0xe9, 0xbf, 0x4d, 0xbe, 0x71, 0x56, 0x6a, 0xa5, 0x58, 0xfb, 0xda, 0x88, 0x8a, 0x59, - 0x97, 0x1e, 0x6b, 0x60, 0xba, 0x6f, 0x94, 0xde, 0xcc, 0x4d, 0x9c, 0xd1, 0xab, 0x7d, 0x75, 0x34, - 0xbd, 0x64, 0xcf, 0xb8, 0x2b, 0x7d, 0x2d, 0x3d, 0xb7, 0x2b, 0x59, 0xbd, 0xfc, 0xae, 0x0c, 0x6f, - 0x1c, 0xc2, 0x95, 0xbe, 0xbb, 0x71, 0x6e, 0x57, 0xb2, 0x7a, 0xf9, 0x5d, 0x19, 0x7e, 0x95, 0xe5, - 0x9d, 0x7e, 0x32, 0xf3, 0xfd, 0xf6, 0x0b, 0x67, 0x8b, 0x4d, 0x6a, 0xd5, 0x6e, 0x8f, 0xa2, 0x95, - 0x38, 0xe1, 0x83, 0x71, 0x79, 0xf5, 0x5c, 0xcf, 0x4b, 0x23, 0xe0, 0xb5, 0x1b, 0x67, 0x82, 0x27, - 0xe6, 0x42, 0x30, 0xa1, 0x6e, 0x79, 0xe6, 0x19, 0x08, 0xf6, 0x3b, 0xac, 0x76, 0xf3, 0x6c, 0xf8, - 0xc4, 0xe2, 0x2f, 0x34, 0xb0, 0x74, 0xf2, 0xad, 0x2b, 0x77, 0xbb, 0x3f, 0x91, 0xa2, 0xb6, 0x7b, - 0x6e, 0x8a, 0xc4, 0xd7, 0x9f, 0x6a, 0x60, 0x61, 0xe8, 0x8d, 0xe6, 0xf6, 0x59, 0x3b, 0x42, 0x5a, - 0xbb, 0xb6, 0x73, 0x1e, 0xed, 0x4c, 0x53, 0xa9, 0x8d, 0xff, 0xf0, 0xd3, 0xf7, 0xaf, 0x69, 0x5b, - 0x6f, 0x7f, 0xf8, 0x6c, 0x59, 0xfb, 0xe8, 0xd9, 0xb2, 0xf6, 0xe7, 0x67, 0xcb, 0xda, 0x93, 0xe7, - 0xcb, 0x63, 0x1f, 0x3d, 0x5f, 0x1e, 0xfb, 0xe3, 0xf3, 0xe5, 0xb1, 0xef, 0x7e, 0xc5, 0xc3, 0xac, - 0xd5, 0x69, 0x9a, 0x0e, 0xf1, 0xd5, 0xef, 0xa2, 0x8d, 0x9e, 0xf1, 0xf5, 0xe4, 0x67, 0xcd, 0xee, - 0x8d, 0xc6, 0x3b, 0xd9, 0xdf, 0x36, 0xc5, 0xaf, 0x38, 0xcd, 0x09, 0xf1, 0xad, 0xe9, 0xf3, 0xff, - 0x0c, 0x00, 0x00, 0xff, 0xff, 0x9e, 0x12, 0xb4, 0x8e, 0x57, 0x1e, 0x00, 0x00, + // 2086 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x59, 0x4d, 0x70, 0x1c, 0x47, + 0x15, 0xd6, 0xec, 0xae, 0x94, 0xdd, 0x5e, 0xfd, 0xb6, 0xe4, 0x68, 0xb5, 0xb6, 0xb5, 0xb2, 0x08, + 0x89, 0xca, 0x44, 0xb3, 0xb1, 0xc0, 0x0e, 0x08, 0xf3, 0xa3, 0x1f, 0x83, 0x15, 0x90, 0xa5, 0x8c, + 0x8c, 0x53, 0x05, 0x55, 0x4c, 0xf5, 0xce, 0xb4, 0x67, 0xbb, 0xbc, 0x33, 0x3d, 0x35, 0xdd, 0xbb, + 0x8a, 0x38, 0x51, 0x39, 0xf9, 0x68, 0x2a, 0x1c, 0xb8, 0x91, 0x03, 0x1c, 0xa8, 0x02, 0x2a, 0x87, + 0x14, 0x07, 0x8e, 0x9c, 0x52, 0xc5, 0x25, 0xe4, 0x44, 0xe5, 0x60, 0x28, 0xfb, 0x10, 0x2e, 0x5c, + 0xb8, 0x71, 0xa3, 0xba, 0xa7, 0x67, 0x76, 0x66, 0x77, 0x25, 0xcd, 0xae, 0x42, 0x38, 0x70, 0x51, + 0x69, 0xfa, 0xbd, 0xf7, 0xbd, 0x9f, 0x7e, 0xfd, 0x5e, 0xbf, 0x5e, 0xf0, 0x2a, 0xf1, 0x38, 0x0e, + 0xac, 0x26, 0x22, 0x9e, 0xc9, 0xb0, 0xd5, 0x0e, 0x08, 0x3f, 0xa9, 0x5b, 0x56, 0xa7, 0xee, 0x07, + 0xb4, 0x43, 0x6c, 0x1c, 0xd4, 0x3b, 0x37, 0xea, 0xfc, 0x6d, 0xdd, 0x0f, 0x28, 0xa7, 0xf0, 0x0b, + 0x03, 0xb8, 0x75, 0xcb, 0xea, 0xe8, 0x11, 0xb7, 0xde, 0xb9, 0x51, 0x9d, 0x43, 0x2e, 0xf1, 0x68, + 0x5d, 0xfe, 0x0d, 0xe5, 0xaa, 0x57, 0x1c, 0x4a, 0x9d, 0x16, 0xae, 0x23, 0x9f, 0xd4, 0x91, 0xe7, + 0x51, 0x8e, 0x38, 0xa1, 0x1e, 0x53, 0xd4, 0x9a, 0xa2, 0xca, 0xaf, 0x46, 0xfb, 0x61, 0x9d, 0x13, + 0x17, 0x33, 0x8e, 0x5c, 0x5f, 0x31, 0x2c, 0xf7, 0x32, 0xd8, 0xed, 0x40, 0x22, 0x28, 0xfa, 0x52, + 0x2f, 0x1d, 0x79, 0x27, 0x8a, 0xb4, 0xe0, 0x50, 0x87, 0xca, 0x7f, 0xeb, 0xe2, 0xbf, 0x48, 0xc0, + 0xa2, 0xcc, 0xa5, 0xcc, 0x0c, 0x09, 0xe1, 0x87, 0x22, 0x2d, 0x86, 0x5f, 0x75, 0x97, 0x39, 0xc2, + 0x75, 0x97, 0x39, 0x91, 0x95, 0xa4, 0x61, 0xd5, 0x2d, 0x1a, 0xe0, 0xba, 0xd5, 0x22, 0xd8, 0xe3, + 0x82, 0x1a, 0xfe, 0xa7, 0x18, 0x36, 0xb2, 0x84, 0x32, 0x0e, 0x54, 0x28, 0x53, 0x17, 0xa0, 0x2d, + 0xe2, 0x34, 0x79, 0x08, 0xc5, 0xea, 0x1c, 0x7b, 0x36, 0x0e, 0x5c, 0x12, 0x2a, 0xe8, 0x7e, 0x45, + 0x56, 0x24, 0xe8, 0xfc, 0xc4, 0xc7, 0xac, 0x8e, 0x05, 0x9e, 0x67, 0xe1, 0x90, 0x61, 0xf5, 0xdf, + 0x1a, 0x58, 0xd8, 0x67, 0xce, 0x16, 0x63, 0xc4, 0xf1, 0x76, 0xa8, 0xc7, 0xda, 0x2e, 0x0e, 0xbe, + 0x87, 0x4f, 0xe0, 0x55, 0x50, 0x0c, 0x6d, 0x23, 0x76, 0x45, 0x5b, 0xd1, 0xd6, 0x4a, 0xdb, 0xb9, + 0x8a, 0x66, 0xbc, 0x20, 0xd7, 0xf6, 0x6c, 0xf8, 0x3a, 0x98, 0x8a, 0x6c, 0x33, 0x91, 0x6d, 0x07, + 0x95, 0x9c, 0xe4, 0x81, 0xff, 0x7a, 0x5a, 0x9b, 0x3e, 0x41, 0x6e, 0x6b, 0x73, 0x55, 0xac, 0x62, + 0xc6, 0x56, 0x8d, 0xc9, 0x88, 0x71, 0xcb, 0xb6, 0x03, 0x78, 0x0d, 0x4c, 0x5a, 0x4a, 0x8d, 0xf9, + 0x08, 0x9f, 0x54, 0xf2, 0x42, 0xce, 0x28, 0x5b, 0x09, 0xd5, 0xaf, 0x81, 0x09, 0x61, 0x0d, 0x0e, + 0x2a, 0x05, 0x09, 0x5a, 0xf9, 0xf8, 0x83, 0xf5, 0x05, 0x15, 0xf5, 0xad, 0x10, 0xf5, 0x88, 0x07, + 0xc4, 0x73, 0x0c, 0xc5, 0x07, 0x6b, 0x20, 0x06, 0x10, 0xf6, 0x8e, 0x4b, 0x4c, 0x10, 0x2d, 0xed, + 0xd9, 0x9b, 0xf3, 0x8f, 0xdf, 0xab, 0x8d, 0xfd, 0xe3, 0xbd, 0xda, 0xd8, 0x3b, 0x9f, 0xbe, 0x7f, + 0x5d, 0x49, 0xad, 0x2e, 0x83, 0x2b, 0x83, 0x5c, 0x37, 0x30, 0xf3, 0xa9, 0xc7, 0xf0, 0xea, 0x33, + 0x0d, 0x5c, 0xdd, 0x67, 0xce, 0x51, 0xbb, 0xe1, 0x12, 0x1e, 0x31, 0xec, 0x13, 0xd6, 0xc0, 0x4d, + 0xd4, 0x21, 0xb4, 0x1d, 0xc0, 0x5b, 0xa0, 0xc4, 0x24, 0x95, 0xe3, 0x40, 0x45, 0xe9, 0x74, 0x63, + 0xbb, 0xac, 0xf0, 0x10, 0x4c, 0xba, 0x09, 0x1c, 0x19, 0xbc, 0xf2, 0xc6, 0xab, 0x3a, 0x69, 0x58, + 0x7a, 0x72, 0x7b, 0xf5, 0xc4, 0x86, 0x76, 0x6e, 0xe8, 0x49, 0xdd, 0x46, 0x0a, 0xa1, 0x37, 0x02, + 0xf9, 0xbe, 0x08, 0xbc, 0x98, 0x8c, 0x40, 0xd7, 0x94, 0xd5, 0x57, 0xc0, 0x17, 0xcf, 0xf4, 0x31, + 0x8e, 0xc6, 0x5f, 0x72, 0x03, 0xa2, 0xb1, 0x4b, 0xdb, 0x8d, 0x16, 0x7e, 0x40, 0x39, 0xf1, 0x9c, + 0x91, 0xa3, 0x61, 0x82, 0x45, 0xbb, 0xed, 0xb7, 0x88, 0x85, 0x38, 0x36, 0x3b, 0x94, 0x63, 0x33, + 0x4a, 0x52, 0x15, 0x98, 0x57, 0x92, 0x71, 0x90, 0x69, 0xac, 0xef, 0x46, 0x02, 0x0f, 0x28, 0xc7, + 0x77, 0x14, 0xbb, 0x71, 0xc9, 0x1e, 0xb4, 0x0c, 0x7f, 0x0c, 0x16, 0x89, 0xf7, 0x30, 0x40, 0x96, + 0x28, 0x02, 0x66, 0xa3, 0x45, 0xad, 0x47, 0x66, 0x13, 0x23, 0x1b, 0x07, 0x32, 0x50, 0xe5, 0x8d, + 0x97, 0xcf, 0x8b, 0xfc, 0x5d, 0xc9, 0x6d, 0x5c, 0xea, 0xc2, 0x6c, 0x0b, 0x94, 0x70, 0xb9, 0x37, + 0xf8, 0x85, 0x0b, 0x05, 0x3f, 0x19, 0xd2, 0x38, 0xf8, 0xbf, 0xd2, 0xc0, 0xcc, 0x3e, 0x73, 0x7e, + 0xe0, 0xdb, 0x88, 0xe3, 0x43, 0x14, 0x20, 0x97, 0x89, 0x70, 0xa3, 0x36, 0x6f, 0x52, 0x51, 0x38, + 0xce, 0x0f, 0x77, 0xcc, 0x0a, 0xf7, 0xc0, 0x84, 0x2f, 0x11, 0x54, 0x74, 0xbf, 0xa4, 0x67, 0x28, + 0xd3, 0x7a, 0xa8, 0x74, 0xbb, 0xf0, 0xe1, 0xd3, 0xda, 0x98, 0xa1, 0x00, 0x36, 0xa7, 0xa5, 0x3f, + 0x31, 0xf4, 0xea, 0x12, 0x58, 0xec, 0xb1, 0x32, 0xf6, 0xe0, 0x93, 0x22, 0x98, 0xdf, 0x67, 0x4e, + 0xe4, 0xe5, 0x96, 0x6d, 0x13, 0x11, 0x46, 0xb8, 0xd4, 0x5b, 0x67, 0xba, 0x35, 0xe6, 0xbb, 0x60, + 0x9a, 0x78, 0x84, 0x13, 0xd4, 0x32, 0x9b, 0x58, 0xec, 0x8d, 0x32, 0xb8, 0x2a, 0x77, 0x4b, 0xd4, + 0x56, 0x5d, 0x55, 0x54, 0xb9, 0x43, 0x82, 0x43, 0xd9, 0x37, 0xa5, 0xe4, 0xc2, 0x45, 0x51, 0x73, + 0x1c, 0xec, 0x61, 0x46, 0x98, 0xd9, 0x44, 0xac, 0x29, 0x37, 0x7d, 0xd2, 0x28, 0xab, 0xb5, 0xbb, + 0x88, 0x35, 0xc5, 0x16, 0x36, 0x88, 0x87, 0x82, 0x93, 0x90, 0xa3, 0x20, 0x39, 0x40, 0xb8, 0x24, + 0x19, 0x76, 0x00, 0x60, 0x3e, 0x3a, 0xf6, 0x4c, 0xd1, 0x6d, 0x64, 0x85, 0x11, 0x86, 0x84, 0x9d, + 0x44, 0x8f, 0x3a, 0x89, 0x7e, 0x3f, 0x6a, 0x45, 0xdb, 0x45, 0x61, 0xc8, 0x93, 0xbf, 0xd5, 0x34, + 0xa3, 0x24, 0xe5, 0x04, 0x05, 0xde, 0x03, 0xb3, 0x6d, 0xaf, 0x41, 0x3d, 0x9b, 0x78, 0x8e, 0xe9, + 0xe3, 0x80, 0x50, 0xbb, 0x32, 0x21, 0xa1, 0x96, 0xfa, 0xa0, 0x76, 0x55, 0xd3, 0x0a, 0x91, 0x7e, + 0x21, 0x90, 0x66, 0x62, 0xe1, 0x43, 0x29, 0x0b, 0xdf, 0x04, 0xd0, 0xb2, 0x3a, 0xd2, 0x24, 0xda, + 0xe6, 0x11, 0xe2, 0x0b, 0xd9, 0x11, 0x67, 0x2d, 0xab, 0x73, 0x3f, 0x94, 0x56, 0x90, 0x3f, 0x02, + 0x8b, 0x3c, 0x40, 0x1e, 0x7b, 0x88, 0x83, 0x5e, 0xdc, 0x62, 0x76, 0xdc, 0x4b, 0x11, 0x46, 0x1a, + 0xfc, 0x2e, 0x58, 0x89, 0x0f, 0x4a, 0x80, 0x6d, 0xc2, 0x78, 0x40, 0x1a, 0x6d, 0x79, 0x2a, 0xa3, + 0x73, 0x55, 0x29, 0xc9, 0x24, 0x58, 0x8e, 0xf8, 0x8c, 0x14, 0xdb, 0x77, 0x14, 0x17, 0x3c, 0x00, + 0x2f, 0xc9, 0x73, 0xcc, 0x84, 0x71, 0x66, 0x0a, 0x49, 0xaa, 0x76, 0x09, 0x63, 0x02, 0x0d, 0xac, + 0x68, 0x6b, 0x79, 0xe3, 0x5a, 0xc8, 0x7b, 0x88, 0x83, 0xdd, 0x04, 0xe7, 0xfd, 0x04, 0x23, 0x5c, + 0x07, 0xb0, 0x49, 0x18, 0xa7, 0x01, 0xb1, 0x50, 0xcb, 0xc4, 0x1e, 0x0f, 0x08, 0x66, 0x95, 0xb2, + 0x14, 0x9f, 0xeb, 0x52, 0xee, 0x84, 0x04, 0xf8, 0x06, 0xb8, 0x76, 0xaa, 0x52, 0xd3, 0x6a, 0x22, + 0xcf, 0xc3, 0xad, 0xca, 0xa4, 0x74, 0xa5, 0x66, 0x9f, 0xa2, 0x73, 0x27, 0x64, 0x83, 0xf3, 0x60, + 0x9c, 0x53, 0xdf, 0xbc, 0x57, 0x99, 0x5a, 0xd1, 0xd6, 0xa6, 0x8c, 0x02, 0xa7, 0xfe, 0x3d, 0xf8, + 0x1a, 0x58, 0xe8, 0xa0, 0x16, 0xb1, 0x11, 0xa7, 0x01, 0x33, 0x7d, 0x7a, 0x8c, 0x03, 0xd3, 0x42, + 0x7e, 0x65, 0x5a, 0xf2, 0xc0, 0x2e, 0xed, 0x50, 0x90, 0x76, 0x90, 0x0f, 0xaf, 0x83, 0xb9, 0x78, + 0xd5, 0x64, 0x98, 0x4b, 0xf6, 0x19, 0xc9, 0x3e, 0x13, 0x13, 0x8e, 0x30, 0x17, 0xbc, 0x57, 0x40, + 0x09, 0xb5, 0x5a, 0xf4, 0xb8, 0x45, 0x18, 0xaf, 0xcc, 0xae, 0xe4, 0xd7, 0x4a, 0x46, 0x77, 0x01, + 0x56, 0x41, 0xd1, 0xc6, 0xde, 0x89, 0x24, 0xce, 0x49, 0x62, 0xfc, 0x9d, 0xae, 0x3a, 0x30, 0x7b, + 0xd5, 0xb9, 0x0c, 0x4a, 0xae, 0xa8, 0x2f, 0x1c, 0x3d, 0xc2, 0x95, 0xf9, 0x15, 0x6d, 0xad, 0x60, + 0x14, 0x5d, 0xe2, 0x1d, 0x89, 0x6f, 0xa8, 0x83, 0x79, 0xa9, 0xdd, 0x24, 0x9e, 0xd8, 0xdf, 0x0e, + 0x36, 0x3b, 0xa8, 0xc5, 0x2a, 0x0b, 0x2b, 0xda, 0x5a, 0xd1, 0x98, 0x93, 0xa4, 0x3d, 0x45, 0x79, + 0x80, 0x5a, 0xfd, 0x75, 0xe7, 0x2a, 0xb8, 0x3c, 0xa0, 0xb6, 0xc4, 0xb5, 0xe7, 0x8f, 0x1a, 0x80, + 0x09, 0xba, 0x81, 0x5d, 0xda, 0x41, 0xad, 0xb3, 0x4a, 0xcf, 0x16, 0x28, 0x31, 0xb1, 0x27, 0xf2, + 0xb0, 0xe7, 0x86, 0x38, 0xec, 0x45, 0x21, 0x26, 0xcf, 0x7a, 0x2a, 0x50, 0xf9, 0xcc, 0x81, 0xea, + 0xf3, 0xed, 0x0a, 0xa8, 0xf6, 0xdb, 0x1e, 0xbb, 0xf6, 0x07, 0x0d, 0xcc, 0xed, 0x33, 0x47, 0x2e, + 0xe3, 0x88, 0xa9, 0xb7, 0x21, 0x69, 0xbd, 0x0d, 0xe9, 0xb3, 0xf0, 0xaf, 0x7b, 0x4b, 0xcb, 0x67, + 0xbb, 0xa5, 0x6d, 0x96, 0x93, 0x97, 0xaf, 0xcb, 0x60, 0xa9, 0xcf, 0xee, 0xd8, 0xab, 0xdf, 0x69, + 0xe0, 0x92, 0x70, 0xba, 0x89, 0x3c, 0x07, 0x1b, 0xf8, 0x18, 0x05, 0xf6, 0x2e, 0xf6, 0xa8, 0xcb, + 0xe0, 0x2a, 0x98, 0xb2, 0xe5, 0x7f, 0x26, 0xa7, 0xe2, 0xe2, 0x59, 0xd1, 0x64, 0x7e, 0x96, 0xc3, + 0xc5, 0xfb, 0x74, 0xcb, 0xb6, 0xe1, 0x1a, 0x98, 0xed, 0xf2, 0x04, 0x52, 0x43, 0x25, 0x27, 0xd9, + 0xa6, 0x23, 0xb6, 0x50, 0xef, 0x67, 0xb6, 0x47, 0x35, 0x79, 0x35, 0xea, 0x37, 0x37, 0x76, 0xe8, + 0x9f, 0x1a, 0x28, 0xee, 0x33, 0xe7, 0xc0, 0xe7, 0x7b, 0xde, 0xff, 0xc3, 0xd5, 0x1a, 0x82, 0xd9, + 0xc8, 0xdd, 0x38, 0x06, 0x7f, 0xd6, 0x40, 0x29, 0x5c, 0x3c, 0x68, 0xf3, 0xff, 0x5a, 0x10, 0x86, + 0x4e, 0xcb, 0xf3, 0x6f, 0x6f, 0x03, 0x3d, 0x9c, 0x97, 0xe7, 0x2e, 0x74, 0x26, 0x76, 0xf1, 0xd7, + 0x39, 0x39, 0x52, 0x88, 0x22, 0xab, 0xc4, 0x77, 0xa8, 0xab, 0xaa, 0xbd, 0x81, 0x38, 0xee, 0x77, + 0x4b, 0xcb, 0xe8, 0x56, 0x32, 0x5c, 0xb9, 0xfe, 0x70, 0xdd, 0x01, 0x85, 0x00, 0x71, 0xac, 0x7c, + 0xbe, 0x21, 0x8e, 0xeb, 0x27, 0x4f, 0x6b, 0x97, 0x43, 0xbf, 0x99, 0xfd, 0x48, 0x27, 0xb4, 0xee, + 0x22, 0xde, 0xd4, 0xbf, 0x8f, 0x1d, 0x64, 0x9d, 0xec, 0x62, 0xeb, 0xe3, 0x0f, 0xd6, 0x81, 0x0a, + 0xcb, 0x2e, 0xb6, 0x0c, 0x29, 0xfe, 0xb9, 0xa5, 0xc7, 0xcb, 0xe0, 0xa5, 0xb3, 0xc2, 0x14, 0xc7, + 0xf3, 0xf7, 0x79, 0x79, 0xa1, 0x8c, 0xe7, 0x12, 0x6a, 0x93, 0x87, 0xe2, 0x7a, 0x2f, 0x1a, 0xf6, + 0x02, 0x18, 0xe7, 0x84, 0xb7, 0xb0, 0xaa, 0x6e, 0xe1, 0x07, 0x5c, 0x01, 0x65, 0x1b, 0x33, 0x2b, + 0x20, 0xbe, 0xbc, 0x4c, 0xe4, 0xc2, 0x23, 0x90, 0x58, 0x4a, 0x55, 0xfd, 0x7c, 0xba, 0xea, 0xc7, + 0x8d, 0xb8, 0x90, 0xa1, 0x11, 0x8f, 0x0f, 0xd7, 0x88, 0x27, 0x32, 0x34, 0xe2, 0x17, 0xce, 0x6a, + 0xc4, 0xc5, 0xb3, 0x1a, 0x71, 0x69, 0xc4, 0x46, 0x0c, 0xb2, 0x35, 0xe2, 0x72, 0xd6, 0x46, 0x7c, + 0x0d, 0xd4, 0x4e, 0xd9, 0xaf, 0x78, 0x4f, 0xff, 0x94, 0x97, 0x27, 0x67, 0x27, 0xc0, 0x88, 0x77, + 0x3b, 0x56, 0x37, 0xf3, 0xb4, 0x8c, 0x99, 0xb7, 0xd4, 0x7b, 0x22, 0xba, 0xfb, 0xf8, 0x16, 0x28, + 0xba, 0x98, 0x23, 0x1b, 0x71, 0xa4, 0x06, 0xbc, 0x9b, 0x99, 0x66, 0x9c, 0xd8, 0x6e, 0x25, 0xac, + 0xa6, 0x89, 0x18, 0x0c, 0xbe, 0xa3, 0x81, 0x25, 0x35, 0x5a, 0x90, 0x9f, 0x48, 0xb7, 0x4c, 0x39, + 0x09, 0x61, 0x8e, 0x03, 0x26, 0xb3, 0xa6, 0xbc, 0x71, 0x67, 0x28, 0x55, 0x7b, 0x29, 0xb4, 0xc3, + 0x18, 0xcc, 0xa8, 0x90, 0x53, 0x28, 0xb0, 0x0d, 0x2a, 0x61, 0x16, 0xb2, 0x26, 0xf2, 0xe5, 0x20, + 0xd1, 0x35, 0x21, 0x9c, 0x4b, 0xbe, 0x9e, 0x6d, 0xa2, 0x13, 0x20, 0x47, 0x21, 0x46, 0x42, 0xf1, + 0x8b, 0xfe, 0xc0, 0xf5, 0x74, 0xf7, 0xbe, 0x2d, 0xbb, 0x77, 0x7a, 0x0f, 0xa3, 0x1d, 0x3e, 0xf7, + 0xf6, 0xb1, 0xfa, 0xb8, 0x20, 0x53, 0x20, 0x9c, 0x13, 0x2f, 0x90, 0x02, 0x3d, 0x8a, 0x72, 0x7d, + 0xd7, 0x9c, 0x5d, 0x30, 0xe7, 0xe1, 0x63, 0x93, 0x1e, 0x7b, 0xaa, 0xde, 0x62, 0xc6, 0xce, 0xed, + 0x0b, 0x33, 0x1e, 0x3e, 0x3e, 0x10, 0x12, 0x6a, 0x19, 0xbe, 0x99, 0x48, 0xa7, 0xc2, 0x05, 0xd2, + 0x29, 0x73, 0x22, 0x8d, 0xff, 0xef, 0x13, 0x69, 0xe2, 0x73, 0x4a, 0xa4, 0xf0, 0x1a, 0x98, 0xce, + 0x84, 0x28, 0x91, 0x36, 0xde, 0x9d, 0x05, 0xf9, 0x7d, 0xe6, 0xc0, 0x9f, 0x69, 0x60, 0xae, 0xff, + 0x85, 0xf2, 0x6b, 0x99, 0x8c, 0x1b, 0xf4, 0xc2, 0x57, 0xdd, 0x1a, 0x59, 0x34, 0x4e, 0xf2, 0xdf, + 0x6a, 0xa0, 0x7a, 0xc6, 0xcb, 0xe0, 0x76, 0x56, 0x0d, 0xa7, 0x63, 0x54, 0xdf, 0xb8, 0x38, 0xc6, + 0x19, 0xe6, 0xa6, 0x9e, 0xee, 0x46, 0x34, 0x37, 0x89, 0x31, 0xaa, 0xb9, 0x83, 0xde, 0xbb, 0xe0, + 0xbb, 0x1a, 0x98, 0xed, 0x7b, 0x2a, 0xfa, 0x6a, 0x56, 0x05, 0xbd, 0x92, 0xd5, 0x6f, 0x8f, 0x2a, + 0x19, 0x77, 0xad, 0xfc, 0xe3, 0x9c, 0x06, 0x9f, 0x68, 0x60, 0xa6, 0x77, 0x88, 0x7c, 0x7d, 0x58, + 0x68, 0x25, 0x58, 0xfd, 0xd6, 0x88, 0x82, 0x69, 0x93, 0x1e, 0x6b, 0x60, 0xba, 0xa7, 0x95, 0xde, + 0xca, 0x0c, 0x9c, 0x92, 0xab, 0x7e, 0x73, 0x34, 0xb9, 0x78, 0xcf, 0x84, 0x29, 0x3d, 0x25, 0x3d, + 0xb3, 0x29, 0x69, 0xb9, 0xec, 0xa6, 0x0c, 0x2e, 0x1c, 0xd2, 0x94, 0x9e, 0x91, 0x38, 0xb3, 0x29, + 0x69, 0xb9, 0xec, 0xa6, 0x0c, 0x1e, 0x65, 0x45, 0xa5, 0x9f, 0x4c, 0x3d, 0xdb, 0x7e, 0x65, 0x38, + 0xdf, 0x42, 0xa9, 0xea, 0xed, 0x51, 0xa4, 0x62, 0x23, 0x5c, 0x30, 0x1e, 0x8e, 0x9e, 0xeb, 0x59, + 0x61, 0x24, 0x7b, 0xf5, 0xe6, 0x50, 0xec, 0xb1, 0x3a, 0x1f, 0x4c, 0xa8, 0x29, 0x4f, 0x1f, 0x02, + 0xe0, 0xa0, 0xcd, 0xab, 0xb7, 0x86, 0xe3, 0x8f, 0x35, 0xfe, 0x46, 0x03, 0x4b, 0xa7, 0x4f, 0x5d, + 0x99, 0xcb, 0xfd, 0xa9, 0x10, 0xd5, 0xbd, 0x0b, 0x43, 0xc4, 0xb6, 0xfe, 0x52, 0x03, 0x0b, 0x03, + 0x27, 0x9a, 0xdb, 0xc3, 0x56, 0x84, 0xa4, 0x74, 0x75, 0xf7, 0x22, 0xd2, 0xe9, 0xa2, 0xf2, 0x73, + 0x0d, 0xc0, 0x01, 0x6f, 0x2f, 0x9b, 0x99, 0x35, 0xf4, 0xc9, 0x56, 0xb7, 0x47, 0x97, 0x8d, 0x6c, + 0xab, 0x8e, 0xff, 0xf4, 0xd3, 0xf7, 0xaf, 0x6b, 0xdb, 0x6f, 0x7d, 0xf8, 0x6c, 0x59, 0xfb, 0xe8, + 0xd9, 0xb2, 0xf6, 0xf7, 0x67, 0xcb, 0xda, 0x93, 0xe7, 0xcb, 0x63, 0x1f, 0x3d, 0x5f, 0x1e, 0xfb, + 0xeb, 0xf3, 0xe5, 0xb1, 0x1f, 0x7e, 0xc3, 0x21, 0xbc, 0xd9, 0x6e, 0xe8, 0x16, 0x75, 0xd5, 0xaf, + 0xb4, 0xf5, 0xae, 0xd6, 0xf5, 0xf8, 0x47, 0xd6, 0xce, 0xcd, 0xfa, 0xdb, 0xe9, 0x5f, 0x5a, 0xe5, + 0x6f, 0x4a, 0x8d, 0x09, 0xf9, 0xf2, 0xf5, 0xe5, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x96, 0xcd, + 0x06, 0xd7, 0xe5, 0x1e, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1849,6 +1851,7 @@ type MsgClient interface { OptOut(ctx context.Context, in *MsgOptOut, opts ...grpc.CallOption) (*MsgOptOutResponse, error) SetConsumerCommissionRate(ctx context.Context, in *MsgSetConsumerCommissionRate, opts ...grpc.CallOption) (*MsgSetConsumerCommissionRateResponse, error) ConsumerModification(ctx context.Context, in *MsgConsumerModification, opts ...grpc.CallOption) (*MsgConsumerModificationResponse, error) + ChangeRewardDenoms(ctx context.Context, in *MsgChangeRewardDenoms, opts ...grpc.CallOption) (*MsgChangeRewardDenomsResponse, error) } type msgClient struct { @@ -1979,6 +1982,15 @@ func (c *msgClient) ConsumerModification(ctx context.Context, in *MsgConsumerMod return out, nil } +func (c *msgClient) ChangeRewardDenoms(ctx context.Context, in *MsgChangeRewardDenoms, opts ...grpc.CallOption) (*MsgChangeRewardDenomsResponse, error) { + out := new(MsgChangeRewardDenomsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/ChangeRewardDenoms", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { AssignConsumerKey(context.Context, *MsgAssignConsumerKey) (*MsgAssignConsumerKeyResponse, error) @@ -1994,6 +2006,7 @@ type MsgServer interface { OptOut(context.Context, *MsgOptOut) (*MsgOptOutResponse, error) SetConsumerCommissionRate(context.Context, *MsgSetConsumerCommissionRate) (*MsgSetConsumerCommissionRateResponse, error) ConsumerModification(context.Context, *MsgConsumerModification) (*MsgConsumerModificationResponse, error) + ChangeRewardDenoms(context.Context, *MsgChangeRewardDenoms) (*MsgChangeRewardDenomsResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -2039,6 +2052,9 @@ func (*UnimplementedMsgServer) SetConsumerCommissionRate(ctx context.Context, re func (*UnimplementedMsgServer) ConsumerModification(ctx context.Context, req *MsgConsumerModification) (*MsgConsumerModificationResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ConsumerModification not implemented") } +func (*UnimplementedMsgServer) ChangeRewardDenoms(ctx context.Context, req *MsgChangeRewardDenoms) (*MsgChangeRewardDenomsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChangeRewardDenoms not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -2278,6 +2294,24 @@ func _Msg_ConsumerModification_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Msg_ChangeRewardDenoms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgChangeRewardDenoms) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ChangeRewardDenoms(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/ChangeRewardDenoms", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ChangeRewardDenoms(ctx, req.(*MsgChangeRewardDenoms)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.provider.v1.Msg", HandlerType: (*MsgServer)(nil), @@ -2334,6 +2368,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "ConsumerModification", Handler: _Msg_ConsumerModification_Handler, }, + { + MethodName: "ChangeRewardDenoms", + Handler: _Msg_ChangeRewardDenoms_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/tx.proto", @@ -2925,10 +2963,10 @@ func (m *MsgRemoveConsumer) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = 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] = 0x1a } @@ -3871,7 +3909,7 @@ func (m *MsgRemoveConsumer) Size() (n int) { } l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.StopTime) n += 1 + l + sovTx(uint64(l)) - l = len(m.Authority) + l = len(m.Signer) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -5991,7 +6029,7 @@ func (m *MsgRemoveConsumer) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6019,7 +6057,7 @@ func (m *MsgRemoveConsumer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Authority = string(dAtA[iNdEx:postIndex]) + m.Signer = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex