Skip to content

Commit dd4cb70

Browse files
authored
chore(validations): make SetValidation private (#1262)
1 parent 42dc770 commit dd4cb70

7 files changed

Lines changed: 135 additions & 122 deletions

File tree

builtin/staker/housekeep.go

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,20 @@ import (
2121

2222
type EpochTransition struct {
2323
Block uint32
24-
Renewals []ValidatorRenewal
24+
Renewals []thor.Address
2525
ExitValidator *thor.Address
26+
Evictions []thor.Address
2627
ActivationCount int64
2728
}
2829

29-
type ValidatorRenewal struct {
30-
Validator thor.Address
31-
NewState *validation.Validation
32-
ValidatorDelta *delta.Renewal
33-
DelegationDelta *delta.Renewal
30+
func (et *EpochTransition) HasUpdates() bool {
31+
if et == nil {
32+
return false
33+
}
34+
return len(et.Renewals) > 0 || // renewing existing staking periods
35+
(et.ExitValidator != nil && !et.ExitValidator.IsZero()) || // exiting 1 validator
36+
len(et.Evictions) > 0 || // forcing eviction of offline validators
37+
et.ActivationCount > 0 // activating new validators
3438
}
3539

3640
// Housekeep performs epoch transitions at epoch boundaries
@@ -46,7 +50,7 @@ func (s *Staker) Housekeep(currentBlock uint32) (bool, error) {
4650
return false, err
4751
}
4852

49-
if transition == nil || (len(transition.Renewals) == 0 && transition.ExitValidator == nil && transition.ActivationCount == 0) {
53+
if !transition.HasUpdates() {
5054
return false, nil
5155
}
5256

@@ -62,22 +66,21 @@ func (s *Staker) Housekeep(currentBlock uint32) (bool, error) {
6266
func (s *Staker) computeEpochTransition(currentBlock uint32) (*EpochTransition, error) {
6367
var err error
6468

65-
transition := &EpochTransition{Block: currentBlock}
66-
67-
var renewals []ValidatorRenewal
69+
var renewals []thor.Address
70+
var evictions []thor.Address
6871
active := make(map[thor.Address]*validation.Validation)
6972
exitValidator := thor.Address{}
7073
err = s.validationService.LeaderGroupIterator(
7174
s.renewalCallback(currentBlock, &renewals),
7275
s.exitsCallback(currentBlock, &exitValidator),
7376
s.collectActiveCallback(active),
74-
s.evictionCallback(currentBlock),
77+
s.evictionCallback(currentBlock, &evictions),
7578
)
7679
if err != nil {
7780
return nil, err
7881
}
7982

80-
transition.Renewals = renewals
83+
transition := &EpochTransition{Block: currentBlock, Renewals: renewals, Evictions: evictions}
8184

8285
if !exitValidator.IsZero() {
8386
transition.ExitValidator = &exitValidator
@@ -92,7 +95,7 @@ func (s *Staker) computeEpochTransition(currentBlock uint32) (*EpochTransition,
9295
return transition, nil
9396
}
9497

95-
func (s *Staker) renewalCallback(currentBlock uint32, renewals *[]ValidatorRenewal) func(thor.Address, *validation.Validation) error {
98+
func (s *Staker) renewalCallback(currentBlock uint32, renewals *[]thor.Address) func(thor.Address, *validation.Validation) error {
9699
// Collect all validators due for renewal
97100
return func(validator thor.Address, entry *validation.Validation) error {
98101
// Skip validators due to exit
@@ -105,24 +108,7 @@ func (s *Staker) renewalCallback(currentBlock uint32, renewals *[]ValidatorRenew
105108
return nil
106109
}
107110

108-
// Compute renewal deltas
109-
validatorRenewal := entry.Renew()
110-
delegationsRenewal, err := s.aggregationService.Renew(validator)
111-
if err != nil {
112-
return err
113-
}
114-
115-
// Calculate new weight and locked VET
116-
changeWeight := big.NewInt(0).Add(validatorRenewal.NewLockedWeight, delegationsRenewal.NewLockedWeight)
117-
entry.LockedVET = big.NewInt(0).Add(entry.LockedVET, validatorRenewal.NewLockedVET)
118-
entry.Weight = big.NewInt(0).Add(entry.Weight, changeWeight)
119-
120-
*renewals = append(*renewals, ValidatorRenewal{
121-
Validator: validator,
122-
NewState: entry,
123-
ValidatorDelta: validatorRenewal,
124-
DelegationDelta: delegationsRenewal,
125-
})
111+
*renewals = append(*renewals, validator)
126112

127113
return nil
128114
}
@@ -144,19 +130,11 @@ func (s *Staker) exitsCallback(currentBlock uint32, exitAddress *thor.Address) f
144130
}
145131
}
146132

147-
func (s *Staker) evictionCallback(currentBlock uint32) func(thor.Address, *validation.Validation) error {
133+
func (s *Staker) evictionCallback(currentBlock uint32, evictions *[]thor.Address) func(thor.Address, *validation.Validation) error {
148134
return func(validator thor.Address, entry *validation.Validation) error {
149135
if entry.OfflineBlock != nil && currentBlock > *entry.OfflineBlock+(thor.OfflineValidatorEvictionThresholdEpochs*EpochLength.Get()) {
150-
exitBlock, err := s.validationService.SetExitBlock(validator, currentBlock+EpochLength.Get())
151-
if err != nil {
152-
return err
153-
}
154-
if entry.ExitBlock != nil && *entry.ExitBlock < exitBlock {
155-
exitBlock = *entry.ExitBlock
156-
}
157-
entry.ExitBlock = &exitBlock
158-
159-
return s.validationService.SetValidation(validator, entry, false)
136+
*evictions = append(*evictions, validator)
137+
return nil
160138
}
161139
return nil
162140
}
@@ -210,14 +188,18 @@ func (s *Staker) applyEpochTransition(transition *EpochTransition) error {
210188

211189
accumulatedRenewal := delta.NewRenewal()
212190
// Apply renewals
213-
for _, renewal := range transition.Renewals {
214-
accumulatedRenewal.Add(renewal.ValidatorDelta)
215-
accumulatedRenewal.Add(renewal.DelegationDelta)
216-
191+
for _, validator := range transition.Renewals {
192+
aggRenewal, err := s.aggregationService.Renew(validator)
193+
if err != nil {
194+
return err
195+
}
196+
accumulatedRenewal.Add(aggRenewal)
217197
// Update validator state
218-
if err := s.validationService.SetValidation(renewal.Validator, renewal.NewState, false); err != nil {
198+
valRenewal, err := s.validationService.Renew(validator, aggRenewal)
199+
if err != nil {
219200
return err
220201
}
202+
accumulatedRenewal.Add(valRenewal)
221203
}
222204
// Apply accumulated renewals to global stats
223205
if err := s.globalStatsService.ApplyRenewal(accumulatedRenewal); err != nil {
@@ -244,6 +226,14 @@ func (s *Staker) applyEpochTransition(transition *EpochTransition) error {
244226
}
245227
}
246228

229+
// Apply evictions
230+
for _, validator := range transition.Evictions {
231+
logger.Info("evicting validator", "validator", validator)
232+
if err := s.validationService.Evict(validator, transition.Block); err != nil {
233+
return err
234+
}
235+
}
236+
247237
// Apply activations using existing method
248238
maxLeaderGroupSize, err := s.params.Get(thor.KeyMaxBlockProposers)
249239
if err != nil {

builtin/staker/staker.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,24 +306,20 @@ func (s *Staker) DecreaseStake(validator thor.Address, endorser thor.Address, am
306306
func (s *Staker) WithdrawStake(validator thor.Address, endorser thor.Address, currentBlock uint32) (*big.Int, error) {
307307
logger.Debug("withdrawing stake", "endorser", endorser, "validator", validator)
308308

309-
// remove validator QueuedVET if the validator is still queued
310-
val, err := s.validationService.GetValidation(validator)
309+
stake, queued, err := s.validationService.WithdrawStake(validator, endorser, currentBlock)
311310
if err != nil {
311+
logger.Info("withdraw failed", "validator", validator, "error", err)
312312
return nil, err
313313
}
314-
if val.Status == validation.StatusQueued {
315-
err = s.globalStatsService.RemoveQueued(stakes.NewWeightedStake(val.QueuedVET, validation.Multiplier))
314+
315+
// remove validator QueuedVET if the validator is still queued or had a pending increase
316+
if queued.Sign() == 1 {
317+
err = s.globalStatsService.RemoveQueued(stakes.NewWeightedStake(queued, validation.Multiplier))
316318
if err != nil {
317319
return nil, err
318320
}
319321
}
320322

321-
stake, err := s.validationService.WithdrawStake(val, validator, endorser, currentBlock)
322-
if err != nil {
323-
logger.Info("withdraw failed", "validator", validator, "error", err)
324-
return nil, err
325-
}
326-
327323
logger.Info("withdrew validator staker", "validator", validator)
328324
return stake, nil
329325
}

builtin/staker/validation/service.go

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ func (s *Service) Add(
201201
return err
202202
}
203203

204-
return s.SetValidation(validator, entry, true)
204+
return s.repo.SetValidation(validator, entry, true)
205205
}
206206

207207
func (s *Service) SignalExit(validator thor.Address, endorser thor.Address) error {
@@ -226,6 +226,24 @@ func (s *Service) SignalExit(validator thor.Address, endorser thor.Address) erro
226226
return s.repo.SetValidation(validator, validation, false)
227227
}
228228

229+
func (s *Service) Evict(validator thor.Address, currentBlock uint32) error {
230+
validation, err := s.GetExistingValidation(validator)
231+
if err != nil {
232+
return err
233+
}
234+
235+
exitBlock, err := s.SetExitBlock(validator, currentBlock+s.epochLength)
236+
if err != nil {
237+
return err
238+
}
239+
if validation.ExitBlock != nil && *validation.ExitBlock < exitBlock {
240+
exitBlock = *validation.ExitBlock
241+
}
242+
validation.ExitBlock = &exitBlock
243+
244+
return s.repo.SetValidation(validator, validation, false)
245+
}
246+
229247
func (s *Service) IncreaseStake(validator thor.Address, endorser thor.Address, amount *big.Int) error {
230248
entry, err := s.GetExistingValidation(validator)
231249
if err != nil {
@@ -243,7 +261,7 @@ func (s *Service) IncreaseStake(validator thor.Address, endorser thor.Address, a
243261

244262
entry.QueuedVET = big.NewInt(0).Add(amount, entry.QueuedVET)
245263

246-
return s.SetValidation(validator, entry, false)
264+
return s.repo.SetValidation(validator, entry, false)
247265
}
248266

249267
func (s *Service) SetBeneficiary(validator, endorser, beneficiary thor.Address) error {
@@ -262,7 +280,7 @@ func (s *Service) SetBeneficiary(validator, endorser, beneficiary thor.Address)
262280
} else {
263281
entry.Beneficiary = &beneficiary
264282
}
265-
if err = s.SetValidation(validator, entry, false); err != nil {
283+
if err = s.repo.SetValidation(validator, entry, false); err != nil {
266284
return errors.Wrap(err, "failed to set beneficiary")
267285
}
268286
return nil
@@ -305,19 +323,22 @@ func (s *Service) DecreaseStake(validator thor.Address, endorser thor.Address, a
305323
entry.WithdrawableVET = big.NewInt(0).Add(entry.WithdrawableVET, amount)
306324
}
307325

308-
return entry.Status == StatusQueued, s.SetValidation(validator, entry, false)
326+
return entry.Status == StatusQueued, s.repo.SetValidation(validator, entry, false)
309327
}
310328

311329
// WithdrawStake allows validations to withdraw any withdrawable stake.
312330
// It also verifies the endorser and updates the validator totals.
313331
func (s *Service) WithdrawStake(
314-
val *Validation,
315332
validator thor.Address,
316333
endorser thor.Address,
317334
currentBlock uint32,
318-
) (*big.Int, error) {
335+
) (*big.Int, *big.Int, error) {
336+
val, err := s.GetExistingValidation(validator)
337+
if err != nil {
338+
return nil, nil, err
339+
}
319340
if val.Endorser != endorser {
320-
return big.NewInt(0), reverts.New("invalid endorser")
341+
return big.NewInt(0), big.NewInt(0), reverts.New("invalid endorser")
321342
}
322343

323344
// calculate currently available VET to withdraw
@@ -333,21 +354,22 @@ func (s *Service) WithdrawStake(
333354
val.QueuedVET = big.NewInt(0)
334355
val.Status = StatusExit
335356
if err := s.validatorQueue.Remove(validator); err != nil {
336-
return nil, err
357+
return nil, nil, err
337358
}
338359
}
360+
queuedVET := big.NewInt(0).Set(val.QueuedVET)
339361
// remove any que
340362
if val.QueuedVET.Sign() > 0 {
341363
val.QueuedVET = big.NewInt(0)
342364
}
343365

344366
// no more withdraw after this
345367
val.WithdrawableVET = big.NewInt(0)
346-
if err := s.SetValidation(validator, val, false); err != nil {
347-
return nil, err
368+
if err := s.repo.SetValidation(validator, val, false); err != nil {
369+
return nil, nil, err
348370
}
349371

350-
return withdrawable, nil
372+
return withdrawable, queuedVET, nil
351373
}
352374

353375
func (s *Service) NextToActivate(maxLeaderGroupSize *big.Int) (*thor.Address, error) {
@@ -388,12 +410,12 @@ func (s *Service) ExitValidator(validator thor.Address) (*delta.Exit, error) {
388410
if entry.IsEmpty() {
389411
return nil, nil
390412
}
391-
exit := entry.Exit()
413+
exit := entry.exit()
392414
if err = s.leaderGroup.Remove(validator); err != nil {
393415
return nil, err
394416
}
395417

396-
if err = s.SetValidation(validator, entry, false); err != nil {
418+
if err = s.repo.SetValidation(validator, entry, false); err != nil {
397419
return nil, err
398420
}
399421

@@ -477,7 +499,7 @@ func (s *Service) ActivateValidator(
477499
}
478500

479501
// Persist the updated validation state
480-
if err = s.SetValidation(validationID, val, false); err != nil {
502+
if err = s.repo.SetValidation(validationID, val, false); err != nil {
481503
return nil, err
482504
}
483505

@@ -504,7 +526,20 @@ func (s *Service) UpdateOfflineBlock(validator thor.Address, block uint32, onlin
504526
validation.OfflineBlock = &block
505527
}
506528

507-
return s.SetValidation(validator, validation, false)
529+
return s.repo.SetValidation(validator, validation, false)
530+
}
531+
532+
func (s *Service) Renew(validator thor.Address, aggRenew *delta.Renewal) (*delta.Renewal, error) {
533+
validation, err := s.GetExistingValidation(validator)
534+
if err != nil {
535+
return nil, err
536+
}
537+
delta := validation.renew(aggRenew)
538+
if err = s.repo.SetValidation(validator, validation, false); err != nil {
539+
return nil, errors.Wrap(err, "failed to renew validator")
540+
}
541+
542+
return delta, nil
508543
}
509544

510545
//
@@ -526,10 +561,6 @@ func (s *Service) GetExistingValidation(validator thor.Address) (*Validation, er
526561
return v, nil
527562
}
528563

529-
func (s *Service) SetValidation(validator thor.Address, entry *Validation, isNew bool) error {
530-
return s.repo.SetValidation(validator, entry, isNew)
531-
}
532-
533564
func (s *Service) LeaderGroupNext(prev thor.Address) (thor.Address, error) {
534565
return s.leaderGroup.Next(prev)
535566
}

0 commit comments

Comments
 (0)