Skip to content

Commit

Permalink
fix(x/staking): stop validators from rotating to the same key on the …
Browse files Browse the repository at this point in the history
…same block (#20649)
  • Loading branch information
facundomedica authored Jun 13, 2024
1 parent 4611311 commit 43991b9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
14 changes: 13 additions & 1 deletion x/staking/keeper/cons_pubkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
27 changes: 27 additions & 0 deletions x/staking/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

0 comments on commit 43991b9

Please sign in to comment.