fix(x/staking): stop validators from rotating to the same key on the same block (#20649)

This commit is contained in:
Facundo Medica 2024-06-13 13:27:44 +02:00 committed by GitHub
parent 461131146b
commit 43991b99e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 40 additions and 1 deletions

View File

@ -34,7 +34,19 @@ func (k Keeper) setConsPubKeyRotationHistory(
Height: height,
Fee: fee,
}
err := k.RotationHistory.Set(ctx, collections.Join(valAddr.Bytes(), height), history)
// check if there's another key rotation for this same key in the same block
allRotations, err := k.GetBlockConsPubKeyRotationHistory(ctx)
if err != nil {
return err
}
for _, r := range allRotations {
if r.NewConsPubkey.Compare(newPubKey) == 0 {
return types.ErrConsensusPubKeyAlreadyUsedForValidator
}
}
err = k.RotationHistory.Set(ctx, collections.Join(valAddr.Bytes(), height), history)
if err != nil {
return err
}

View File

@ -1378,3 +1378,30 @@ func (s *KeeperTestSuite) TestConsKeyRotn() {
})
}
}
// TestConsKeyRotationInSameBlock tests the scenario where multiple validators try to
// rotate to the **same** consensus key in the same block.
func (s *KeeperTestSuite) TestConsKeyRotationInSameBlock() {
stakingKeeper, ctx := s.stakingKeeper, s.ctx
msgServer := stakingkeeper.NewMsgServerImpl(stakingKeeper)
s.setValidators(2)
validators, err := stakingKeeper.GetAllValidators(ctx)
s.Require().NoError(err)
s.Require().Len(validators, 2)
req, err := types.NewMsgRotateConsPubKey(validators[0].GetOperator(), PKs[444])
s.Require().NoError(err)
s.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
_, err = msgServer.RotateConsPubKey(ctx, req)
s.Require().NoError(err)
req, err = types.NewMsgRotateConsPubKey(validators[1].GetOperator(), PKs[444])
s.Require().NoError(err)
_, err = msgServer.RotateConsPubKey(ctx, req)
s.Require().ErrorContains(err, "consensus pubkey is already used for a validator")
}