From ff06a9be048844411493e98c0a8e7174e1696710 Mon Sep 17 00:00:00 2001 From: insumity Date: Thu, 13 Jun 2024 11:52:56 +0200 Subject: [PATCH] first commit --- app/consumer-democracy/app.go | 1 - app/consumer/app.go | 1 - app/consumer/genesis.go | 3 + app/consumer/genesis_test.go | 9 +- docs/docs/adrs/adr-009-soft-opt-out.md | 2 +- docs/docs/adrs/intro.md | 2 +- docs/docs/features/proposals.md | 7 - .../ccv/v1/shared_consumer.proto | 7 +- tests/e2e/actions.go | 2 +- tests/e2e/state_rapid_test.go | 2 +- tests/e2e/step_delegation.go | 72 +---- tests/e2e/steps.go | 14 +- tests/e2e/steps_consumer_misbehaviour.go | 17 +- tests/e2e/steps_double_sign.go | 12 +- tests/e2e/steps_downtime.go | 161 ++++------- tests/e2e/steps_light_client_attack.go | 24 +- tests/integration/soft_opt_out.go | 251 ------------------ x/ccv/consumer/keeper/params.go | 9 - x/ccv/consumer/keeper/params_test.go | 3 +- x/ccv/consumer/keeper/soft_opt_out.go | 118 -------- x/ccv/consumer/keeper/soft_opt_out_test.go | 120 --------- x/ccv/consumer/keeper/validators.go | 12 - x/ccv/consumer/module.go | 3 - x/ccv/consumer/types/genesis_test.go | 3 - x/ccv/consumer/types/keys.go | 9 +- x/ccv/consumer/types/keys_test.go | 5 +- x/ccv/consumer/types/params_test.go | 36 +-- x/ccv/provider/keeper/proposal.go | 1 - x/ccv/provider/keeper/proposal_test.go | 2 +- x/ccv/types/params.go | 31 +-- x/ccv/types/shared_consumer.pb.go | 113 ++++---- 31 files changed, 192 insertions(+), 860 deletions(-) delete mode 100644 tests/integration/soft_opt_out.go delete mode 100644 x/ccv/consumer/keeper/soft_opt_out.go delete mode 100644 x/ccv/consumer/keeper/soft_opt_out_test.go diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index e90d35760e..a57f237a14 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -551,7 +551,6 @@ func New( // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) - // NOTE: the soft opt-out requires that the consumer module's beginblocker comes after the slashing module's beginblocker app.MM.SetOrderBeginBlockers( // upgrades should be run first upgradetypes.ModuleName, diff --git a/app/consumer/app.go b/app/consumer/app.go index 9853145117..e1d82bb600 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -481,7 +481,6 @@ func New( // NOTE: Capability module must occur first so that it can initialize any capabilities // so that other modules that want to create or claim capabilities afterwards in InitChain // can do so safely. - // NOTE: the soft opt-out requires that the consumer module's beginblocker comes after the slashing module's beginblocker app.MM.SetOrderInitGenesis( capabilitytypes.ModuleName, authtypes.ModuleName, diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index f6c8e47905..e8cd96e600 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -81,6 +81,9 @@ func transformToNew(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) oldConsumerGenesis.Params.RetryDelayPeriod = types.DefaultRetryDelayPeriod } + // `SoftOptThreshold` is deprecated in the current consumer implementation, so set to empty + oldConsumerGenesis.Params.SoftOptOutThreshold = "" + // Versions before v3.3.x of provider genesis data fills up deprecated fields // ProviderClientState, ConsensusState and InitialValSet in type GenesisState newGenesis := types.ConsumerGenesisState{ diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go index 5827651959..7fa37c7d20 100644 --- a/app/consumer/genesis_test.go +++ b/app/consumer/genesis_test.go @@ -494,7 +494,9 @@ func TestConsumerGenesisTransformationFromV2ToCurrent(t *testing.T) { require.EqualValues(t, srcGenesis.Params.ConsumerRedistributionFraction, resultGenesis.Params.ConsumerRedistributionFraction) require.EqualValues(t, srcGenesis.Params.HistoricalEntries, resultGenesis.Params.HistoricalEntries) require.EqualValues(t, srcGenesis.Params.UnbondingPeriod, resultGenesis.Params.UnbondingPeriod) - require.EqualValues(t, srcGenesis.Params.SoftOptOutThreshold, resultGenesis.Params.SoftOptOutThreshold) + + // `SoftOptOutThreshold` is deprecated, so it should not be set in the current version + require.EqualValues(t, "", resultGenesis.Params.SoftOptOutThreshold) require.EqualValues(t, srcGenesis.Params.RewardDenoms, resultGenesis.Params.RewardDenoms) require.EqualValues(t, srcGenesis.Params.ProviderRewardDenoms, resultGenesis.Params.ProviderRewardDenoms) @@ -565,7 +567,10 @@ func TestConsumerGenesisTransformationV330ToCurrent(t *testing.T) { require.Equal(t, srcGenesis.Params.ConsumerRedistributionFraction, resultGenesis.Params.ConsumerRedistributionFraction) require.Equal(t, srcGenesis.Params.HistoricalEntries, resultGenesis.Params.HistoricalEntries) require.Equal(t, srcGenesis.Params.UnbondingPeriod, resultGenesis.Params.UnbondingPeriod) - require.Equal(t, srcGenesis.Params.SoftOptOutThreshold, resultGenesis.Params.SoftOptOutThreshold) + + // `SoftOptOutThreshold` is deprecated, so it should not be set in the current version + require.Equal(t, "", resultGenesis.Params.SoftOptOutThreshold) + require.Equal(t, srcGenesis.Params.RewardDenoms, resultGenesis.Params.RewardDenoms) require.Equal(t, srcGenesis.Params.ProviderRewardDenoms, resultGenesis.Params.ProviderRewardDenoms) diff --git a/docs/docs/adrs/adr-009-soft-opt-out.md b/docs/docs/adrs/adr-009-soft-opt-out.md index b8dbc27124..3a8c1d62af 100644 --- a/docs/docs/adrs/adr-009-soft-opt-out.md +++ b/docs/docs/adrs/adr-009-soft-opt-out.md @@ -10,7 +10,7 @@ title: Soft Opt-Out ## Status -Accepted +Deprecated ## Context diff --git a/docs/docs/adrs/intro.md b/docs/docs/adrs/intro.md index fc7d06a152..7a90bca905 100644 --- a/docs/docs/adrs/intro.md +++ b/docs/docs/adrs/intro.md @@ -37,7 +37,6 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov - [ADR 004: Denom DOS fixes](./adr-004-denom-dos-fixes.md) - [ADR 005: Cryptographic verification of equivocation evidence](./adr-005-cryptographic-equivocation-verification.md) - [ADR 008: Throttle with retries](./adr-008-throttle-retries.md) -- [ADR 009: Soft Opt-Out](./adr-009-soft-opt-out.md) - [ADR 010: Standalone to Consumer Changeover](./adr-010-standalone-changeover.md) - [ADR 013: Slashing on the provider for consumer equivocation](./adr-013-equivocation-slashing.md) - [ADR 014: Epochs](./adr-014-epochs.md) @@ -57,3 +56,4 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov ### Deprecated - [ADR 003: Equivocation governance proposal](./adr-003-equivocation-gov-proposal.md) +- [ADR 009: Soft Opt-Out](./adr-009-soft-opt-out.md) diff --git a/docs/docs/features/proposals.md b/docs/docs/features/proposals.md index 1f188b8567..2343f019ae 100644 --- a/docs/docs/features/proposals.md +++ b/docs/docs/features/proposals.md @@ -77,13 +77,6 @@ Minimal example: } ``` -:::warning -Before the introduction of Partial Set Security, consumer chains typically included a "soft opt-out mechanism" -which allows the bottom N% of the provider's validators to not validate the consumer chain, without being jailed for downtime on the provider. -After the introduction of Partial Set Security, the use of the soft opt-out mechanism is discouraged, and consumer chains are -encouraged to use the topN parameter to not force validators with little stake to validate the chain. -::: - ## ChangeRewardDenomProposal Proposal type used to mutate the set of denoms accepted by the provider as rewards. diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index d1f0a5d5a3..948443cede 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -62,11 +62,8 @@ message ConsumerParams { google.protobuf.Duration unbonding_period = 9 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - // The threshold for the percentage of validators at the bottom of the set who - // can opt out of running the consumer chain without being punished. For - // example, a value of 0.05 means that the validators in the bottom 5% of the - // set can opt out - string soft_opt_out_threshold = 10; + // !!! DEPRECATED !!! soft_opt_out_threshold is deprecated. + string soft_opt_out_threshold = 10 [deprecated = true]; // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 32e8604709..4e8f9debc1 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -1992,7 +1992,7 @@ func (tr TestConfig) invokeDoublesignSlash( if err != nil { log.Fatal(err, "\n", string(bz)) } - tr.waitBlocks("provi", 10, 2*time.Minute) + tr.waitBlocks("provi", 20, 4*time.Minute) } else { // tr.useCometMock validatorPrivateKeyAddress := tr.GetValidatorPrivateKeyAddress(action.Chain, action.Validator) diff --git a/tests/e2e/state_rapid_test.go b/tests/e2e/state_rapid_test.go index 3192662d27..67a0a8ed27 100644 --- a/tests/e2e/state_rapid_test.go +++ b/tests/e2e/state_rapid_test.go @@ -70,7 +70,7 @@ func GetRegisteredConsumerRewardDenomsGen() *rapid.Generator[[]string] { }) } -func GetConsumerChainQueueSizesGen() *rapid.Generator[uint] { +func bGetConsumerChainQueueSizesGen() *rapid.Generator[uint] { return rapid.Custom(func(t *rapid.T) uint { return rapid.Uint().Draw(t, "ConsumerChainQueueSizes") }) diff --git a/tests/e2e/step_delegation.go b/tests/e2e/step_delegation.go index 102ee76fa2..7439d35bc0 100644 --- a/tests/e2e/step_delegation.go +++ b/tests/e2e/step_delegation.go @@ -220,58 +220,6 @@ func stepsCancelUnbond(consumerName string) []Step { } } -// stepsRedelegateForOptOut tests redelegation, and sets up voting powers s.t -// alice will have less than 5% of the total voting power. This is needed to -// test opt-out functionality. -func stepsRedelegateForOptOut(consumerName string) []Step { - return []Step{ - { - Action: RedelegateTokensAction{ - Chain: ChainID("provi"), - Src: ValidatorID("alice"), - Dst: ValidatorID("carol"), - TxSender: ValidatorID("alice"), - Amount: 450000000, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // Voting power changes not seen by consumer yet - ValidatorID("alice"): 510, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // Now power changes are seen by consumer - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - }, - }, - } -} - // stepsRedelegate tests redelegation and resulting validator power changes. func stepsRedelegate(consumerName string) []Step { return []Step{ @@ -283,23 +231,23 @@ func stepsRedelegate(consumerName string) []Step { TxSender: ValidatorID("carol"), // redelegate s.t. alice has majority stake so non-faulty validators maintain more than // 2/3 voting power during downtime tests below, avoiding chain halt - Amount: 449000000, + Amount: 400000000, }, State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // carol always uses a consumer assigned key - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ // Voting power changes not seen by consumer yet - ValidatorID("alice"): 60, + ValidatorID("alice"): 510, ValidatorID("bob"): 500, - ValidatorID("carol"): 950, + ValidatorID("carol"): 500, }, }, }, @@ -315,9 +263,9 @@ func stepsRedelegate(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ // Now power changes are seen by consumer - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -336,15 +284,15 @@ func stepsRedelegateShort(consumerName string) []Step { TxSender: ValidatorID("alice"), // Leave alice with majority stake so non-faulty validators maintain more than // 2/3 voting power during downtime tests below, avoiding chain halt - Amount: 1000000, + Amount: 400000000, }, State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 110, ValidatorID("bob"): 500, // carol always uses a consumer assigned key - ValidatorID("carol"): 501, + ValidatorID("carol"): 900, }, }, ChainID(consumerName): ChainState{ diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index 4a6f40333e..b78f859266 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -18,7 +18,7 @@ var compatibilitySteps = concatSteps( compstepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider stepsStartRelayer(), @@ -32,8 +32,6 @@ var happyPathSteps = concatSteps( stepsAssignConsumerKeyOnStartedChain("consu", "bob"), stepsUnbond("consu"), stepsCancelUnbond("consu"), - stepsRedelegateForOptOut("consu"), - stepsDowntimeWithOptOut("consu"), stepsRedelegate("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider @@ -46,7 +44,7 @@ var shortHappyPathSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider stepsStartRelayer(), @@ -58,12 +56,12 @@ var lightClientAttackSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDowntime("consu"), stepsLightClientAttackOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer stepsStartRelayer(), - stepsConsumerRemovalPropNotPassing("consu", 3), // submit removal prop but vote no on it - chain should stay - stepsStopChain("consu", 4), // stop chain + stepsConsumerRemovalPropNotPassing("consu", 2), // submit removal prop but vote no on it - chain should stay + stepsStopChain("consu", 3), // stop chain ) var slashThrottleSteps = concatSteps( @@ -137,6 +135,6 @@ var consumerDoubleDowntimeSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDoubleDowntime("consu"), ) diff --git a/tests/e2e/steps_consumer_misbehaviour.go b/tests/e2e/steps_consumer_misbehaviour.go index bd6e3f1d3c..fca1a063c9 100644 --- a/tests/e2e/steps_consumer_misbehaviour.go +++ b/tests/e2e/steps_consumer_misbehaviour.go @@ -36,7 +36,7 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { ConsumerChain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - TopN: 100, + TopN: 0, }, State: State{ ChainID("provi"): ChainState{ @@ -79,6 +79,13 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { }, }, }, + { + Action: OptInAction{ + Chain: ChainID(consumerName), + Validator: ValidatorID("alice"), + }, + State: State{}, + }, { Action: VoteGovProposalAction{ Chain: ChainID("provi"), @@ -173,7 +180,7 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 500, - ValidatorID("bob"): 20, + ValidatorID("bob"): 0, }, }, }, @@ -189,7 +196,7 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 20, + ValidatorID("bob"): 0, }, }, }, @@ -239,7 +246,7 @@ func stepsCauseConsumerMisbehaviour(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 20, + ValidatorID("bob"): 0, }, }, }, @@ -279,7 +286,7 @@ func stepsCauseConsumerMisbehaviour(consumerName string) []Step { // since its light client is frozen on the provider ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 20, + ValidatorID("bob"): 0, }, }, }, diff --git a/tests/e2e/steps_double_sign.go b/tests/e2e/steps_double_sign.go index 353de13761..bdc4a68cb4 100644 --- a/tests/e2e/steps_double_sign.go +++ b/tests/e2e/steps_double_sign.go @@ -13,16 +13,16 @@ func stepsDoubleSignOnProvider(consumerName string) []Step { // slash on provider ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, // from 500 to 0 + ValidatorID("carol"): 0, // from 99 to 0 }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, // not tombstoned on consumerName yet + ValidatorID("carol"): 99, // not tombstoned on consumerName yet }, }, }, @@ -38,14 +38,14 @@ func stepsDoubleSignOnProvider(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, // tombstoning visible on consumerName }, diff --git a/tests/e2e/steps_downtime.go b/tests/e2e/steps_downtime.go index a8506bf518..70fd81c130 100644 --- a/tests/e2e/steps_downtime.go +++ b/tests/e2e/steps_downtime.go @@ -23,16 +23,16 @@ func stepsDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -47,18 +47,18 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -75,10 +75,10 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -91,18 +91,18 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -117,11 +117,11 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -136,7 +136,7 @@ func stepsDowntime(consumerName string) []Step { ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ // Non faulty validators still maintain just above 2/3 power here - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // Carol's stake should be slashed and jailed // downtime slash was initiated from provider @@ -145,9 +145,9 @@ func stepsDowntime(consumerName string) []Step { }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -162,7 +162,7 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -177,14 +177,14 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, + ValidatorID("carol"): 99, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -201,9 +201,9 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, + ValidatorID("carol"): 99, }, }, }, @@ -211,7 +211,7 @@ func stepsDowntime(consumerName string) []Step { } } -// stepsDowstepsDoubleDowntime time tests that a validator can get jailed twice +// stepsDoubleDowntime time tests that a validator can get jailed twice // on a consumer. // These are the steps: // - a validator is down on a consumer @@ -233,16 +233,16 @@ func stepsDoubleDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -257,18 +257,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -285,10 +285,10 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -301,18 +301,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -327,11 +327,11 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -346,16 +346,16 @@ func stepsDoubleDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -370,18 +370,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -398,67 +398,10 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 501, - }, - }, - }, - }, - } -} - -// stepsDowntimeWithOptOut returns steps validating that alice can incur downtime -// and not be slashed/jailed, since her voting power is less than 5% of the total. -// -// Note: 60 / (60 + 500 + 950) ~= 0.04 -func stepsDowntimeWithOptOut(consumerName string) []Step { - return []Step{ - { - Action: DowntimeSlashAction{ - Chain: ChainID(consumerName), - Validator: ValidatorID("alice"), - }, - State: State{ - // powers not affected on either chain - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // alice is not slashed or jailed due to soft opt out - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, + ValidatorID("carol"): 100, }, }, }, diff --git a/tests/e2e/steps_light_client_attack.go b/tests/e2e/steps_light_client_attack.go index 65481157b1..afe1356c51 100644 --- a/tests/e2e/steps_light_client_attack.go +++ b/tests/e2e/steps_light_client_attack.go @@ -13,16 +13,16 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { // Slash on provider ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, // from 500 to 0 + ValidatorID("carol"): 0, // from 100 to 0 }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, // not tombstoned on consumerName yet + ValidatorID("carol"): 99, // not tombstoned on consumerName yet }, }, }, @@ -38,14 +38,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, // tombstoning visible on consumerName }, @@ -62,14 +62,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -86,14 +86,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, @@ -111,14 +111,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, diff --git a/tests/integration/soft_opt_out.go b/tests/integration/soft_opt_out.go deleted file mode 100644 index bce2e1d77c..0000000000 --- a/tests/integration/soft_opt_out.go +++ /dev/null @@ -1,251 +0,0 @@ -package integration - -import ( - "bytes" - "sort" - - sdk "github.com/cosmos/cosmos-sdk/types" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - abci "github.com/cometbft/cometbft/abci/types" - - consumerKeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" -) - -// TestSoftOptOut tests the soft opt-out feature -// - if a validator in the top 95% doesn't sign 50 blocks on the consumer, a SlashPacket is sent to the provider -// - if a validator in the bottom 5% doesn't sign 50 blocks on the consumer, a SlashPacket is NOT sent to the provider -// - if a validator in the bottom 5% doesn't sign 49 blocks on the consumer, -// then it moves to the top 95% and doesn't sign one more block, a SlashPacket is NOT sent to the provider -func (suite *CCVTestSuite) TestSoftOptOut() { - var votes []abci.VoteInfo - - testCases := []struct { - name string - downtimeFunc func(*consumerKeeper.Keeper, *slashingkeeper.Keeper, []byte, int) - targetValidator int - expJailed bool - expSlashPacket bool - }{ - { - "downtime top 95%", - func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { - for i, voteInfo := range votes { - if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false - } - } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + 1 - slashingBeginBlocker(suite, votes, blocksToDowntime) - }, - 0, - true, - true, - }, - { - "downtime bottom 5%", - func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { - for i, voteInfo := range votes { - if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false - } - } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + 1 - slashingBeginBlocker(suite, votes, blocksToDowntime) - }, - 3, - true, - false, - }, - { - "downtime bottom 5% first and then top 95%, but not enough", - func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { - for i, voteInfo := range votes { - if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false - } - } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) - slashingBeginBlocker(suite, votes, blocksToDowntime) - - // Increase the power of this validator (to bring it in the top 95%) - delAddr := suite.providerChain.SenderAccount.GetAddress() - bondAmt := sdk.NewInt(100).Mul(sdk.DefaultPowerReduction) - delegateByIdx(suite, delAddr, bondAmt, valIdx) - - suite.nextEpoch() - - // Relay 1 VSC packet from provider to consumer - relayAllCommittedPackets(suite, suite.providerChain, suite.path, ccv.ProviderPortID, suite.path.EndpointB.ChannelID, 1) - - // Update validator from store - val, found := ck.GetCCValidator(suite.consumerCtx(), valAddr) - suite.Require().True(found) - smallestNonOptOutPower := ck.GetSmallestNonOptOutPower(suite.consumerCtx()) - suite.Require().Equal(val.Power, smallestNonOptOutPower) - - // Let the validator continue not signing, but not enough to get jailed - for i, voteInfo := range votes { - if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].Validator.Power = val.Power - } - } - slashingBeginBlocker(suite, votes, 10) - }, - 2, - false, - false, - }, - { - "donwtime bottom 5% first and then top 95% until jailed", - func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { - for i, voteInfo := range votes { - if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false - } - } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) - slashingBeginBlocker(suite, votes, blocksToDowntime) - - // Increase the power of this validator (to bring it in the top 95%) - delAddr := suite.providerChain.SenderAccount.GetAddress() - bondAmt := sdk.NewInt(100).Mul(sdk.DefaultPowerReduction) - delegateByIdx(suite, delAddr, bondAmt, valIdx) - - suite.nextEpoch() - - // Relay 1 VSC packet from provider to consumer - relayAllCommittedPackets(suite, suite.providerChain, suite.path, ccv.ProviderPortID, suite.path.EndpointB.ChannelID, 1) - - // Update validator from store - val, found := ck.GetCCValidator(suite.consumerCtx(), valAddr) - suite.Require().True(found) - smallestNonOptOutPower := ck.GetSmallestNonOptOutPower(suite.consumerCtx()) - suite.Require().Equal(val.Power, smallestNonOptOutPower) - - // Let the validator continue not signing until it gets jailed. - // Due to the starting height being just updated, the signed blocked window needs to pass. - for i, voteInfo := range votes { - if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].Validator.Power = val.Power - } - } - slashingBeginBlocker(suite, votes, sk.SignedBlocksWindow(suite.consumerCtx())+1) - }, - 2, - true, - true, - }, - } - - for i, tc := range testCases { - // initial setup - suite.SetupCCVChannel(suite.path) - - consumerKeeper := suite.consumerApp.GetConsumerKeeper() - consumerSlashingKeeper := suite.consumerApp.GetTestSlashingKeeper() - - // Setup validator power s.t. the bottom 5% is non-empty - validatorPowers := []int64{1000, 500, 50, 10} - suite.setupValidatorPowers(validatorPowers) - - suite.nextEpoch() - - // Relay 1 VSC packet from provider to consumer - relayAllCommittedPackets(suite, suite.providerChain, suite.path, ccv.ProviderPortID, suite.path.EndpointB.ChannelID, 1) - - // Check that the third validator is the first in the top 95% - smallestNonOptOutPower := consumerKeeper.GetSmallestNonOptOutPower(suite.consumerCtx()) - suite.Require().Equal(validatorPowers[1], smallestNonOptOutPower, "test: "+tc.name) - - // Get the list of all CCV validators - vals := consumerKeeper.GetAllCCValidator(suite.consumerCtx()) - // Note that GetAllCCValidator is iterating over a map so the result need to be sorted - sort.Slice(vals, func(i, j int) bool { - if vals[i].Power != vals[j].Power { - return vals[i].Power > vals[j].Power - } - return bytes.Compare(vals[i].Address, vals[j].Address) > 0 - }) - - // Let everyone sign the first 100 blocks (default value for slahing.SignedBlocksWindow param). - // This populates the signingInfo of the slashing module so that - // the check for starting height passes. - votes = []abci.VoteInfo{} - for _, val := range vals { - votes = append(votes, abci.VoteInfo{ - Validator: abci.Validator{Address: val.Address, Power: val.Power}, - SignedLastBlock: true, - }) - } - slashingBeginBlocker(suite, votes, consumerSlashingKeeper.SignedBlocksWindow(suite.consumerCtx())) - - // Downtime infraction - sk := consumerSlashingKeeper.(slashingkeeper.Keeper) - tc.downtimeFunc(&consumerKeeper, &sk, vals[tc.targetValidator].Address, tc.targetValidator) - - // Check the signing info for target validator - consAddr := sdk.ConsAddress(vals[tc.targetValidator].Address) - info, _ := consumerSlashingKeeper.GetValidatorSigningInfo(suite.consumerCtx(), consAddr) - if tc.expJailed { - // expect increased jail time - suite.Require().True( - info.JailedUntil.Equal(suite.consumerCtx().BlockTime().Add(consumerSlashingKeeper.DowntimeJailDuration(suite.consumerCtx()))), - "test: "+tc.name+"; did not update validator jailed until signing info", - ) - // expect missed block counters reset - suite.Require().Zero(info.MissedBlocksCounter, "test: "+tc.name+"; did not reset validator missed block counter") - suite.Require().Zero(info.IndexOffset, "test: "+tc.name) - consumerSlashingKeeper.IterateValidatorMissedBlockBitArray(suite.consumerCtx(), consAddr, func(_ int64, missed bool) bool { - suite.Require().True(missed, "test: "+tc.name) - return false - }) - } else { - suite.Require().True( - // expect not increased jail time - info.JailedUntil.Before(suite.consumerCtx().BlockTime()), - "test: "+tc.name+"; validator jailed until signing info was updated", - ) - suite.Require().Positive(info.IndexOffset, "test: "+tc.name) - } - - pendingPackets := consumerKeeper.GetPendingPackets(suite.consumerCtx()) - if tc.expSlashPacket { - // Check that slash packet is queued - suite.Require().NotEmpty(pendingPackets, "test: "+tc.name+"; pending packets empty") - suite.Require().Len(pendingPackets, 1, "test: "+tc.name+"; pending packets len should be 1 is %d", len(pendingPackets)) - cp := pendingPackets[0] - suite.Require().Equal(ccv.SlashPacket, cp.Type, "test: "+tc.name) - sp := cp.GetSlashPacketData() - suite.Require().Equal(stakingtypes.Infraction_INFRACTION_DOWNTIME, sp.Infraction, "test: "+tc.name) - suite.Require().Equal(vals[tc.targetValidator].Address, sp.Validator.Address, "test: "+tc.name) - } else { - suite.Require().Empty(pendingPackets, "test: "+tc.name+"; pending packets non-empty") - } - - if i+1 < len(testCases) { - // reset suite - suite.SetupTest() - } - } -} - -// slashingBeginBlocker is a mock for the slashing BeginBlocker. -// It applies the votes for a sequence of blocks -func slashingBeginBlocker(s *CCVTestSuite, votes []abci.VoteInfo, blocks int64) { - consumerSlashingKeeper := s.consumerApp.GetTestSlashingKeeper() - currentHeight := s.consumerCtx().BlockHeight() - for s.consumerCtx().BlockHeight() < currentHeight+blocks { - for _, voteInfo := range votes { - consumerSlashingKeeper.HandleValidatorSignature( - s.consumerCtx(), - voteInfo.Validator.Address, - voteInfo.Validator.Power, - voteInfo.SignedLastBlock, - ) - } - s.consumerChain.NextBlock() - } -} diff --git a/x/ccv/consumer/keeper/params.go b/x/ccv/consumer/keeper/params.go index 4d96ddf604..8d74205b8a 100644 --- a/x/ccv/consumer/keeper/params.go +++ b/x/ccv/consumer/keeper/params.go @@ -22,7 +22,6 @@ func (k Keeper) GetConsumerParams(ctx sdk.Context) ccvtypes.ConsumerParams { k.GetConsumerRedistributionFrac(ctx), k.GetHistoricalEntries(ctx), k.GetUnbondingPeriod(ctx), - k.GetSoftOptOutThreshold(ctx), k.GetRewardDenoms(ctx), k.GetProviderRewardDenoms(ctx), k.GetRetryDelayPeriod(ctx), @@ -120,14 +119,6 @@ func (k Keeper) GetUnbondingPeriod(ctx sdk.Context) time.Duration { return period } -// GetSoftOptOutThreshold returns the percentage of validators at the bottom of the set -// that can opt out of running the consumer chain -func (k Keeper) GetSoftOptOutThreshold(ctx sdk.Context) string { - var str string - k.paramStore.Get(ctx, ccvtypes.KeySoftOptOutThreshold, &str) - return str -} - func (k Keeper) GetRewardDenoms(ctx sdk.Context) []string { var denoms []string k.paramStore.Get(ctx, ccvtypes.KeyRewardDenoms, &denoms) diff --git a/x/ccv/consumer/keeper/params_test.go b/x/ccv/consumer/keeper/params_test.go index e2975a0b31..536ae98236 100644 --- a/x/ccv/consumer/keeper/params_test.go +++ b/x/ccv/consumer/keeper/params_test.go @@ -28,7 +28,6 @@ func TestParams(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, - ccv.DefaultSoftOptOutThreshold, rewardDenoms, provideRewardDenoms, ccv.DefaultRetryDelayPeriod, @@ -39,7 +38,7 @@ func TestParams(t *testing.T) { newParams := ccv.NewParams(false, 1000, "channel-2", "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", - 7*24*time.Hour, 25*time.Hour, "0.5", 500, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour) + 7*24*time.Hour, 25*time.Hour, "0.5", 500, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour) consumerKeeper.SetParams(ctx, newParams) params = consumerKeeper.GetConsumerParams(ctx) require.Equal(t, newParams, params) diff --git a/x/ccv/consumer/keeper/soft_opt_out.go b/x/ccv/consumer/keeper/soft_opt_out.go deleted file mode 100644 index 9221cca851..0000000000 --- a/x/ccv/consumer/keeper/soft_opt_out.go +++ /dev/null @@ -1,118 +0,0 @@ -package keeper - -import ( - "encoding/binary" - "sort" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" -) - -// BeginBlockSoftOptOut executes BeginBlock logic for the Soft Opt-Out sub-protocol -func (k Keeper) BeginBlockSoftOptOut(ctx sdk.Context) { - // Update smallest validator power that cannot opt out. - k.UpdateSmallestNonOptOutPower(ctx) - - // Update the SigningInfo structs of the Slashing module - k.UpdateSlashingSigningInfo(ctx) -} - -// SetSmallestNonOptOutPower sets the smallest validator power that cannot soft opt out. -func (k Keeper) SetSmallestNonOptOutPower(ctx sdk.Context, power uint64) { - store := ctx.KVStore(k.storeKey) - store.Set(types.SmallestNonOptOutPowerKey(), sdk.Uint64ToBigEndian(power)) -} - -// UpdateSmallestNonOptOutPower updates the smallest validator power that cannot soft opt out. -// This is the smallest validator power such that the sum of the power of all validators with a lower power -// is less than [SoftOptOutThreshold] of the total power of all validators. -func (k Keeper) UpdateSmallestNonOptOutPower(ctx sdk.Context) { - // get soft opt-out threshold - optOutThreshold := sdk.MustNewDecFromStr(k.GetSoftOptOutThreshold(ctx)) - if optOutThreshold.IsZero() { - // If the SoftOptOutThreshold is zero, then soft opt-out is disable. - // Setting the smallest non-opt-out power to zero, fixes the diff-testing - // when soft opt-out is disable. - k.SetSmallestNonOptOutPower(ctx, uint64(0)) - return - } - - // get all validators - valset := k.GetAllCCValidator(ctx) - - // Valset should only be empty for hacky tests. Log error in case this ever happens in prod. - if len(valset) == 0 { - k.Logger(ctx).Error("UpdateSoftOptOutThresholdPower called with empty validator set") - return - } - - // sort validators by power ascending - sort.SliceStable(valset, func(i, j int) bool { - return valset[i].Power < valset[j].Power - }) - - // get total power in set - totalPower := sdk.ZeroDec() - for _, val := range valset { - totalPower = totalPower.Add(sdk.NewDec(val.Power)) - } - - // get power of the smallest validator that cannot soft opt out - powerSum := sdk.ZeroDec() - for _, val := range valset { - powerSum = powerSum.Add(sdk.NewDecFromInt(sdk.NewInt(val.Power))) - // if powerSum / totalPower > SoftOptOutThreshold - if powerSum.Quo(totalPower).GT(optOutThreshold) { - // set smallest non opt out power - k.SetSmallestNonOptOutPower(ctx, uint64(val.Power)) - k.Logger(ctx).Info("smallest non opt out power updated", "power", val.Power) - return - } - } - panic("UpdateSoftOptOutThresholdPower should not reach this point. Incorrect logic!") -} - -// GetSmallestNonOptOutPower returns the smallest validator power that cannot soft opt out. -func (k Keeper) GetSmallestNonOptOutPower(ctx sdk.Context) int64 { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.SmallestNonOptOutPowerKey()) - if bz == nil { - return 0 - } - return int64(binary.BigEndian.Uint64(bz)) -} - -func (k Keeper) UpdateSlashingSigningInfo(ctx sdk.Context) { - smallestNonOptOutPower := k.GetSmallestNonOptOutPower(ctx) - - // Update SigningInfo for opted out validators - valset := k.GetAllCCValidator(ctx) - // Note that we don't need to sort the valset as GetAllCCValidator - // uses KVStorePrefixIterator that iterates over all the keys with - // a certain prefix in ascending order - for _, val := range valset { - consAddr := sdk.ConsAddress(val.Address) - signingInfo, found := k.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) - if !found { - continue - } - if val.Power < smallestNonOptOutPower { - // validator CAN opt-out from validating on consumer chains - if !val.OptedOut { - // previously the validator couldn't opt-out - val.OptedOut = true - } - } else { - // validator CANNOT opt-out from validating on consumer chains - if val.OptedOut { - // previously the validator could opt-out - signingInfo.StartHeight = ctx.BlockHeight() - val.OptedOut = false - } - } - - k.slashingKeeper.SetValidatorSigningInfo(ctx, consAddr, signingInfo) - k.SetCCValidator(ctx, val) - } -} diff --git a/x/ccv/consumer/keeper/soft_opt_out_test.go b/x/ccv/consumer/keeper/soft_opt_out_test.go deleted file mode 100644 index 1a726d1767..0000000000 --- a/x/ccv/consumer/keeper/soft_opt_out_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package keeper_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - tmtypes "github.com/cometbft/cometbft/types" - - "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" -) - -// Tests that UpdateSmallestNonOptOutPower updates the smallest validator power that cannot soft opt out. -// Soft opt out allows the bottom [SoftOptOutThreshold] portion of validators in the set to opt out. -// UpdateSmallestNonOptOutPower should update the smallest validator power that cannot opt out. -func TestUpdateSmallestNonOptOutPower(t *testing.T) { - cIds := crypto.GenMultipleCryptoIds(7, 682934679238) - - testCases := []struct { - name string - // soft opt out threshold set as param - optOutThresh string - // validators to set in store - validators []*tmtypes.Validator - // expected smallest power of validator which cannot opt out - expSmallestNonOptOutValPower int64 - }{ - { - name: "One", - optOutThresh: "0.05", - validators: []*tmtypes.Validator{ - tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 3), - tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 49), - tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 51), - }, - // 107 total power, validator with 3 power passes 0.05 threshold (6 / 107 = 0.056) and cannot opt out - expSmallestNonOptOutValPower: 3, - }, - { - name: "One in different order", - optOutThresh: "0.05", - validators: []*tmtypes.Validator{ - tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 3), - tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 51), - tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 49), - tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 1), - }, - // Same result as first test case, just confirms order of validators doesn't matter - expSmallestNonOptOutValPower: 3, - }, - { - name: "Two", - optOutThresh: "0.05", - validators: []*tmtypes.Validator{ - tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 3), - tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 500), - }, - // 506 total power, validator with 500 passes 0.05 threshold and cannot opt out - expSmallestNonOptOutValPower: 500, - }, - { - name: "Three", - optOutThresh: "0.199999", - validators: []*tmtypes.Validator{ - tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 54), - tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 53), - tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 52), - tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 51), - tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 50), - tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[6].TMCryptoPubKey(), 1), - }, - // 262 total power, (50 + 1 + 1) / 262 ~= 0.19, validator with 51 passes 0.199999 threshold and cannot opt out - expSmallestNonOptOutValPower: 51, - }, - { - name: "soft opt-out disabled", - optOutThresh: "0", - validators: []*tmtypes.Validator{ - tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 54), - tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 53), - tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 52), - tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 51), - tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 50), - tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 1), - tmtypes.NewValidator(cIds[6].TMCryptoPubKey(), 1), - }, - expSmallestNonOptOutValPower: 0, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - moduleParams := ccvtypes.DefaultParams() - moduleParams.SoftOptOutThreshold = tc.optOutThresh - consumerKeeper.SetParams(ctx, moduleParams) - defer ctrl.Finish() - - // set validators in store - SetCCValidators(t, consumerKeeper, ctx, tc.validators) - - // update smallest power of validator which cannot opt out - consumerKeeper.UpdateSmallestNonOptOutPower(ctx) - - // expect smallest power of validator which cannot opt out to be updated - require.Equal(t, tc.expSmallestNonOptOutValPower, consumerKeeper.GetSmallestNonOptOutPower(ctx)) - }) - } -} diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index 24a1c5a57c..b0e3e12846 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -136,18 +136,6 @@ func (k Keeper) SlashWithInfractionReason(ctx sdk.Context, addr sdk.ConsAddress, // Otherwise infraction happened after the changeover was completed. - // if this is a downtime infraction and the validator is allowed to - // soft opt out, do not queue a slash packet - if infraction == stakingtypes.Infraction_INFRACTION_DOWNTIME { - if power < k.GetSmallestNonOptOutPower(ctx) { - // soft opt out - k.Logger(ctx).Debug("soft opt out", - "validator", addr, - "power", power, - ) - return math.NewInt(0) - } - } // get VSC ID for infraction height vscID := k.GetHeightValsetUpdateID(ctx, uint64(infractionHeight)) diff --git a/x/ccv/consumer/module.go b/x/ccv/consumer/module.go index 4b5d9c053b..1896728085 100644 --- a/x/ccv/consumer/module.go +++ b/x/ccv/consumer/module.go @@ -138,9 +138,6 @@ func (AppModule) ConsensusVersion() uint64 { // Set the VSC ID for the subsequent block to the same value as the current block // Panic if the provider's channel was established and then closed func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { - // Execute BeginBlock logic for the Soft Opt-Out sub-protocol - am.keeper.BeginBlockSoftOptOut(ctx) - channelID, found := am.keeper.GetProviderChannel(ctx) if found && am.keeper.IsChannelClosed(ctx, channelID) { // The CCV channel was established, but it was then closed; diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index dcd30b642c..c8c61776ec 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -230,7 +230,6 @@ func TestValidateInitialGenesisState(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, - ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, ccv.DefaultRetryDelayPeriod, @@ -250,7 +249,6 @@ func TestValidateInitialGenesisState(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, - ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, ccv.DefaultRetryDelayPeriod, @@ -456,7 +454,6 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, - ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, ccv.DefaultRetryDelayPeriod, diff --git a/x/ccv/consumer/types/keys.go b/x/ccv/consumer/types/keys.go index 20163f5ed9..5fcd26a1ca 100644 --- a/x/ccv/consumer/types/keys.go +++ b/x/ccv/consumer/types/keys.go @@ -65,8 +65,9 @@ const ( // [DEPRECATED] LastStandaloneHeightByteKey - // SmallestNonOptOutPowerByteKey is the byte that will store the smallest val power that cannot opt out - SmallestNonOptOutPowerByteKey + // NOTE: This key is deprecated, but left in place to avoid consumer state migrations + // [DEPRECATED] + DeprecatedSmallestNonOptOutPowerByteKey // HistoricalInfoKey is the byte prefix that will store the historical info for a given height HistoricalInfoBytePrefix @@ -201,10 +202,6 @@ func InitGenesisHeightKey() []byte { return []byte{InitGenesisHeightByteKey} } -func SmallestNonOptOutPowerKey() []byte { - return []byte{SmallestNonOptOutPowerByteKey} -} - // StandaloneTransferChannelIDKey returns the key to the transfer channelID that existed from a standalone chain // changing over to a consumer func StandaloneTransferChannelIDKey() []byte { diff --git a/x/ccv/consumer/types/keys_test.go b/x/ccv/consumer/types/keys_test.go index a8cebee284..66880b2ae9 100644 --- a/x/ccv/consumer/types/keys_test.go +++ b/x/ccv/consumer/types/keys_test.go @@ -31,7 +31,7 @@ func getAllKeyPrefixes() []byte { PreCCVByteKey, InitialValSetByteKey, LastStandaloneHeightByteKey, - SmallestNonOptOutPowerByteKey, + DeprecatedSmallestNonOptOutPowerByteKey, HistoricalInfoBytePrefix, PacketMaturityTimeBytePrefix, HeightValsetUpdateIDBytePrefix, @@ -68,8 +68,7 @@ func getAllFullyDefinedKeys() [][]byte { // PendingDataPacketsKey() does not use duplicated prefix with value of 0x06 PreCCVKey(), InitialValSetKey(), - // LastStandaloneHeightKey() is depreciated - SmallestNonOptOutPowerKey(), + // LastStandaloneHeightKey() is deprecated HistoricalInfoKey(0), PacketMaturityTimeKey(0, time.Time{}), HeightValsetUpdateIDKey(0), diff --git a/x/ccv/consumer/types/params_test.go b/x/ccv/consumer/types/params_test.go index 5b11b52d43..8e81e2301c 100644 --- a/x/ccv/consumer/types/params_test.go +++ b/x/ccv/consumer/types/params_test.go @@ -19,67 +19,59 @@ func TestValidateParams(t *testing.T) { {"default params", ccvtypes.DefaultParams(), true}, { "custom valid params", - ccvtypes.NewParams(true, 5, "", "", 1004, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), true, + ccvtypes.NewParams(true, 5, "", "", 1004, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), true, }, { "custom invalid params, block per dist transmission", - ccvtypes.NewParams(true, -5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, -5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, dist transmission channel", - ccvtypes.NewParams(true, 5, "badchannel/", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "badchannel/", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, ccv timeout", - ccvtypes.NewParams(true, 5, "", "", -5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", -5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, transfer timeout", - ccvtypes.NewParams(true, 5, "", "", 1004, -7, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 1004, -7, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, consumer redist fraction is negative", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "-0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "-0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, consumer redist fraction is over 1", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "1.2", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "1.2", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, bad consumer redist fraction ", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "notFrac", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "notFrac", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, negative num historical entries", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", -100, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", -100, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, negative unbonding period", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, -24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, - }, - { - "custom invalid params, invalid soft opt out threshold", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "-0.05", []string{"u"}, []string{}, 2*time.Hour), false, - }, - { - "custom invalid params, invalid soft opt out threshold", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.5", []string{"u"}, []string{}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, -24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, invalid reward denom", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"u"}, []string{}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"u"}, []string{}, 2*time.Hour), false, }, { "custom invalid params, invalid provider reward denom", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{}, []string{"a"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{}, []string{"a"}, 2*time.Hour), false, }, { "custom invalid params, retry delay period is negative", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{}, []string{}, -2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{}, []string{}, -2*time.Hour), false, }, { "custom invalid params, retry delay period is zero", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{}, []string{}, 0), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{}, []string{}, 0), false, }, } diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index 34bb5b6971..898992ef10 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -329,7 +329,6 @@ func (k Keeper) MakeConsumerGenesis( prop.ConsumerRedistributionFraction, prop.HistoricalEntries, prop.UnbondingPeriod, - "0.05", []string{}, []string{}, ccv.DefaultRetryDelayPeriod, diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index c561960a49..c242118e41 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -876,7 +876,7 @@ func TestMakeConsumerGenesis(t *testing.T) { "consumer_redistribution_fraction": "0.75", "historical_entries": 10000, "unbonding_period": 1728000000000000, - "soft_opt_out_threshold": "0.05", + "soft_opt_out_threshold": "", "reward_denoms": [], "provider_reward_denoms": [], "retry_delay_period": 3600000000000 diff --git a/x/ccv/types/params.go b/x/ccv/types/params.go index c80e353d66..be3fe7f533 100644 --- a/x/ccv/types/params.go +++ b/x/ccv/types/params.go @@ -37,9 +37,6 @@ const ( // the staking module default. DefaultConsumerUnbondingPeriod = stakingtypes.DefaultUnbondingTime - 7*24*time.Hour - // By default, the bottom 5% of the validator set can opt out of validating consumer chains - DefaultSoftOptOutThreshold = "0.05" - // Default retry delay period is 1 hour. DefaultRetryDelayPeriod = time.Hour ) @@ -54,7 +51,6 @@ var ( KeyConsumerRedistributionFrac = []byte("ConsumerRedistributionFraction") KeyHistoricalEntries = []byte("HistoricalEntries") KeyConsumerUnbondingPeriod = []byte("UnbondingPeriod") - KeySoftOptOutThreshold = []byte("SoftOptOutThreshold") KeyRewardDenoms = []byte("RewardDenoms") KeyProviderRewardDenoms = []byte("ProviderRewardDenoms") KeyRetryDelayPeriod = []byte("RetryDelayPeriod") @@ -70,7 +66,7 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, distributionTransmissionChannel, providerFeePoolAddrStr string, ccvTimeoutPeriod, transferTimeoutPeriod time.Duration, consumerRedistributionFraction string, historicalEntries int64, - consumerUnbondingPeriod time.Duration, softOptOutThreshold string, + consumerUnbondingPeriod time.Duration, rewardDenoms, providerRewardDenoms []string, retryDelayPeriod time.Duration, ) ConsumerParams { return ConsumerParams{ @@ -83,7 +79,6 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, ConsumerRedistributionFraction: consumerRedistributionFraction, HistoricalEntries: historicalEntries, UnbondingPeriod: consumerUnbondingPeriod, - SoftOptOutThreshold: softOptOutThreshold, RewardDenoms: rewardDenoms, ProviderRewardDenoms: providerRewardDenoms, RetryDelayPeriod: retryDelayPeriod, @@ -104,7 +99,6 @@ func DefaultParams() ConsumerParams { DefaultConsumerRedistributeFrac, DefaultHistoricalEntries, DefaultConsumerUnbondingPeriod, - DefaultSoftOptOutThreshold, rewardDenoms, provideRewardDenoms, DefaultRetryDelayPeriod, @@ -140,9 +134,6 @@ func (p ConsumerParams) Validate() error { if err := ValidateDuration(p.UnbondingPeriod); err != nil { return err } - if err := ValidateSoftOptOutThreshold(p.SoftOptOutThreshold); err != nil { - return err - } if err := ValidateDenoms(p.RewardDenoms); err != nil { return err } @@ -175,8 +166,6 @@ func (p *ConsumerParams) ParamSetPairs() paramtypes.ParamSetPairs { p.HistoricalEntries, ValidatePositiveInt64), paramtypes.NewParamSetPair(KeyConsumerUnbondingPeriod, p.UnbondingPeriod, ValidateDuration), - paramtypes.NewParamSetPair(KeySoftOptOutThreshold, - p.SoftOptOutThreshold, ValidateSoftOptOutThreshold), paramtypes.NewParamSetPair(KeyRewardDenoms, p.RewardDenoms, ValidateDenoms), paramtypes.NewParamSetPair(KeyProviderRewardDenoms, @@ -195,24 +184,6 @@ func ValidateProviderFeePoolAddrStr(i interface{}) error { return nil } -func ValidateSoftOptOutThreshold(i interface{}) error { - str, ok := i.(string) - if !ok { - return fmt.Errorf("invalid parameter type: %T", i) - } - dec, err := sdktypes.NewDecFromStr(str) - if err != nil { - return err - } - if dec.IsNegative() { - return fmt.Errorf("soft opt out threshold cannot be negative, got %s", str) - } - if !dec.Sub(sdktypes.MustNewDecFromStr("0.2")).IsNegative() { - return fmt.Errorf("soft opt out threshold cannot be greater than 0.2, got %s", str) - } - return nil -} - func ValidateDenoms(i interface{}) error { v, ok := i.([]string) if !ok { diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index 95050192b8..56cfeb2785 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -65,11 +65,8 @@ type ConsumerParams struct { // Unbonding period for the consumer, // which should be smaller than that of the provider in general. UnbondingPeriod time.Duration `protobuf:"bytes,9,opt,name=unbonding_period,json=unbondingPeriod,proto3,stdduration" json:"unbonding_period"` - // The threshold for the percentage of validators at the bottom of the set who - // can opt out of running the consumer chain without being punished. For - // example, a value of 0.05 means that the validators in the bottom 5% of the - // set can opt out - SoftOptOutThreshold string `protobuf:"bytes,10,opt,name=soft_opt_out_threshold,json=softOptOutThreshold,proto3" json:"soft_opt_out_threshold,omitempty"` + // !!! DEPRECATED !!! soft_opt_out_threshold is deprecated. + SoftOptOutThreshold string `protobuf:"bytes,10,opt,name=soft_opt_out_threshold,json=softOptOutThreshold,proto3" json:"soft_opt_out_threshold,omitempty"` // Deprecated: Do not use. // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. RewardDenoms []string `protobuf:"bytes,11,rep,name=reward_denoms,json=rewardDenoms,proto3" json:"reward_denoms,omitempty"` @@ -176,6 +173,7 @@ func (m *ConsumerParams) GetUnbondingPeriod() time.Duration { return 0 } +// Deprecated: Do not use. func (m *ConsumerParams) GetSoftOptOutThreshold() string { if m != nil { return m.SoftOptOutThreshold @@ -343,58 +341,59 @@ func init() { } var fileDescriptor_d0a8be0efc64dfbc = []byte{ - // 812 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x73, 0xdc, 0x34, - 0x14, 0x8e, 0xbb, 0x25, 0xdd, 0x68, 0x93, 0xa6, 0x88, 0x50, 0x4c, 0x3a, 0xb3, 0x71, 0x03, 0x87, - 0x1d, 0x98, 0xda, 0x24, 0xcd, 0x89, 0x1b, 0x49, 0x28, 0xa5, 0x87, 0x64, 0xeb, 0x84, 0x32, 0x03, - 0x07, 0x8d, 0x2c, 0xbd, 0x5d, 0x6b, 0xb0, 0x25, 0x8f, 0x24, 0x3b, 0xe4, 0x17, 0x70, 0xe5, 0xc8, - 0x4f, 0x2a, 0xb7, 0x1e, 0x39, 0x51, 0x26, 0xf9, 0x23, 0x8c, 0x65, 0x3b, 0xf1, 0x32, 0x04, 0xd2, - 0x9b, 0x9e, 0xde, 0xf7, 0x7d, 0xf6, 0xf7, 0xa4, 0xf7, 0x84, 0xbe, 0x10, 0xd2, 0x82, 0x66, 0x29, - 0x15, 0x92, 0x18, 0x60, 0xa5, 0x16, 0xf6, 0x3c, 0x62, 0xac, 0x8a, 0xaa, 0x9d, 0xc8, 0xa4, 0x54, - 0x03, 0x27, 0x4c, 0x49, 0x53, 0xe6, 0xa0, 0xc3, 0x42, 0x2b, 0xab, 0xf0, 0xe6, 0xbf, 0x30, 0x42, - 0xc6, 0xaa, 0xb0, 0xda, 0xd9, 0x7c, 0x64, 0x41, 0x72, 0xd0, 0xb9, 0x90, 0x36, 0xa2, 0x09, 0x13, - 0x91, 0x3d, 0x2f, 0xc0, 0x34, 0xc4, 0xcd, 0x48, 0x24, 0x2c, 0xca, 0xc4, 0x3c, 0xb5, 0x2c, 0x13, - 0x20, 0xad, 0x89, 0x7a, 0xe8, 0x6a, 0xa7, 0x17, 0xb5, 0x84, 0xf1, 0x5c, 0xa9, 0x79, 0x06, 0x91, - 0x8b, 0x92, 0x72, 0x16, 0xf1, 0x52, 0x53, 0x2b, 0x94, 0x6c, 0xf3, 0x1b, 0x73, 0x35, 0x57, 0x6e, - 0x19, 0xd5, 0xab, 0x66, 0x77, 0xfb, 0xed, 0x32, 0xba, 0x7f, 0xd0, 0xfe, 0xf2, 0x94, 0x6a, 0x9a, - 0x1b, 0xec, 0xa3, 0x7b, 0x20, 0x69, 0x92, 0x01, 0xf7, 0xbd, 0xc0, 0x9b, 0x0c, 0xe3, 0x2e, 0xc4, - 0xc7, 0xe8, 0xd3, 0x24, 0x53, 0xec, 0x27, 0x43, 0x0a, 0xd0, 0x84, 0x0b, 0x63, 0xb5, 0x48, 0xca, - 0xfa, 0x1b, 0xc4, 0x6a, 0x2a, 0x4d, 0x2e, 0x8c, 0x11, 0x4a, 0xfa, 0x77, 0x02, 0x6f, 0x32, 0x88, - 0x1f, 0x37, 0xd8, 0x29, 0xe8, 0xc3, 0x1e, 0xf2, 0xb4, 0x07, 0xc4, 0x2f, 0xd0, 0xe3, 0x1b, 0x55, - 0x08, 0x4b, 0xa9, 0x94, 0x90, 0xf9, 0x83, 0xc0, 0x9b, 0xac, 0xc4, 0x5b, 0xfc, 0x06, 0x91, 0x83, - 0x06, 0x86, 0xbf, 0x44, 0x9b, 0x85, 0x56, 0x95, 0xe0, 0xa0, 0xc9, 0x0c, 0x80, 0x14, 0x4a, 0x65, - 0x84, 0x72, 0xae, 0x89, 0xb1, 0xda, 0xbf, 0xeb, 0x44, 0x1e, 0x76, 0x88, 0x67, 0x00, 0x53, 0xa5, - 0xb2, 0xaf, 0x38, 0xd7, 0x27, 0x56, 0xe3, 0x97, 0x08, 0x33, 0x56, 0x11, 0x2b, 0x72, 0x50, 0xa5, - 0xad, 0xdd, 0x09, 0xc5, 0xfd, 0xf7, 0x02, 0x6f, 0x32, 0xda, 0xfd, 0x38, 0x6c, 0x0a, 0x1b, 0x76, - 0x85, 0x0d, 0x0f, 0xdb, 0xc2, 0xee, 0x0f, 0x5f, 0xff, 0xb9, 0xb5, 0xf4, 0xdb, 0xdb, 0x2d, 0x2f, - 0x7e, 0xc0, 0x58, 0x75, 0xda, 0xb0, 0xa7, 0x8e, 0x8c, 0x7f, 0x44, 0x1f, 0x39, 0x37, 0x33, 0xd0, - 0xff, 0xd4, 0x5d, 0xbe, 0xbd, 0xee, 0x87, 0x9d, 0xc6, 0xa2, 0xf8, 0x73, 0x14, 0x74, 0xf7, 0x8c, - 0x68, 0x58, 0x28, 0xe1, 0x4c, 0x53, 0x56, 0x2f, 0xfc, 0x7b, 0xce, 0xf1, 0xb8, 0xc3, 0xc5, 0x0b, - 0xb0, 0x67, 0x2d, 0x0a, 0x3f, 0x41, 0x38, 0x15, 0xc6, 0x2a, 0x2d, 0x18, 0xcd, 0x08, 0x48, 0xab, - 0x05, 0x18, 0x7f, 0xe8, 0x0e, 0xf0, 0xfd, 0xeb, 0xcc, 0xd7, 0x4d, 0x02, 0x1f, 0xa1, 0x07, 0xa5, - 0x4c, 0x94, 0xe4, 0x42, 0xce, 0x3b, 0x3b, 0x2b, 0xb7, 0xb7, 0xb3, 0x7e, 0x45, 0x6e, 0x8d, 0x3c, - 0x45, 0x0f, 0x8d, 0x9a, 0x59, 0xa2, 0x0a, 0x4b, 0xea, 0x0a, 0xd9, 0x54, 0x83, 0x49, 0x55, 0xc6, - 0x7d, 0xe4, 0x7e, 0xff, 0x83, 0x3a, 0x7b, 0x5c, 0xd8, 0xe3, 0xd2, 0x9e, 0x76, 0x29, 0xfc, 0x09, - 0x5a, 0xd3, 0x70, 0x46, 0x35, 0x27, 0x1c, 0xa4, 0xca, 0x8d, 0x3f, 0x0a, 0x06, 0x93, 0x95, 0x78, - 0xb5, 0xd9, 0x3c, 0x74, 0x7b, 0x78, 0x0f, 0x5d, 0x1d, 0x36, 0x59, 0x44, 0xaf, 0x3a, 0xf4, 0x46, - 0x97, 0x8d, 0xfb, 0xac, 0x97, 0x08, 0x6b, 0xb0, 0xfa, 0x9c, 0x70, 0xc8, 0xe8, 0x79, 0xe7, 0x70, - 0xed, 0x1d, 0x2e, 0x82, 0xa3, 0x1f, 0xd6, 0xec, 0xc6, 0xe2, 0xf6, 0xef, 0x1e, 0xda, 0xe8, 0x3a, - 0xec, 0x1b, 0x90, 0x60, 0x84, 0x39, 0xb1, 0xd4, 0x02, 0x7e, 0x8e, 0x96, 0x0b, 0xd7, 0x71, 0xae, - 0xcd, 0x46, 0xbb, 0x9f, 0x85, 0x37, 0xcf, 0x8a, 0x70, 0xb1, 0x47, 0xf7, 0xef, 0xd6, 0x1f, 0x8c, - 0x5b, 0x3e, 0x7e, 0x81, 0x86, 0x9d, 0x1b, 0xd7, 0x7b, 0xa3, 0xdd, 0xc9, 0x7f, 0x69, 0x4d, 0x5b, - 0xec, 0xb7, 0x72, 0xa6, 0x5a, 0xa5, 0x2b, 0x3e, 0x7e, 0x84, 0x56, 0x24, 0x9c, 0x11, 0xc7, 0x74, - 0xad, 0x37, 0x8c, 0x87, 0x12, 0xce, 0x0e, 0xea, 0x78, 0xfb, 0x97, 0x3b, 0x68, 0xb5, 0xcf, 0xc6, - 0x47, 0x68, 0xb5, 0x19, 0x4f, 0xc4, 0xd4, 0x9e, 0x5a, 0x27, 0x9f, 0x87, 0x22, 0x61, 0x61, 0x7f, - 0x78, 0x85, 0xbd, 0x71, 0x55, 0xbb, 0x71, 0xbb, 0xae, 0x0c, 0xf1, 0x88, 0x5d, 0x07, 0xf8, 0x7b, - 0xb4, 0x5e, 0x5f, 0x58, 0x90, 0xa6, 0x34, 0xad, 0x64, 0x63, 0x28, 0xfc, 0x5f, 0xc9, 0x8e, 0xd6, - 0xa8, 0xde, 0x67, 0x0b, 0x31, 0x3e, 0x42, 0xeb, 0x42, 0x0a, 0x2b, 0x68, 0x46, 0x2a, 0x9a, 0x11, - 0x03, 0xd6, 0x1f, 0x04, 0x83, 0xc9, 0x68, 0x37, 0xe8, 0xeb, 0xd4, 0x53, 0x38, 0x7c, 0x45, 0x33, - 0xc1, 0xa9, 0x55, 0xfa, 0xbb, 0x82, 0x53, 0x0b, 0x6d, 0x85, 0xd6, 0x5a, 0xfa, 0x2b, 0x9a, 0x9d, - 0x80, 0xdd, 0x3f, 0x7a, 0x7d, 0x31, 0xf6, 0xde, 0x5c, 0x8c, 0xbd, 0xbf, 0x2e, 0xc6, 0xde, 0xaf, - 0x97, 0xe3, 0xa5, 0x37, 0x97, 0xe3, 0xa5, 0x3f, 0x2e, 0xc7, 0x4b, 0x3f, 0xec, 0xcd, 0x85, 0x4d, - 0xcb, 0x24, 0x64, 0x2a, 0x8f, 0x98, 0x32, 0xb9, 0x32, 0xd1, 0xf5, 0x59, 0x3c, 0xb9, 0x7a, 0x35, - 0xaa, 0xbd, 0xe8, 0x67, 0xf7, 0x74, 0xb8, 0xa1, 0x9f, 0x2c, 0xbb, 0x4b, 0xf5, 0xf4, 0xef, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x04, 0x32, 0x2d, 0xba, 0x62, 0x06, 0x00, 0x00, + // 817 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x6f, 0xe4, 0x34, + 0x14, 0x6e, 0x3a, 0x4b, 0x77, 0xea, 0x69, 0xb7, 0x8b, 0x29, 0x4b, 0xe8, 0x4a, 0xd3, 0x6c, 0xe1, + 0x30, 0x02, 0x6d, 0x42, 0x4b, 0x25, 0x24, 0x6e, 0xb4, 0x65, 0x59, 0xf6, 0xd0, 0xce, 0xa6, 0x65, + 0x91, 0xe0, 0x60, 0x39, 0xf6, 0x9b, 0x89, 0x45, 0x62, 0x47, 0xb6, 0x93, 0xd2, 0x5f, 0xc0, 0x95, + 0x23, 0x3f, 0x69, 0xb9, 0xed, 0x91, 0x13, 0xa0, 0xf6, 0x8f, 0xa0, 0x38, 0x49, 0x9b, 0x41, 0x14, + 0xca, 0xcd, 0xcf, 0xef, 0xfb, 0xbe, 0xe4, 0x7b, 0xf6, 0x7b, 0x46, 0x9f, 0x08, 0x69, 0x41, 0xb3, + 0x94, 0x0a, 0x49, 0x0c, 0xb0, 0x52, 0x0b, 0x7b, 0x11, 0x31, 0x56, 0x45, 0xd5, 0x6e, 0x64, 0x52, + 0xaa, 0x81, 0x13, 0xa6, 0xa4, 0x29, 0x73, 0xd0, 0x61, 0xa1, 0x95, 0x55, 0x78, 0xeb, 0x1f, 0x18, + 0x21, 0x63, 0x55, 0x58, 0xed, 0x6e, 0x3d, 0xb6, 0x20, 0x39, 0xe8, 0x5c, 0x48, 0x1b, 0xd1, 0x84, + 0x89, 0xc8, 0x5e, 0x14, 0x60, 0x1a, 0xe2, 0x56, 0x24, 0x12, 0x16, 0x65, 0x62, 0x9e, 0x5a, 0x96, + 0x09, 0x90, 0xd6, 0x44, 0x3d, 0x74, 0xb5, 0xdb, 0x8b, 0x5a, 0xc2, 0x78, 0xae, 0xd4, 0x3c, 0x83, + 0xc8, 0x45, 0x49, 0x39, 0x8b, 0x78, 0xa9, 0xa9, 0x15, 0x4a, 0xb6, 0xf9, 0xcd, 0xb9, 0x9a, 0x2b, + 0xb7, 0x8c, 0xea, 0x55, 0xb3, 0xbb, 0x73, 0xb5, 0x82, 0x1e, 0x1c, 0xb6, 0xbf, 0x3c, 0xa5, 0x9a, + 0xe6, 0x06, 0xfb, 0xe8, 0x3e, 0x48, 0x9a, 0x64, 0xc0, 0x7d, 0x2f, 0xf0, 0x26, 0xc3, 0xb8, 0x0b, + 0xf1, 0x09, 0xfa, 0x30, 0xc9, 0x14, 0xfb, 0xc1, 0x90, 0x02, 0x34, 0xe1, 0xc2, 0x58, 0x2d, 0x92, + 0xb2, 0xfe, 0x06, 0xb1, 0x9a, 0x4a, 0x93, 0x0b, 0x63, 0x84, 0x92, 0xfe, 0x72, 0xe0, 0x4d, 0x06, + 0xf1, 0x93, 0x06, 0x3b, 0x05, 0x7d, 0xd4, 0x43, 0x9e, 0xf5, 0x80, 0xf8, 0x05, 0x7a, 0x72, 0xab, + 0x0a, 0x61, 0x29, 0x95, 0x12, 0x32, 0x7f, 0x10, 0x78, 0x93, 0xd5, 0x78, 0x9b, 0xdf, 0x22, 0x72, + 0xd8, 0xc0, 0xf0, 0xe7, 0x68, 0xab, 0xd0, 0xaa, 0x12, 0x1c, 0x34, 0x99, 0x01, 0x90, 0x42, 0xa9, + 0x8c, 0x50, 0xce, 0x35, 0x31, 0x56, 0xfb, 0xf7, 0x9c, 0xc8, 0xa3, 0x0e, 0xf1, 0x0c, 0x60, 0xaa, + 0x54, 0xf6, 0x05, 0xe7, 0xfa, 0xd4, 0x6a, 0xfc, 0x12, 0x61, 0xc6, 0x2a, 0x62, 0x45, 0x0e, 0xaa, + 0xb4, 0xb5, 0x3b, 0xa1, 0xb8, 0xff, 0x56, 0xe0, 0x4d, 0x46, 0x7b, 0xef, 0x87, 0x4d, 0x61, 0xc3, + 0xae, 0xb0, 0xe1, 0x51, 0x5b, 0xd8, 0x83, 0xe1, 0xeb, 0xdf, 0xb7, 0x97, 0x7e, 0xf9, 0x63, 0xdb, + 0x8b, 0x1f, 0x32, 0x56, 0x9d, 0x35, 0xec, 0xa9, 0x23, 0xe3, 0xef, 0xd1, 0x7b, 0xce, 0xcd, 0x0c, + 0xf4, 0xdf, 0x75, 0x57, 0xee, 0xae, 0xfb, 0x6e, 0xa7, 0xb1, 0x28, 0xfe, 0x1c, 0x05, 0xdd, 0x3d, + 0x23, 0x1a, 0x16, 0x4a, 0x38, 0xd3, 0x94, 0xd5, 0x0b, 0xff, 0xbe, 0x73, 0x3c, 0xee, 0x70, 0xf1, + 0x02, 0xec, 0x59, 0x8b, 0xc2, 0x4f, 0x11, 0x4e, 0x85, 0xb1, 0x4a, 0x0b, 0x46, 0x33, 0x02, 0xd2, + 0x6a, 0x01, 0xc6, 0x1f, 0xba, 0x03, 0x7c, 0xfb, 0x26, 0xf3, 0x65, 0x93, 0xc0, 0xc7, 0xe8, 0x61, + 0x29, 0x13, 0x25, 0xb9, 0x90, 0xf3, 0xce, 0xce, 0xea, 0xdd, 0xed, 0x6c, 0x5c, 0x93, 0x5b, 0x23, + 0x9f, 0xa1, 0x47, 0x46, 0xcd, 0x2c, 0x51, 0x85, 0x25, 0x75, 0x85, 0x6c, 0xaa, 0xc1, 0xa4, 0x2a, + 0xe3, 0x3e, 0xaa, 0x7f, 0xff, 0x60, 0xd9, 0xf7, 0xe2, 0x77, 0x6a, 0xc4, 0x49, 0x61, 0x4f, 0x4a, + 0x7b, 0xd6, 0xa5, 0xf1, 0x07, 0x68, 0x5d, 0xc3, 0x39, 0xd5, 0x9c, 0x70, 0x90, 0x2a, 0x37, 0xfe, + 0x28, 0x18, 0x4c, 0x56, 0xe3, 0xb5, 0x66, 0xf3, 0xc8, 0xed, 0xe1, 0x7d, 0x74, 0x7d, 0xe0, 0x64, + 0x11, 0xbd, 0xe6, 0xd0, 0x9b, 0x5d, 0x36, 0xee, 0xb3, 0x5e, 0x22, 0xac, 0xc1, 0xea, 0x0b, 0xc2, + 0x21, 0xa3, 0x17, 0x9d, 0xcb, 0xf5, 0xff, 0x71, 0x19, 0x1c, 0xfd, 0xa8, 0x66, 0x37, 0x36, 0x77, + 0x7e, 0xf5, 0xd0, 0x66, 0xd7, 0x65, 0x5f, 0x81, 0x04, 0x23, 0xcc, 0xa9, 0xa5, 0x16, 0xf0, 0x73, + 0xb4, 0x52, 0xb8, 0xae, 0x73, 0xad, 0x36, 0xda, 0xfb, 0x28, 0xbc, 0x7d, 0x5e, 0x84, 0x8b, 0x7d, + 0x7a, 0x70, 0xaf, 0xfe, 0x60, 0xdc, 0xf2, 0xf1, 0x0b, 0x34, 0xec, 0xdc, 0xb8, 0xfe, 0x1b, 0xed, + 0x4d, 0xfe, 0x4d, 0x6b, 0xda, 0x62, 0xbf, 0x96, 0x33, 0xd5, 0x2a, 0x5d, 0xf3, 0xf1, 0x63, 0xb4, + 0x2a, 0xe1, 0x9c, 0x38, 0xa6, 0x6b, 0xbf, 0x61, 0x3c, 0x94, 0x70, 0x7e, 0x58, 0xc7, 0x3b, 0x3f, + 0x2d, 0xa3, 0xb5, 0x3e, 0x1b, 0x1f, 0xa3, 0xb5, 0x66, 0x44, 0x11, 0x53, 0x7b, 0x6a, 0x9d, 0x7c, + 0x1c, 0x8a, 0x84, 0x85, 0xfd, 0x01, 0x16, 0xf6, 0x46, 0x56, 0xed, 0xc6, 0xed, 0xba, 0x32, 0xc4, + 0x23, 0x76, 0x13, 0xe0, 0x6f, 0xd1, 0x46, 0x7d, 0x69, 0x41, 0x9a, 0xd2, 0xb4, 0x92, 0x8d, 0xa1, + 0xf0, 0x3f, 0x25, 0x3b, 0x5a, 0xa3, 0xfa, 0x80, 0x2d, 0xc4, 0xf8, 0x18, 0x6d, 0x08, 0x29, 0xac, + 0xa0, 0x19, 0xa9, 0x68, 0x46, 0x0c, 0x58, 0x7f, 0x10, 0x0c, 0x26, 0xa3, 0xbd, 0xa0, 0xaf, 0x53, + 0x4f, 0xe2, 0xf0, 0x15, 0xcd, 0x04, 0xa7, 0x56, 0xe9, 0x6f, 0x0a, 0x4e, 0x2d, 0xb4, 0x15, 0x5a, + 0x6f, 0xe9, 0xaf, 0x68, 0x76, 0x0a, 0xf6, 0xe0, 0xf8, 0xf5, 0xe5, 0xd8, 0x7b, 0x73, 0x39, 0xf6, + 0xfe, 0xbc, 0x1c, 0x7b, 0x3f, 0x5f, 0x8d, 0x97, 0xde, 0x5c, 0x8d, 0x97, 0x7e, 0xbb, 0x1a, 0x2f, + 0x7d, 0xb7, 0x3f, 0x17, 0x36, 0x2d, 0x93, 0x90, 0xa9, 0x3c, 0x62, 0xca, 0xe4, 0xca, 0x44, 0x37, + 0x67, 0xf1, 0xf4, 0xfa, 0xe5, 0xa8, 0xf6, 0xa3, 0x1f, 0xdd, 0xf3, 0xe1, 0x06, 0x7f, 0xb2, 0xe2, + 0x2e, 0xd5, 0xa7, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x9e, 0x67, 0x6a, 0xf6, 0x66, 0x06, 0x00, + 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) {