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