github.com/prysmaticlabs/prysm@v1.4.4/endtoend/helpers/epochTimer.go (about) 1 package helpers 2 3 import ( 4 "time" 5 6 "github.com/prysmaticlabs/prysm/shared/timeutils" 7 ) 8 9 // EpochTicker is a special ticker for timing epoch changes. 10 // The channel emits over the epoch interval, and ensures that 11 // the ticks are in line with the genesis time. This means that 12 // the duration between the ticks and the genesis time are always a 13 // multiple of the epoch duration. 14 // In addition, the channel returns the new epoch number. 15 type EpochTicker struct { 16 c chan uint64 17 done chan struct{} 18 } 19 20 // C returns the ticker channel. Call Cancel afterwards to ensure 21 // that the goroutine exits cleanly. 22 func (s *EpochTicker) C() <-chan uint64 { 23 return s.c 24 } 25 26 // Done should be called to clean up the ticker. 27 func (s *EpochTicker) Done() { 28 go func() { 29 s.done <- struct{}{} 30 }() 31 } 32 33 // NewEpochTicker starts the EpochTicker. 34 func NewEpochTicker(genesisTime time.Time, secondsPerEpoch uint64) *EpochTicker { 35 ticker := &EpochTicker{ 36 c: make(chan uint64), 37 done: make(chan struct{}), 38 } 39 ticker.start(genesisTime, secondsPerEpoch, timeutils.Since, timeutils.Until, time.After) 40 return ticker 41 } 42 43 func (s *EpochTicker) start( 44 genesisTime time.Time, 45 secondsPerEpoch uint64, 46 since, until func(time.Time) time.Duration, 47 after func(time.Duration) <-chan time.Time) { 48 49 d := time.Duration(secondsPerEpoch) * time.Second 50 51 go func() { 52 sinceGenesis := since(genesisTime) 53 54 var nextTickTime time.Time 55 var epoch uint64 56 if sinceGenesis < 0 { 57 // Handle when the current time is before the genesis time. 58 nextTickTime = genesisTime 59 epoch = 0 60 } else { 61 nextTick := sinceGenesis.Truncate(d) + d 62 nextTickTime = genesisTime.Add(nextTick) 63 epoch = uint64(nextTick / d) 64 } 65 66 for { 67 waitTime := until(nextTickTime) 68 select { 69 case <-after(waitTime): 70 s.c <- epoch 71 epoch++ 72 nextTickTime = nextTickTime.Add(d) 73 case <-s.done: 74 return 75 } 76 } 77 }() 78 }