Skip to content

Commit 441bcee

Browse files
committed
fix #1282
1 parent 50cb42a commit 441bcee

File tree

5 files changed

+105
-60
lines changed

5 files changed

+105
-60
lines changed

x/ccv/provider/keeper/hooks.go

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -91,50 +91,8 @@ func (h Hooks) AfterUnbondingInitiated(ctx sdk.Context, id uint64) error {
9191
return nil
9292
}
9393

94-
// ValidatorConsensusKeyInUse is called when a new validator is created
95-
// in the x/staking module of cosmos-sdk. In case it panics, the TX aborts
96-
// and thus, the validator is not created. See AfterValidatorCreated hook.
97-
func ValidatorConsensusKeyInUse(k *Keeper, ctx sdk.Context, valAddr sdk.ValAddress) bool {
98-
// Get the validator being added in the staking module.
99-
val, found := k.stakingKeeper.GetValidator(ctx, valAddr)
100-
if !found {
101-
// Abort TX, do NOT allow validator to be created
102-
panic("did not find newly created validator in staking module")
103-
}
104-
105-
// Get the consensus address of the validator being added
106-
consensusAddr, err := val.GetConsAddr()
107-
if err != nil {
108-
// Abort TX, do NOT allow validator to be created
109-
panic("could not get validator cons addr ")
110-
}
111-
112-
allConsumerChains := []string{}
113-
consumerChains := k.GetAllConsumerChains(ctx)
114-
for _, consumerChain := range consumerChains {
115-
allConsumerChains = append(allConsumerChains, consumerChain.ChainId)
116-
}
117-
proposedChains := k.GetAllProposedConsumerChainIDs(ctx)
118-
for _, proposedChain := range proposedChains {
119-
allConsumerChains = append(allConsumerChains, proposedChain.ChainID)
120-
}
121-
pendingChainIDs := k.GetAllPendingConsumerChainIDs(ctx)
122-
allConsumerChains = append(allConsumerChains, pendingChainIDs...)
123-
124-
for _, c := range allConsumerChains {
125-
if _, exist := k.GetValidatorByConsumerAddr(
126-
ctx,
127-
c,
128-
providertypes.NewConsumerConsAddress(consensusAddr)); exist {
129-
return true
130-
}
131-
}
132-
133-
return false
134-
}
135-
13694
func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error {
137-
if ValidatorConsensusKeyInUse(h.k, ctx, valAddr) {
95+
if h.k.ValidatorConsensusKeyInUse(ctx, valAddr) {
13896
// Abort TX, do NOT allow validator to be created
13997
panic("cannot create a validator with a consensus key that is already in use or was recently in use as an assigned consumer chain key")
14098
}

x/ccv/provider/keeper/hooks_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func TestValidatorConsensusKeyInUse(t *testing.T) {
8383
tt.setup(ctx, k)
8484

8585
t.Run(tt.name, func(t *testing.T) {
86-
if actual := providerkeeper.ValidatorConsensusKeyInUse(&k, ctx, newValidator.SDKStakingValidator().GetOperator()); actual != tt.expect {
86+
if actual := k.ValidatorConsensusKeyInUse(ctx, newValidator.SDKStakingValidator().GetOperator()); actual != tt.expect {
8787
t.Errorf("validatorConsensusKeyInUse() = %v, want %v", actual, tt.expect)
8888
}
8989
})

x/ccv/provider/keeper/keeper.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,19 @@ func (k Keeper) GetSlashLog(
11231123
func (k Keeper) BondDenom(ctx sdk.Context) string {
11241124
return k.stakingKeeper.BondDenom(ctx)
11251125
}
1126+
1127+
func (k Keeper) GetAllRegisteredAndProposedChainIDs(ctx sdk.Context) []string {
1128+
allConsumerChains := []string{}
1129+
consumerChains := k.GetAllConsumerChains(ctx)
1130+
for _, consumerChain := range consumerChains {
1131+
allConsumerChains = append(allConsumerChains, consumerChain.ChainId)
1132+
}
1133+
proposedChains := k.GetAllProposedConsumerChainIDs(ctx)
1134+
for _, proposedChain := range proposedChains {
1135+
allConsumerChains = append(allConsumerChains, proposedChain.ChainID)
1136+
}
1137+
pendingChainIDs := k.GetAllPendingConsumerChainIDs(ctx)
1138+
allConsumerChains = append(allConsumerChains, pendingChainIDs...)
1139+
1140+
return allConsumerChains
1141+
}

x/ccv/provider/keeper/key_assignment.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,14 @@ func (k Keeper) AssignConsumerKey(
377377
validator stakingtypes.Validator,
378378
consumerKey tmprotocrypto.PublicKey,
379379
) error {
380+
// check that the consumer chain is either registered or that
381+
// ConsumerAdditionProposal was voted on.
382+
if !k.CheckIfConsumerIsProposedOrRegistered(ctx, chainID) {
383+
return errorsmod.Wrapf(
384+
types.ErrUnknownConsumerChainId, chainID,
385+
)
386+
}
387+
380388
consAddrTmp, err := ccvtypes.TMCryptoPublicKeyToConsAddr(consumerKey)
381389
if err != nil {
382390
return err
@@ -629,3 +637,47 @@ func (k Keeper) DeleteKeyAssignments(ctx sdk.Context, chainID string) {
629637
k.DeleteConsumerAddrsToPrune(ctx, chainID, consumerAddrsToPrune.VscId)
630638
}
631639
}
640+
641+
// CheckIfConsumerIsProposedOrRegistered checks if a consumer chain is either registered, meaning either already running
642+
// or will run soon, or proposed its ConsumerAdditionProposal was submitted but the chain was not yet added to ICS yet.
643+
func (k Keeper) CheckIfConsumerIsProposedOrRegistered(ctx sdk.Context, chainID string) bool {
644+
allConsumerChains := k.GetAllRegisteredAndProposedChainIDs(ctx)
645+
for _, c := range allConsumerChains {
646+
if c == chainID {
647+
return true
648+
}
649+
}
650+
651+
return false
652+
}
653+
654+
// ValidatorConsensusKeyInUse checks if the given consensus key is already
655+
// used by validator in a consumer chain.
656+
// Note that this method is called when a new validator is created in the x/staking module of cosmos-sdk.
657+
// In case it panics, the TX aborts and thus, the validator is not created. See AfterValidatorCreated hook.
658+
func (k Keeper) ValidatorConsensusKeyInUse(ctx sdk.Context, valAddr sdk.ValAddress) bool {
659+
// Get the validator being added in the staking module.
660+
val, found := k.stakingKeeper.GetValidator(ctx, valAddr)
661+
if !found {
662+
// Abort TX, do NOT allow validator to be created
663+
panic("did not find newly created validator in staking module")
664+
}
665+
666+
// Get the consensus address of the validator being added
667+
consensusAddr, err := val.GetConsAddr()
668+
if err != nil {
669+
// Abort TX, do NOT allow validator to be created
670+
panic("could not get validator cons addr ")
671+
}
672+
673+
allConsumerChains := k.GetAllRegisteredAndProposedChainIDs(ctx)
674+
for _, c := range allConsumerChains {
675+
if _, exist := k.GetValidatorByConsumerAddr(ctx,
676+
c,
677+
types.NewConsumerConsAddress(consensusAddr),
678+
); exist {
679+
return true
680+
}
681+
}
682+
return false
683+
}

x/ccv/provider/keeper/key_assignment_test.go

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -389,17 +389,32 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
389389
doActions func(sdk.Context, providerkeeper.Keeper)
390390
}{
391391
/*
392-
0. Consumer registered: Assign PK0->CK0 and retrieve PK0->CK0
393-
1. Consumer registered: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1
394-
2. Consumer registered: Assign PK0->CK0, PK1->CK0 and error
395-
3. Consumer registered: Assign PK1->PK0 and error
396-
4. Consumer not registered: Assign PK0->CK0 and retrieve PK0->CK0
397-
5. Consumer not registered: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1
398-
6. Consumer not registered: Assign PK0->CK0, PK1->CK0 and error
399-
7. Consumer not registered: Assign PK1->PK0 and error
392+
0. Consumer not registered: Assign PK0->CK0 and error
393+
1. Consumer registered: Assign PK0->CK0 and retrieve PK0->CK0
394+
2. Consumer registered: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1
395+
3. Consumer registered: Assign PK0->CK0, PK1->CK0 and error
396+
4. Consumer registered: Assign PK1->PK0 and error
397+
5. Consumer proposed: Assign Assign PK0->CK0 and retrieve PK0->CK0
398+
6. Consumer proposed: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1
399+
7. Consumer proposed: Assign PK0->CK0, PK1->CK0 and error
400+
8. Consumer proposed: Assign PK1->PK0 and error
400401
*/
401402
{
402-
name: "0",
403+
name: "0",
404+
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {},
405+
doActions: func(ctx sdk.Context, k providerkeeper.Keeper) {
406+
err := k.AssignConsumerKey(ctx, chainID,
407+
providerIdentities[0].SDKStakingValidator(),
408+
consumerIdentities[0].TMProtoCryptoPublicKey(),
409+
)
410+
require.Error(t, err)
411+
_, found := k.GetValidatorByConsumerAddr(ctx, chainID,
412+
consumerIdentities[0].ConsumerConsAddress())
413+
require.False(t, found)
414+
},
415+
},
416+
{
417+
name: "1",
403418
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
404419
gomock.InOrder(
405420
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -424,7 +439,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
424439
},
425440
},
426441
{
427-
name: "1",
442+
name: "2",
428443
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
429444
gomock.InOrder(
430445
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -460,7 +475,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
460475
},
461476
},
462477
{
463-
name: "2",
478+
name: "3",
464479
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
465480
gomock.InOrder(
466481
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -493,7 +508,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
493508
},
494509
},
495510
{
496-
name: "3",
511+
name: "4",
497512
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
498513
gomock.InOrder(
499514
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -511,7 +526,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
511526
},
512527
},
513528
{
514-
name: "4",
529+
name: "5",
515530
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
516531
gomock.InOrder(
517532
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -520,6 +535,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
520535
)
521536
},
522537
doActions: func(ctx sdk.Context, k providerkeeper.Keeper) {
538+
k.SetProposedConsumerChain(ctx, chainID, 0)
523539
err := k.AssignConsumerKey(ctx, chainID,
524540
providerIdentities[0].SDKStakingValidator(),
525541
consumerIdentities[0].TMProtoCryptoPublicKey(),
@@ -532,7 +548,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
532548
},
533549
},
534550
{
535-
name: "5",
551+
name: "6",
536552
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
537553
gomock.InOrder(
538554
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -544,6 +560,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
544560
)
545561
},
546562
doActions: func(ctx sdk.Context, k providerkeeper.Keeper) {
563+
k.SetProposedConsumerChain(ctx, chainID, 0)
547564
err := k.AssignConsumerKey(ctx, chainID,
548565
providerIdentities[0].SDKStakingValidator(),
549566
consumerIdentities[0].TMProtoCryptoPublicKey(),
@@ -561,7 +578,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
561578
},
562579
},
563580
{
564-
name: "6",
581+
name: "7",
565582
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
566583
gomock.InOrder(
567584
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -573,6 +590,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
573590
)
574591
},
575592
doActions: func(ctx sdk.Context, k providerkeeper.Keeper) {
593+
k.SetProposedConsumerChain(ctx, chainID, 0)
576594
err := k.AssignConsumerKey(ctx, chainID,
577595
providerIdentities[0].SDKStakingValidator(),
578596
consumerIdentities[0].TMProtoCryptoPublicKey(),
@@ -590,7 +608,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
590608
},
591609
},
592610
{
593-
name: "7",
611+
name: "8",
594612
mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {
595613
gomock.InOrder(
596614
mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx,
@@ -599,6 +617,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) {
599617
)
600618
},
601619
doActions: func(ctx sdk.Context, k providerkeeper.Keeper) {
620+
k.SetProposedConsumerChain(ctx, chainID, 0)
602621
err := k.AssignConsumerKey(ctx, chainID,
603622
providerIdentities[1].SDKStakingValidator(),
604623
providerIdentities[0].TMProtoCryptoPublicKey(),

0 commit comments

Comments
 (0)