Skip to content

Commit

Permalink
feat!: Introduce the MaxProviderConsensusValidators param (#1992)
Browse files Browse the repository at this point in the history
* Refactor validator set storage

* Add comment for getTotalPower

* Add provider consensus validator set storage

* Add new MaxProviderConsensusValidators param

* Add validation for MaxProviderConsensusValidators

* Add function to get MaxProviderConsensusValidators param

* refactor!: Refactor the validator set storage and add provider consensus validator storage (#1990)

* Refactor validator set storage

* Add comment for getTotalPower

* Add provider consensus validator set storage

* Add key to key test

* Add unit test for LastTotalProviderConsensusPower

* Address comments
  • Loading branch information
p-offtermatt authored Jul 2, 2024
1 parent f26e4ec commit 8ba4e6e
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 151 deletions.
4 changes: 4 additions & 0 deletions proto/interchain_security/ccv/provider/v1/provider.proto
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ message Params {

// The number of blocks that comprise an epoch.
int64 blocks_per_epoch = 10;

// The maximal number of validators that will be passed
// to the consensus engine on the provider.
int64 max_provider_consensus_validators = 11;
}

// SlashAcks contains cons addresses of consumer chain validators
Expand Down
7 changes: 7 additions & 0 deletions x/ccv/provider/keeper/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ func (k Keeper) GetBlocksPerEpoch(ctx sdk.Context) int64 {
return params.BlocksPerEpoch
}

// GetMaxProviderConsensusValidators returns the number of validators that will be passed on from the staking module
// to the consensus engine on the provider
func (k Keeper) GetMaxProviderConsensusValidators(ctx sdk.Context) int64 {
params := k.GetParams(ctx)
return params.MaxProviderConsensusValidators
}

// GetParams returns the paramset for the provider module
func (k Keeper) GetParams(ctx sdk.Context) types.Params {
store := ctx.KVStore(k.storeKey)
Expand Down
1 change: 1 addition & 0 deletions x/ccv/provider/keeper/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func TestParams(t *testing.T) {
Amount: math.NewInt(10000000),
},
600,
10,
)
providerKeeper.SetParams(ctx, newParams)
params = providerKeeper.GetParams(ctx)
Expand Down
2 changes: 2 additions & 0 deletions x/ccv/provider/migrations/v6/legacy_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,7 @@ func GetParamsLegacy(ctx sdk.Context, paramspace ccvtypes.LegacyParamSubspace) t
getSlashMeterReplenishFraction(ctx, paramspace),
getConsumerRewardDenomRegistrationFee(ctx, paramspace),
getBlocksPerEpoch(ctx, paramspace),
// this parameter is new so it doesn't need to be migrated, just initialized
types.DefaultMaxProviderConsensusValidators,
)
}
26 changes: 13 additions & 13 deletions x/ccv/provider/types/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestValidateGenesisState(t *testing.T) {
nil,
types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -103,7 +103,7 @@ func TestValidateGenesisState(t *testing.T) {
nil,
types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -124,7 +124,7 @@ func TestValidateGenesisState(t *testing.T) {
nil,
types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -145,7 +145,7 @@ func TestValidateGenesisState(t *testing.T) {
nil,
types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -172,7 +172,7 @@ func TestValidateGenesisState(t *testing.T) {
types.DefaultVscTimeoutPeriod,
types.DefaultSlashMeterReplenishPeriod,
types.DefaultSlashMeterReplenishFraction,
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -199,7 +199,7 @@ func TestValidateGenesisState(t *testing.T) {
types.DefaultVscTimeoutPeriod,
types.DefaultSlashMeterReplenishPeriod,
types.DefaultSlashMeterReplenishFraction,
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -226,7 +226,7 @@ func TestValidateGenesisState(t *testing.T) {
types.DefaultVscTimeoutPeriod,
types.DefaultSlashMeterReplenishPeriod,
types.DefaultSlashMeterReplenishFraction,
sdk.Coin{Denom: "stake", Amount: math.NewInt(1000000)}, 600),
sdk.Coin{Denom: "stake", Amount: math.NewInt(1000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -253,7 +253,7 @@ func TestValidateGenesisState(t *testing.T) {
types.DefaultVscTimeoutPeriod,
types.DefaultSlashMeterReplenishPeriod,
types.DefaultSlashMeterReplenishFraction,
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -280,7 +280,7 @@ func TestValidateGenesisState(t *testing.T) {
0, // 0 vsc timeout here
types.DefaultSlashMeterReplenishPeriod,
types.DefaultSlashMeterReplenishFraction,
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -307,7 +307,7 @@ func TestValidateGenesisState(t *testing.T) {
types.DefaultVscTimeoutPeriod,
0, // 0 slash meter replenish period here
types.DefaultSlashMeterReplenishFraction,
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -334,7 +334,7 @@ func TestValidateGenesisState(t *testing.T) {
types.DefaultVscTimeoutPeriod,
types.DefaultSlashMeterReplenishPeriod,
"1.15",
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600),
sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand Down Expand Up @@ -686,7 +686,7 @@ func TestValidateGenesisState(t *testing.T) {
nil,
types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 600),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 600, 180),
nil,
nil,
nil,
Expand All @@ -707,7 +707,7 @@ func TestValidateGenesisState(t *testing.T) {
nil,
types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-1000000)}, 600),
types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-1000000)}, 600, 180),
nil,
nil,
nil,
Expand Down
11 changes: 11 additions & 0 deletions x/ccv/provider/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const (
// an epoch corresponds to 1 hour (6 * 600 = 3600 seconds).
// forcing int64 as the Params KeyTable expects an int64 and not int.
DefaultBlocksPerEpoch = int64(600)

// DefaultMaxProviderConsensusValidators is the default maximum number of validators that will
// be passed on from the staking module to the consensus engine on the provider.
DefaultMaxProviderConsensusValidators = 180
)

// Reflection based keys for params subspace
Expand All @@ -57,6 +61,7 @@ var (
KeySlashMeterReplenishFraction = []byte("SlashMeterReplenishFraction")
KeyConsumerRewardDenomRegistrationFee = []byte("ConsumerRewardDenomRegistrationFee")
KeyBlocksPerEpoch = []byte("BlocksPerEpoch")
KeyMaxProviderConsensusValidators = []byte("MaxProviderConsensusValidators")
)

// ParamKeyTable returns a key table with the necessary registered provider params
Expand All @@ -75,6 +80,7 @@ func NewParams(
slashMeterReplenishFraction string,
consumerRewardDenomRegistrationFee sdk.Coin,
blocksPerEpoch int64,
maxProviderConsensusValidators int64,
) Params {
return Params{
TemplateClient: cs,
Expand All @@ -86,6 +92,7 @@ func NewParams(
SlashMeterReplenishFraction: slashMeterReplenishFraction,
ConsumerRewardDenomRegistrationFee: consumerRewardDenomRegistrationFee,
BlocksPerEpoch: blocksPerEpoch,
MaxProviderConsensusValidators: maxProviderConsensusValidators,
}
}

Expand Down Expand Up @@ -117,6 +124,7 @@ func DefaultParams() Params {
Amount: math.NewInt(10000000),
},
DefaultBlocksPerEpoch,
DefaultMaxProviderConsensusValidators,
)
}

Expand Down Expand Up @@ -152,6 +160,9 @@ func (p Params) Validate() error {
if err := ccvtypes.ValidateInt64(p.BlocksPerEpoch); err != nil {
return fmt.Errorf("blocks per epoch is invalid: %s", err)
}
if err := ccvtypes.ValidatePositiveInt64(p.MaxProviderConsensusValidators); err != nil {
return fmt.Errorf("max provider consensus validators is invalid: %s", err)
}
return nil
}

Expand Down
28 changes: 16 additions & 12 deletions x/ccv/provider/types/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,43 @@ func TestValidateParams(t *testing.T) {
{"custom valid params", types.NewParams(
ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), true},
"0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), true},
{"custom invalid params", types.NewParams(
ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"blank client", types.NewParams(&ibctmtypes.ClientState{},
"0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
{"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
// Check if "0.00" is valid or if a zero dec TrustFraction needs to return an error
{"0 trusting period fraction", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), true},
"0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), true},
{"0 ccv timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"0 init timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"0 vsc timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"0 slash meter replenish period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"slash meter replenish fraction over 1", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"invalid consumer reward denom registration fee denom", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 1000), false},
"0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 1000, 180), false},
{"invalid consumer reward denom registration fee amount", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-10000000)}, 1000), false},
"0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-10000000)}, 1000, 180), false},
{"0 max provider consensus validators", types.NewParams(
ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0,
time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}),
"0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 0), false},
}

for _, tc := range testCases {
Expand Down
Loading

0 comments on commit 8ba4e6e

Please sign in to comment.