Skip to content

Commit fc1e33f

Browse files
Vanja/feat/767 code coverage staker (#1272)
* Increase coverage in staker package * fix after merge * Fix weight bug, add tests * Fix after merge * Fix comment fixes
1 parent b862c23 commit fc1e33f

9 files changed

Lines changed: 415 additions & 40 deletions

File tree

builtin/staker/aggregation/service.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,20 @@ func (s *Service) SubPendingVet(validator thor.Address, stake *stakes.WeightedSt
7676

7777
// Renew transitions the validator's delegations to the next staking period.
7878
// Called during staking period renewal process.
79-
func (s *Service) Renew(validator thor.Address) (*delta.Renewal, error) {
79+
func (s *Service) Renew(validator thor.Address) (*delta.Renewal, bool, error) {
8080
agg, err := s.GetAggregation(validator)
8181
if err != nil {
82-
return nil, err
82+
return nil, false, err
8383
}
8484

8585
renew := agg.renew()
8686

8787
if err = s.setAggregation(validator, agg, false); err != nil {
88-
return nil, err
88+
return nil, false, err
8989
}
90+
hasDelegations := agg.LockedVET.Sign() == 1
9091

91-
return renew, nil
92+
return renew, hasDelegations, nil
9293
}
9394

9495
// Exit moves all delegations to withdrawable state when validator exits.

builtin/staker/aggregation/service_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func TestService_Renew(t *testing.T) {
7474
wsAdd := stakes.NewWeightedStake(big.NewInt(3000), 200)
7575
assert.NoError(t, svc.AddPendingVET(v, wsAdd))
7676

77-
renew1, err := svc.Renew(v)
77+
renew1, _, err := svc.Renew(v)
7878
assert.NoError(t, err)
7979
assert.Equal(t, big.NewInt(3000), renew1.NewLockedVET)
8080
assert.Equal(t, big.NewInt(6000), renew1.NewLockedWeight)
@@ -83,7 +83,7 @@ func TestService_Renew(t *testing.T) {
8383

8484
assert.NoError(t, svc.AddPendingVET(v, stakes.NewWeightedStake(big.NewInt(500), 200)))
8585

86-
renew2, err := svc.Renew(v)
86+
renew2, _, err := svc.Renew(v)
8787
assert.NoError(t, err)
8888
assert.Equal(t, big.NewInt(-500), renew2.NewLockedVET)
8989
assert.Equal(t, big.NewInt(-1000), renew2.NewLockedWeight)
@@ -103,7 +103,7 @@ func TestService_Exit(t *testing.T) {
103103
v := thor.BytesToAddress([]byte("v"))
104104

105105
assert.NoError(t, svc.AddPendingVET(v, stakes.NewWeightedStake(big.NewInt(2000), 200)))
106-
_, err := svc.Renew(v)
106+
_, _, err := svc.Renew(v)
107107
assert.NoError(t, err)
108108

109109
assert.NoError(t, svc.AddPendingVET(v, stakes.NewWeightedStake(big.NewInt(800), 200)))
@@ -165,7 +165,7 @@ func TestService_Renew_ErrorOnGet(t *testing.T) {
165165
v := thor.BytesToAddress([]byte("v"))
166166
poisonMapping(st, contract, v)
167167

168-
_, err := svc.Renew(v)
168+
_, _, err := svc.Renew(v)
169169
assert.ErrorContains(t, err, "failed to get validator aggregation")
170170
}
171171

builtin/staker/housekeep.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,13 @@ func (s *Staker) applyEpochTransition(transition *EpochTransition) error {
189189
accumulatedRenewal := delta.NewRenewal()
190190
// Apply renewals
191191
for _, validator := range transition.Renewals {
192-
aggRenewal, err := s.aggregationService.Renew(validator)
192+
aggRenewal, hasDelegations, err := s.aggregationService.Renew(validator)
193193
if err != nil {
194194
return err
195195
}
196196
accumulatedRenewal.Add(aggRenewal)
197197
// Update validator state
198-
valRenewal, err := s.validationService.Renew(validator, aggRenewal)
198+
valRenewal, err := s.validationService.Renew(validator, aggRenewal, hasDelegations)
199199
if err != nil {
200200
return err
201201
}
@@ -258,7 +258,7 @@ func (s *Staker) activateNextValidation(currentBlk uint32, maxLeaderGroupSize *b
258258
logger.Debug("activating validator", "validatorID", validatorID, "block", currentBlk)
259259

260260
// renew the current delegations aggregation
261-
aggRenew, err := s.aggregationService.Renew(*validatorID)
261+
aggRenew, _, err := s.aggregationService.Renew(*validatorID)
262262
if err != nil {
263263
return nil, err
264264
}

builtin/staker/staker.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,24 @@ func (s *Staker) IncreaseStake(validator thor.Address, endorser thor.Address, am
253253
if err := s.validateNextPeriodTVL(validator); err != nil {
254254
return err
255255
}
256+
agg, err := s.aggregationService.GetAggregation(validator)
257+
if err != nil {
258+
return err
259+
}
260+
261+
weightedStake := stakes.NewWeightedStake(amount, validation.Multiplier)
262+
if agg.LockedVET.Sign() == 1 || agg.PendingVET.Sign() == 1 {
263+
weightedStake.AddWeight(*amount)
264+
aggWeightIncrease := stakes.NewWeightedStake(big.NewInt(0), validation.Multiplier)
265+
aggWeightIncrease.AddWeight(*amount)
266+
err = s.aggregationService.AddPendingVET(validator, aggWeightIncrease)
267+
if err != nil {
268+
return err
269+
}
270+
}
256271

257272
// update global totals
258-
if err := s.globalStatsService.AddQueued(stakes.NewWeightedStake(amount, validation.Multiplier)); err != nil {
273+
if err := s.globalStatsService.AddQueued(weightedStake); err != nil {
259274
return err
260275
}
261276

@@ -272,8 +287,20 @@ func (s *Staker) DecreaseStake(validator thor.Address, endorser thor.Address, am
272287
return err
273288
}
274289

290+
agg, err := s.aggregationService.GetAggregation(validator)
291+
if err != nil {
292+
return err
293+
}
294+
295+
weightedStake := stakes.NewWeightedStake(amount, validation.Multiplier)
296+
if agg.LockedVET.Sign() == 1 || agg.PendingVET.Sign() == 1 {
297+
weightedStake.AddWeight(*amount)
298+
aggWeightDecrease := stakes.NewWeightedStake(big.NewInt(0), validation.Multiplier)
299+
aggWeightDecrease.AddWeight(*amount)
300+
}
301+
275302
if queued {
276-
err = s.globalStatsService.RemoveQueued(stakes.NewWeightedStake(amount, validation.Multiplier))
303+
err = s.globalStatsService.RemoveQueued(weightedStake)
277304
if err != nil {
278305
return err
279306
}
@@ -357,6 +384,9 @@ func (s *Staker) AddDelegation(
357384
}
358385
if agg.PendingWeight.Cmp(big.NewInt(0).Add(valStake, stake)) < 0 {
359386
weightedStake.AddWeight(*valStake)
387+
if val.Status != validation.StatusQueued {
388+
weightedStake.AddWeight(*val.QueuedVET)
389+
}
360390
}
361391
}
362392

@@ -374,7 +404,9 @@ func (s *Staker) AddDelegation(
374404
}
375405

376406
// update global figures
377-
weightedStake.AddWeight(*val.QueuedVET)
407+
if val.Status == validation.StatusQueued {
408+
weightedStake.AddWeight(*val.QueuedVET)
409+
}
378410
if err = s.globalStatsService.AddQueued(weightedStake); err != nil {
379411
return nil, err
380412
}

builtin/staker/validation/service.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,12 +514,12 @@ func (s *Service) UpdateOfflineBlock(validator thor.Address, block uint32, onlin
514514
return s.repo.setValidation(validator, validation, false)
515515
}
516516

517-
func (s *Service) Renew(validator thor.Address, aggRenew *delta.Renewal) (*delta.Renewal, error) {
517+
func (s *Service) Renew(validator thor.Address, aggRenew *delta.Renewal, hasDelegations bool) (*delta.Renewal, error) {
518518
validation, err := s.GetExistingValidation(validator)
519519
if err != nil {
520520
return nil, err
521521
}
522-
delta := validation.renew(aggRenew)
522+
delta := validation.renew(aggRenew, hasDelegations)
523523
if err = s.repo.setValidation(validator, validation, false); err != nil {
524524
return nil, errors.Wrap(err, "failed to renew validator")
525525
}

builtin/staker/validation/service_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func TestService_ActivateAndExit_Flow(t *testing.T) {
102102
}
103103
assert.NoError(t, svc.repo.setValidation(id, val, true))
104104

105-
renew := (&Validation{QueuedVET: big.NewInt(100), LockedVET: big.NewInt(0), Weight: big.NewInt(0)}).renew(delta.NewRenewal())
105+
renew := (&Validation{QueuedVET: big.NewInt(100), LockedVET: big.NewInt(0), Weight: big.NewInt(0)}).renew(delta.NewRenewal(), false)
106106

107107
_, err := svc.ActivateValidator(id, 1, renew)
108108
assert.NoError(t, err)
@@ -610,3 +610,23 @@ func TestService_LeaderGroupNext_Order(t *testing.T) {
610610
assert.NoError(t, err)
611611
assert.Equal(t, thor.Address{}, n4)
612612
}
613+
614+
func TestService_GetCompletedPeriods(t *testing.T) {
615+
svc, _, _ := newSvc()
616+
617+
a1 := thor.BytesToAddress([]byte("a1"))
618+
a2 := thor.BytesToAddress([]byte("a2"))
619+
a3 := thor.BytesToAddress([]byte("a3"))
620+
for _, id := range []thor.Address{a1, a2, a3} {
621+
assert.NoError(t, svc.Add(id, id, thor.LowStakingPeriod(), big.NewInt(1)))
622+
idPtr, err := svc.NextToActivate(big.NewInt(10))
623+
assert.NoError(t, err)
624+
assert.Equal(t, id, *idPtr)
625+
_, err = svc.ActivateValidator(*idPtr, 1, &delta.Renewal{NewLockedWeight: big.NewInt(0)})
626+
assert.NoError(t, err)
627+
}
628+
629+
periods, err := svc.GetCompletedPeriods(a1)
630+
assert.NoError(t, err)
631+
assert.Equal(t, uint32(0), periods)
632+
}

builtin/staker/validation/validation.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const (
2525
)
2626

2727
const (
28-
Multiplier = uint8(100) // 200% for validators
28+
Multiplier = uint8(100) // 100% for validators if no delegations
2929
)
3030

3131
type Validation struct {
@@ -114,7 +114,7 @@ func (v *Validation) CurrentIteration() uint32 {
114114
// 3. Increase WithdrawableVET by PendingUnlockVET
115115
// 4. Set QueuedVET to 0
116116
// 5. Set PendingUnlockVET to 0
117-
func (v *Validation) renew(aggregations *delta.Renewal) *delta.Renewal {
117+
func (v *Validation) renew(aggregations *delta.Renewal, hasDelegations bool) *delta.Renewal {
118118
newLockedVET := big.NewInt(0)
119119

120120
if v.QueuedVET == nil {
@@ -132,21 +132,26 @@ func (v *Validation) renew(aggregations *delta.Renewal) *delta.Renewal {
132132
queuedDecrease := big.NewInt(0).Set(v.QueuedVET)
133133
v.WithdrawableVET = big.NewInt(0).Add(v.WithdrawableVET, v.PendingUnlockVET)
134134
v.QueuedVET = big.NewInt(0)
135+
pendingUnlock := v.PendingUnlockVET
135136
v.PendingUnlockVET = big.NewInt(0)
136137

137138
v.CompleteIterations++
138139

139-
changeWeight := big.NewInt(0).Add(newLockedVET, aggregations.NewLockedWeight)
140140
v.LockedVET = big.NewInt(0).Add(v.LockedVET, newLockedVET)
141+
newLockedWeight := newLockedVET
142+
if hasDelegations {
143+
newLockedWeight = big.NewInt(0).Sub(newLockedWeight, pendingUnlock)
144+
}
145+
146+
changeWeight := big.NewInt(0).Add(newLockedWeight, aggregations.NewLockedWeight)
141147
v.Weight = big.NewInt(0).Add(v.Weight, changeWeight)
142148

143149
// deltas
144-
weight := stakes.NewWeightedStake(newLockedVET, Multiplier).Weight()
145150
queuedDecreaseWeight := stakes.NewWeightedStake(queuedDecrease, Multiplier).Weight()
146151

147152
return &delta.Renewal{
148153
NewLockedVET: newLockedVET,
149-
NewLockedWeight: weight,
154+
NewLockedWeight: newLockedWeight,
150155
QueuedDecrease: queuedDecrease,
151156
QueuedDecreaseWeight: queuedDecreaseWeight,
152157
}

0 commit comments

Comments
 (0)