github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/consense/dpoa/timerpool.go (about) 1 package dpoa 2 3 4 import ( 5 "container/heap" 6 "fmt" 7 "math/rand" 8 "sync" 9 "time" 10 11 "github.com/sixexorg/magnetic-ring/consense/dpoa/comm" 12 "github.com/sixexorg/magnetic-ring/log" 13 ) 14 15 type TimerEventType int 16 17 const ( 18 EventProposeBlockTimeout TimerEventType = iota 19 EventProposalBackoff 20 EventRandomBackoff 21 EventPropose2ndBlockTimeout 22 EventEndorseBlockTimeout 23 EventEndorseEmptyBlockTimeout 24 EventCommitBlockTimeout 25 EventPeerHeartbeat 26 EventTxPool 27 EventTxBlockTimeout 28 EventMax 29 ) 30 31 var ( 32 makeProposalTimeout = 300 * time.Millisecond 33 make2ndProposalTimeout = 300 * time.Millisecond 34 endorseBlockTimeout = 100 * time.Millisecond 35 commitBlockTimeout = 200 * time.Millisecond 36 peerHandshakeTimeout = 10 * time.Second 37 txPooltimeout = 1 * time.Second 38 zeroTxBlockTimeout = 10 * time.Second 39 ) 40 41 type SendMsgEvent struct { 42 ToPeer string // peer index 43 Msg comm.ConsensusMsg 44 } 45 46 type TimerEvent struct { 47 evtType TimerEventType 48 blockNum uint32 49 msg comm.ConsensusMsg 50 } 51 52 type perBlockTimer map[uint32]*time.Timer 53 54 type EventTimer struct { 55 lock sync.Mutex 56 //server *Server 57 C chan *TimerEvent 58 //timerQueue TimerQueue 59 60 // bft timers 61 eventTimers map[TimerEventType]perBlockTimer 62 63 // peer heartbeat tickers 64 peerTickers map[uint32]*time.Timer 65 // other timers 66 normalTimers map[uint32]*time.Timer 67 } 68 69 func NewEventTimer() *EventTimer { 70 timer := &EventTimer{ 71 //server: server, 72 C: make(chan *TimerEvent, 64), 73 eventTimers: make(map[TimerEventType]perBlockTimer), 74 peerTickers: make(map[uint32]*time.Timer), 75 normalTimers: make(map[uint32]*time.Timer), 76 } 77 78 for i := 0; i < int(EventMax); i++ { 79 timer.eventTimers[TimerEventType(i)] = make(map[uint32]*time.Timer) 80 } 81 82 return timer 83 } 84 85 func stopAllTimers(timers map[uint32]*time.Timer) { 86 for _, t := range timers { 87 t.Stop() 88 } 89 } 90 91 func (self *EventTimer) stop() { 92 self.lock.Lock() 93 defer self.lock.Unlock() 94 95 // clear timers by event timer 96 for i := 0; i < int(EventMax); i++ { 97 stopAllTimers(self.eventTimers[TimerEventType(i)]) 98 self.eventTimers[TimerEventType(i)] = make(map[uint32]*time.Timer) 99 } 100 101 // clear normal timers 102 stopAllTimers(self.normalTimers) 103 self.normalTimers = make(map[uint32]*time.Timer) 104 } 105 106 func (self *EventTimer) StartTimer(Idx uint32, timeout time.Duration) error { 107 self.lock.Lock() 108 defer self.lock.Unlock() 109 110 if t, present := self.normalTimers[Idx]; present { 111 t.Stop() 112 log.Info("timer for %d got reset", Idx) 113 } 114 115 self.normalTimers[Idx] = time.AfterFunc(timeout, func() { 116 // remove timer from map 117 self.lock.Lock() 118 defer self.lock.Unlock() 119 delete(self.normalTimers, Idx) 120 121 self.C <- &TimerEvent{ 122 evtType: EventMax, 123 blockNum: Idx, 124 } 125 }) 126 127 return nil 128 } 129 130 func (self *EventTimer) CancelTimer(idx uint32) error { 131 self.lock.Lock() 132 defer self.lock.Unlock() 133 134 if t, present := self.normalTimers[idx]; present { 135 t.Stop() 136 delete(self.normalTimers, idx) 137 } 138 return nil 139 } 140 141 func (self *EventTimer) getEventTimeout(evtType TimerEventType) time.Duration { 142 switch evtType { 143 case EventProposeBlockTimeout: 144 return makeProposalTimeout 145 case EventPropose2ndBlockTimeout: 146 return make2ndProposalTimeout 147 case EventEndorseBlockTimeout: 148 return endorseBlockTimeout 149 case EventEndorseEmptyBlockTimeout: 150 return endorseBlockTimeout 151 case EventCommitBlockTimeout: 152 return commitBlockTimeout 153 case EventPeerHeartbeat: 154 return peerHandshakeTimeout 155 case EventProposalBackoff: 156 //rank := self.server.getProposerRank(self.server.GetCurrentBlockNo(), self.server.Index) 157 //if rank >= 0 { 158 // d := int64(rank+1) * int64(make2ndProposalTimeout) / 3 159 // return time.Duration(d) 160 //} 161 return time.Duration(100 * time.Second) 162 case EventRandomBackoff: 163 d := (rand.Int63n(100) + 50) * int64(endorseBlockTimeout) / 100 164 return time.Duration(d) 165 case EventTxPool: 166 return txPooltimeout 167 case EventTxBlockTimeout: 168 return zeroTxBlockTimeout 169 } 170 171 return 0 172 } 173 174 // 175 // internal helper, should call with lock held 176 // 177 func (self *EventTimer) startEventTimer(evtType TimerEventType, blockNum uint32) error { 178 timers := self.eventTimers[evtType] 179 if t, present := timers[blockNum]; present { 180 t.Stop() 181 delete(timers, blockNum) 182 log.Info("timer (type: %d) for %d got reset", evtType, blockNum) 183 } 184 185 timeout := self.getEventTimeout(evtType) 186 if timeout == 0 { 187 panic(fmt.Errorf("invalid timeout for event %d, blkNum %d", evtType, blockNum)) 188 } 189 timers[blockNum] = time.AfterFunc(timeout, func() { 190 self.C <- &TimerEvent{ 191 evtType: evtType, 192 blockNum: blockNum, 193 } 194 }) 195 196 return nil 197 } 198 199 // 200 // internal helper, should call with lock held 201 // 202 func (self *EventTimer) cancelEventTimer(evtType TimerEventType, blockNum uint32) error { 203 timers := self.eventTimers[evtType] 204 205 if t, present := timers[blockNum]; present { 206 t.Stop() 207 delete(timers, blockNum) 208 } 209 210 return nil 211 } 212 213 func (self *EventTimer) StartProposalTimer(blockNum uint32) error { 214 self.lock.Lock() 215 defer self.lock.Unlock() 216 217 //log.Infof("server %d started proposal timer for blk %d", self.server.accountStr, blockNum) 218 return self.startEventTimer(EventProposeBlockTimeout, blockNum) 219 } 220 221 func (self *EventTimer) CancelProposalTimer(blockNum uint32) error { 222 self.lock.Lock() 223 defer self.lock.Unlock() 224 225 return self.cancelEventTimer(EventProposeBlockTimeout, blockNum) 226 } 227 228 func (self *EventTimer) StartEndorsingTimer(blockNum uint32) error { 229 self.lock.Lock() 230 defer self.lock.Unlock() 231 232 //log.Infof("server %d started endorsing timer for blk %d", self.server.accountStr, blockNum) 233 return self.startEventTimer(EventEndorseBlockTimeout, blockNum) 234 } 235 236 func (self *EventTimer) CancelEndorseMsgTimer(blockNum uint32) error { 237 self.lock.Lock() 238 defer self.lock.Unlock() 239 240 return self.cancelEventTimer(EventEndorseBlockTimeout, blockNum) 241 } 242 243 func (self *EventTimer) StartEndorseEmptyBlockTimer(blockNum uint32) error { 244 self.lock.Lock() 245 defer self.lock.Unlock() 246 247 //log.Infof("server %d started empty endorsing timer for blk %d", self.server.accountStr, blockNum) 248 return self.startEventTimer(EventEndorseEmptyBlockTimeout, blockNum) 249 } 250 251 func (self *EventTimer) CancelEndorseEmptyBlockTimer(blockNum uint32) error { 252 self.lock.Lock() 253 defer self.lock.Unlock() 254 255 return self.cancelEventTimer(EventEndorseEmptyBlockTimeout, blockNum) 256 } 257 258 func (self *EventTimer) StartCommitTimer(blockNum uint32) error { 259 self.lock.Lock() 260 defer self.lock.Unlock() 261 262 //log.Infof("server %d started commit timer for blk %d", self.server.accountStr, blockNum) 263 return self.startEventTimer(EventCommitBlockTimeout, blockNum) 264 } 265 266 func (self *EventTimer) CancelCommitMsgTimer(blockNum uint32) error { 267 self.lock.Lock() 268 defer self.lock.Unlock() 269 270 return self.cancelEventTimer(EventCommitBlockTimeout, blockNum) 271 } 272 273 func (self *EventTimer) StartProposalBackoffTimer(blockNum uint32) error { 274 self.lock.Lock() 275 defer self.lock.Unlock() 276 277 return self.startEventTimer(EventProposalBackoff, blockNum) 278 } 279 280 func (self *EventTimer) CancelProposalBackoffTimer(blockNum uint32) error { 281 self.lock.Lock() 282 defer self.lock.Unlock() 283 284 return self.cancelEventTimer(EventProposalBackoff, blockNum) 285 } 286 287 func (self *EventTimer) StartBackoffTimer(blockNum uint32) error { 288 self.lock.Lock() 289 defer self.lock.Unlock() 290 291 return self.startEventTimer(EventRandomBackoff, blockNum) 292 } 293 294 func (self *EventTimer) CancelBackoffTimer(blockNum uint32) error { 295 self.lock.Lock() 296 defer self.lock.Unlock() 297 298 return self.cancelEventTimer(EventRandomBackoff, blockNum) 299 } 300 301 func (self *EventTimer) Start2ndProposalTimer(blockNum uint32) error { 302 self.lock.Lock() 303 defer self.lock.Unlock() 304 305 return self.startEventTimer(EventPropose2ndBlockTimeout, blockNum) 306 } 307 308 func (self *EventTimer) Cancel2ndProposalTimer(blockNum uint32) error { 309 self.lock.Lock() 310 defer self.lock.Unlock() 311 312 return self.cancelEventTimer(EventPropose2ndBlockTimeout, blockNum) 313 } 314 315 func (self *EventTimer) onBlockSealed(blockNum uint32) { 316 self.lock.Lock() 317 defer self.lock.Unlock() 318 319 // clear event timers 320 for i := 0; i < int(EventMax); i++ { 321 if err := self.cancelEventTimer(TimerEventType(i), blockNum); err != nil { 322 //log.Errorf("server %d, failed to stop timer %d on sealing", 323 // self.server.accountStr, i) 324 } 325 } 326 } 327 328 func (self *EventTimer) StartTxBlockTimeout(blockNum uint32) error { 329 self.lock.Lock() 330 defer self.lock.Unlock() 331 332 return self.startEventTimer(EventTxBlockTimeout, blockNum) 333 } 334 335 func (self *EventTimer) CancelTxBlockTimeout(blockNum uint32) error { 336 self.lock.Lock() 337 defer self.lock.Unlock() 338 339 return self.cancelEventTimer(EventTxBlockTimeout, blockNum) 340 } 341 342 func (self *EventTimer) startPeerTicker(peerIdx uint32) error { 343 self.lock.Lock() 344 defer self.lock.Unlock() 345 346 if p, present := self.peerTickers[peerIdx]; present { 347 p.Stop() 348 log.Info("ticker for %d got reset", peerIdx) 349 } 350 351 timeout := self.getEventTimeout(EventPeerHeartbeat) 352 self.peerTickers[peerIdx] = time.AfterFunc(timeout, func() { 353 self.C <- &TimerEvent{ 354 evtType: EventPeerHeartbeat, 355 blockNum: peerIdx, 356 } 357 self.peerTickers[peerIdx].Reset(timeout) 358 }) 359 360 return nil 361 } 362 363 func (self *EventTimer) stopPeerTicker(peerIdx uint32) error { 364 self.lock.Lock() 365 defer self.lock.Unlock() 366 367 if p, present := self.peerTickers[peerIdx]; present { 368 p.Stop() 369 delete(self.peerTickers, peerIdx) 370 } 371 return nil 372 } 373 374 func (self *EventTimer) startTxTicker(blockNum uint32) error { 375 self.lock.Lock() 376 defer self.lock.Unlock() 377 378 return self.startEventTimer(EventTxPool, blockNum) 379 } 380 381 func (self *EventTimer) stopTxTicker(blockNum uint32) error { 382 self.lock.Lock() 383 defer self.lock.Unlock() 384 385 return self.cancelEventTimer(EventTxPool, blockNum) 386 } 387 388 /////////////////////////////////////////////////////////// 389 // 390 // timer queue 391 // 392 /////////////////////////////////////////////////////////// 393 394 type TimerItem struct { 395 due time.Time 396 evt *TimerEvent 397 index int 398 } 399 400 type TimerQueue []*TimerItem 401 402 func (tq TimerQueue) Len() int { 403 return len(tq) 404 } 405 406 func (tq TimerQueue) Less(i, j int) bool { 407 return tq[j].due.After(tq[i].due) 408 } 409 410 func (tq TimerQueue) Swap(i, j int) { 411 tq[i], tq[j] = tq[j], tq[i] 412 tq[i].index = i 413 tq[j].index = j 414 } 415 416 func (tq *TimerQueue) Push(x interface{}) { 417 item := x.(*TimerItem) 418 item.index = len(*tq) 419 *tq = append(*tq, item) 420 } 421 422 func (tq *TimerQueue) Pop() interface{} { 423 old := *tq 424 n := len(old) 425 item := old[n-1] 426 item.index = -1 427 *tq = old[0 : n-1] 428 return item 429 } 430 431 func (tq *TimerQueue) update(item *TimerItem, due time.Time) { 432 item.due = due 433 heap.Fix(tq, item.index) 434 } 435