Skip to content

Commit bdadedb

Browse files
MSalopekgithub-actions
andauthored
feat!: enable unjail on pre-ccv chains (#2396)
* feat!: enable unjail on pre-ccv chains * docs: update docstrings * feat!: enable unjail related functions * docs: update docstrings * fix: update handling (changeover completed checks) * fix comment * tests: add unjail tests * tests: improve unjail tests * tests: improve unjail tests * tests: appease linter * Update testing documentation --------- Co-authored-by: github-actions <[email protected]>
1 parent fe2ec1e commit bdadedb

File tree

7 files changed

+100
-13
lines changed

7 files changed

+100
-13
lines changed

scripts/test_doc/test_documentation.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
|----------|-------------------|
1616
[TestDemocracyRewardsDistribution](../../tests/integration/democracy.go#L77) | TestDemocracyRewardsDistribution checks that rewards to democracy representatives, community pool, and provider redistribution account are done correctly.<details><summary>Details</summary>* Set up a democracy consumer chain.<br>* Create a new block.<br>* Check that rewards to democracy representatives, community pool, and provider redistribution account are distributed in the right proportions.</details> |
1717
[TestDemocracyMsgUpdateParams](../../tests/integration/democracy.go#L187) | TestDemocracyMsgUpdateParams checks that the consumer parameters can be updated through a governance proposal.<details><summary>Details</summary>* Set up a democracy consumer chain.<br>* Submit a proposal containing changes to the consumer module parameters.<br>* Check that the proposal is executed, and the parameters are updated.</details> |
18+
[TestDemocracyValidatorUnjail](../../tests/integration/democracy.go#L243) | TestDemocracyValidatorUnjail checks that the consumer validator can be unjailed when there is a standalone staking keeper available.<details><summary>Details</summary>* Set up a democracy consumer chain.<br>* Jail a validator.<br>* Check that the validator is jailed.<br>* Unjail the validator.<br>* Check that the validator is unjailed.</details> |
1819
</details>
1920

2021
# [distribution.go](../../tests/integration/distribution.go)
@@ -127,7 +128,8 @@
127128

128129
| Function | Short Description |
129130
|----------|-------------------|
130-
[TestUndelegationCompletion](../../tests/integration/unbonding.go#L16) | TestUndelegationCompletion tests that undelegations complete after the unbonding period elapses on the provider, regardless of the consumer's state<details><summary>Details</summary>* Set up CCV channel.<br>* Perform initial delegation of tokens followed by a partial undelegation (1/4 of the tokens).<br>* Verify that the staking unbonding operation is created as expected.<br>* Increment provider block height.<br>* Check that the unbonding operation has been completed.<br>* Verify that the token balances are correctly updated and the expected amount of tokens has been returned to the account.</details> |
131+
[TestUndelegationCompletion](../../tests/integration/unbonding.go#L17) | TestUndelegationCompletion tests that undelegations complete after the unbonding period elapses on the provider, regardless of the consumer's state<details><summary>Details</summary>* Set up CCV channel.<br>* Perform initial delegation of tokens followed by a partial undelegation (1/4 of the tokens).<br>* Verify that the staking unbonding operation is created as expected.<br>* Increment provider block height.<br>* Check that the unbonding operation has been completed.<br>* Verify that the token balances are correctly updated and the expected amount of tokens has been returned to the account.</details> |
132+
[TestConsumerUnjailNoOp](../../tests/integration/unbonding.go#L50) | TestConsumerUnjailNoOp check that consumerKeeper can call .Unjail() without error. This operation must only be available in case the app also implements a "standalone" staking keeper. |
131133
</details>
132134

133135
# [valset_update.go](../../tests/integration/valset_update.go)

tests/integration/democracy.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,52 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyMsgUpdateParams() {
233233
s.Assert().Equal(votersOldBalances, getAccountsBalances(s.consumerCtx(), bankKeeper, bondDenom, votingAccounts))
234234
}
235235

236+
// TestDemocracyValidatorUnjail checks that the consumer validator can be unjailed when there is a standalone staking keeper available.
237+
// @Long Description@
238+
// * Set up a democracy consumer chain.
239+
// * Jail a validator.
240+
// * Check that the validator is jailed.
241+
// * Unjail the validator.
242+
// * Check that the validator is unjailed.
243+
func (s *ConsumerDemocracyTestSuite) TestDemocracyValidatorUnjail() {
244+
stakingKeeper := s.consumerApp.GetTestStakingKeeper()
245+
consumerKeeper := s.consumerApp.GetConsumerKeeper()
246+
247+
validators, err := stakingKeeper.GetAllValidators(s.consumerCtx())
248+
s.Require().NoError(err)
249+
250+
// setting up pre-conditions
251+
// validator[0] is expected to be jailed
252+
expectJailed := validators[0]
253+
consAddr, err := expectJailed.GetConsAddr()
254+
s.Require().NoError(err)
255+
stakingKeeper.GetValidatorSet().Jail(s.consumerCtx(), consAddr)
256+
257+
s.consumerChain.NextBlock()
258+
259+
validators, err = stakingKeeper.GetAllValidators(s.consumerCtx())
260+
s.Require().NoError(err)
261+
for _, validator := range validators {
262+
if validator.OperatorAddress == expectJailed.OperatorAddress {
263+
s.Require().True(validator.IsJailed())
264+
} else {
265+
s.Require().False(validator.IsJailed())
266+
}
267+
}
268+
269+
// confirm unjail will not error and properly unjail
270+
// in case of a consumer chain without standalone staking the call is a no-op
271+
err = consumerKeeper.Unjail(s.consumerCtx(), consAddr)
272+
s.Require().NoError(err)
273+
s.consumerChain.NextBlock()
274+
275+
validators, err = stakingKeeper.GetAllValidators(s.consumerCtx())
276+
s.Require().NoError(err)
277+
for _, validator := range validators {
278+
s.Require().False(validator.IsJailed())
279+
}
280+
}
281+
236282
func submitProposalWithDepositAndVote(govKeeper govkeeper.Keeper, ctx sdk.Context, msgs []sdk.Msg,
237283
accounts []ibctesting.SenderAccount, proposer sdk.AccAddress, depositAmount sdk.Coins,
238284
) error {

tests/integration/unbonding.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package integration
22

33
import (
44
"cosmossdk.io/math"
5+
sdk "github.com/cosmos/cosmos-sdk/types"
56
)
67

78
// TestUndelegationCompletion tests that undelegations complete after
@@ -43,3 +44,13 @@ func (s *CCVTestSuite) TestUndelegationCompletion() {
4344
"unexpected initial balance after unbonding; test: %s",
4445
)
4546
}
47+
48+
// TestConsumerUnjailNoOp check that consumerKeeper can call .Unjail() without error.
49+
// This operation must only be available in case the app also implements a "standalone" staking keeper.
50+
func (s *CCVTestSuite) TestConsumerUnjailNoOp() {
51+
consumerKeeper := s.consumerApp.GetConsumerKeeper()
52+
53+
// this is a no-op
54+
err := consumerKeeper.Unjail(s.consumerCtx(), sdk.ConsAddress([]byte{0x01, 0x02, 0x03}))
55+
s.Require().NoError(err)
56+
}

testutil/integration/debug_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ func TestDemocracyMsgUpdateParams(t *testing.T) {
6161
runConsumerDemocracyTestByName(t, "TestDemocracyMsgUpdateParams")
6262
}
6363

64+
func TestDemocracyUnjail(t *testing.T) {
65+
runConsumerDemocracyTestByName(t, "TestDemocracyValidatorUnjail")
66+
}
67+
6468
//
6569
// Distribution tests
6670
//
@@ -193,6 +197,10 @@ func TestUndelegationCompletion(t *testing.T) {
193197
runCCVTestByName(t, "TestUndelegationCompletion")
194198
}
195199

200+
func TestConsumerUnjailNoOp(t *testing.T) {
201+
runCCVTestByName(t, "TestConsumerUnjailNoOp")
202+
}
203+
196204
//
197205
// Val set update tests
198206
//

x/ccv/consumer/keeper/changeover.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
// ChangeoverIsComplete returns whether the standalone to consumer changeover process is complete.
1010
func (k Keeper) ChangeoverIsComplete(ctx sdk.Context) bool {
1111
if !k.IsPrevStandaloneChain(ctx) {
12-
panic("ChangeoverIsComplete should only be called on previously standalone consumers")
12+
return true
1313
}
1414
return ctx.BlockHeight() >= k.FirstConsumerHeight(ctx)
1515
}

x/ccv/consumer/keeper/validators.go

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,14 @@ func (k Keeper) IterateValidators(context.Context, func(index int64, validator s
8484
return nil
8585
}
8686

87-
// Validator - unimplemented on CCV keeper
88-
func (k Keeper) Validator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.ValidatorI, error) {
89-
panic("unimplemented on CCV keeper")
87+
// Validator - unimplemented on CCV keeper but implemented on standalone keeper
88+
func (k Keeper) Validator(sdkCtx context.Context, addr sdk.ValAddress) (stakingtypes.ValidatorI, error) {
89+
ctx := sdk.UnwrapSDKContext(sdkCtx)
90+
if k.ChangeoverIsComplete(ctx) && k.standaloneStakingKeeper != nil {
91+
return k.standaloneStakingKeeper.Validator(ctx, addr)
92+
}
93+
94+
return stakingtypes.Validator{}, errors.New("unimplemented on CCV keeper")
9095
}
9196

9297
// IsJailed returns the outstanding slashing flag for the given validator address
@@ -174,16 +179,24 @@ func (k Keeper) SlashWithInfractionReason(goCtx context.Context, addr sdk.ConsAd
174179
// the provider validator set will soon be in effect, and jailing is n/a.
175180
func (k Keeper) Jail(context.Context, sdk.ConsAddress) error { return nil }
176181

177-
// Unjail - unimplemented on CCV keeper
182+
// Unjail is enabled for previously standalone chains and chains implementing democracy staking.
178183
//
179-
// This method should be a no-op even during a standalone to consumer changeover.
180-
// Once the upgrade has happened as a part of the changeover,
181-
// the provider validator set will soon be in effect, and jailing is n/a.
182-
func (k Keeper) Unjail(context.Context, sdk.ConsAddress) error { return nil }
184+
// This method should be a no-op for consumer chains that launched with the CCV module first.
185+
func (k Keeper) Unjail(sdkCtx context.Context, addr sdk.ConsAddress) error {
186+
ctx := sdk.UnwrapSDKContext(sdkCtx)
187+
if k.ChangeoverIsComplete(ctx) && k.standaloneStakingKeeper != nil {
188+
return k.standaloneStakingKeeper.Unjail(ctx, addr)
189+
}
190+
return nil
191+
}
183192

184-
// Delegation - unimplemented on CCV keeper
185-
func (k Keeper) Delegation(ctx context.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.DelegationI, error) {
186-
panic("unimplemented on CCV keeper")
193+
// Delegation - unimplemented on CCV keeper but implemented on standalone keeper
194+
func (k Keeper) Delegation(sdkCtx context.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.DelegationI, error) {
195+
ctx := sdk.UnwrapSDKContext(sdkCtx)
196+
if k.ChangeoverIsComplete(ctx) && k.standaloneStakingKeeper != nil {
197+
return k.standaloneStakingKeeper.Delegation(ctx, addr, valAddr)
198+
}
199+
return stakingtypes.Delegation{}, errors.New("unimplemented on CCV keeper")
187200
}
188201

189202
// MaxValidators - unimplemented on CCV keeper

x/ccv/consumer/keeper/validators_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ func TestIsValidatorJailed(t *testing.T) {
151151
isJailed3, err := consumerKeeper.IsValidatorJailed(ctx, consAddr)
152152
require.NoError(t, err)
153153
require.True(t, isJailed3)
154+
155+
// confirm that unjail returns no error and validator remains jailed
156+
mocks.MockStakingKeeper.EXPECT().IsValidatorJailed(ctx, consAddr).Return(true, nil).Times(1)
157+
require.NoError(t, consumerKeeper.Unjail(ctx, consAddr))
158+
isJailed3, err = consumerKeeper.IsValidatorJailed(ctx, consAddr)
159+
require.NoError(t, err)
160+
require.True(t, isJailed3)
154161
}
155162

156163
func TestSlash(t *testing.T) {

0 commit comments

Comments
 (0)