github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/emitter/validators.go (about) 1 package emitter 2 3 import ( 4 "time" 5 6 "github.com/unicornultrafoundation/go-helios/native/idx" 7 "github.com/unicornultrafoundation/go-helios/native/pos" 8 "github.com/unicornultrafoundation/go-helios/utils/piecefunc" 9 ) 10 11 const ( 12 validatorChallenge = 4 * time.Second 13 networkStartPeriod = 3 * time.Hour 14 ) 15 16 func (em *Emitter) recountValidators(validators *pos.Validators) { 17 // stakers with lower stake should emit less events to reduce network load 18 // confirmingEmitInterval = piecefunc(totalStakeBeforeMe / totalStake) * MinEmitInterval 19 totalStakeBefore := pos.Weight(0) 20 for i, stake := range validators.SortedWeights() { 21 vid := validators.GetID(idx.Validator(i)) 22 // pos.Weight is uint32, so cast to uint64 to avoid an overflow 23 stakeRatio := uint64(totalStakeBefore) * uint64(piecefunc.DecimalUnit) / uint64(validators.TotalWeight()) 24 if !em.offlineValidators[vid] { 25 totalStakeBefore += stake 26 } 27 confirmingEmitIntervalRatio := confirmingEmitIntervalF(stakeRatio) 28 em.stakeRatio[vid] = stakeRatio 29 em.expectedEmitIntervals[vid] = time.Duration(piecefunc.Mul(uint64(em.config.EmitIntervals.Confirming), confirmingEmitIntervalRatio)) 30 } 31 em.intervals.Confirming = em.expectedEmitIntervals[em.config.Validator.ID] 32 em.intervals.Max = em.config.EmitIntervals.Max 33 // if network just has started, then relax the doublesign protection 34 if time.Since(em.world.GetGenesisTime().Time()) < networkStartPeriod { 35 em.intervals.Max /= 6 36 em.intervals.DoublesignProtection /= 6 37 } 38 } 39 40 func (em *Emitter) recheckChallenges() { 41 if time.Since(em.prevRecheckedChallenges) < validatorChallenge/10 { 42 return 43 } 44 em.world.Lock() 45 defer em.world.Unlock() 46 now := time.Now() 47 if !em.idle() { 48 // give challenges to all the non-spare validators if network isn't idle 49 for _, vid := range em.validators.IDs() { 50 if em.offlineValidators[vid] { 51 continue 52 } 53 if _, ok := em.challenges[vid]; !ok { 54 em.challenges[vid] = now.Add(validatorChallenge + em.expectedEmitIntervals[vid]*4) 55 } 56 } 57 } else { 58 // erase all the challenges if network is idle 59 em.challenges = make(map[idx.ValidatorID]time.Time) 60 } 61 // check challenges 62 recount := false 63 for vid, challengeDeadline := range em.challenges { 64 if now.After(challengeDeadline) { 65 em.offlineValidators[vid] = true 66 recount = true 67 } 68 } 69 if recount { 70 em.recountValidators(em.validators) 71 } 72 em.prevRecheckedChallenges = now 73 }