github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/p2pserver/sync/org/org_block_sync.go (about)

     1  package org
     2  
     3  import (
     4  	"github.com/sixexorg/magnetic-ring/p2pserver/temp"
     5  	"math"
     6  	"sort"
     7  	"sync"
     8  	"time"
     9  
    10  	"github.com/sixexorg/magnetic-ring/common"
    11  	"github.com/sixexorg/magnetic-ring/core/orgchain/types"
    12  	"github.com/sixexorg/magnetic-ring/log"
    13  	p2pComm "github.com/sixexorg/magnetic-ring/p2pserver/common"
    14  	msgpack "github.com/sixexorg/magnetic-ring/p2pserver/message"
    15  	"github.com/sixexorg/magnetic-ring/p2pserver/peer"
    16  	"github.com/sixexorg/magnetic-ring/p2pserver/sync/p2pserprotocol"
    17  	ledger "github.com/sixexorg/magnetic-ring/store/orgchain/storages"
    18  	"github.com/sixexorg/magnetic-ring/store/orgchain/validation"
    19  )
    20  
    21  const (
    22  	SYNC_MAX_HEADER_FORWARD_SIZE = 5000       //keep CurrentHeaderHeight - CurrentBlockHeight <= SYNC_MAX_HEADER_FORWARD_SIZE
    23  	SYNC_MAX_FLIGHT_HEADER_SIZE  = 1          //Number of headers on flight
    24  	SYNC_MAX_FLIGHT_BLOCK_SIZE   = 50         //Number of blocks on flight
    25  	SYNC_MAX_BLOCK_CACHE_SIZE    = 500        //Cache size of block wait to commit to ledger
    26  	SYNC_HEADER_REQUEST_TIMEOUT  = 2          //s, Request header timeout time. If header haven't receive after SYNC_HEADER_REQUEST_TIMEOUT second, retry
    27  	SYNC_BLOCK_REQUEST_TIMEOUT   = 2          //s, Request block timeout time. If block haven't received after SYNC_BLOCK_REQUEST_TIMEOUT second, retry
    28  	SYNC_NEXT_BLOCK_TIMES        = 3          //Request times of next height block
    29  	SYNC_NEXT_BLOCKS_HEIGHT      = 2          //for current block height plus next
    30  	SYNC_NODE_RECORD_SPEED_CNT   = 3          //Record speed count for accuracy
    31  	SYNC_NODE_RECORD_TIME_CNT    = 3          //Record request time  for accuracy
    32  	SYNC_NODE_SPEED_INIT         = 100 * 1024 //Init a big speed (100MB/s) for every node in first round
    33  	SYNC_MAX_ERROR_RESP_TIMES    = 5          //Max error headers/blocks response times, if reaches, delete it
    34  	SYNC_MAX_HEIGHT_OFFSET       = 5          //Offset of the max height and current height
    35  )
    36  
    37  //NodeWeight record some params of node, using for sort
    38  type NodeWeight struct {
    39  	id           uint64    //NodeID
    40  	speed        []float32 //Record node request-response speed, using for calc the avg speed, unit kB/s
    41  	timeoutCnt   int       //Node response timeout count
    42  	errorRespCnt int       //Node response error data count
    43  	reqTime      []int64   //Record request time, using for calc the avg req time interval, unit millisecond
    44  }
    45  
    46  //NewNodeWeight new a nodeweight
    47  func NewNodeWeight(id uint64) *NodeWeight {
    48  	s := make([]float32, 0, SYNC_NODE_RECORD_SPEED_CNT)
    49  	for i := 0; i < SYNC_NODE_RECORD_SPEED_CNT; i++ {
    50  		s = append(s, float32(SYNC_NODE_SPEED_INIT))
    51  	}
    52  	r := make([]int64, 0, SYNC_NODE_RECORD_TIME_CNT)
    53  	now := time.Now().UnixNano() / int64(time.Millisecond)
    54  	for i := 0; i < SYNC_NODE_RECORD_TIME_CNT; i++ {
    55  		r = append(r, now)
    56  	}
    57  	return &NodeWeight{
    58  		id:           id,
    59  		speed:        s,
    60  		timeoutCnt:   0,
    61  		errorRespCnt: 0,
    62  		reqTime:      r,
    63  	}
    64  }
    65  
    66  //AddTimeoutCnt incre timeout count
    67  func (that *NodeWeight) AddTimeoutCnt() {
    68  	that.timeoutCnt++
    69  }
    70  
    71  //AddErrorRespCnt incre receive error header/block count
    72  func (that *NodeWeight) AddErrorRespCnt() {
    73  	that.errorRespCnt++
    74  }
    75  
    76  //GetErrorRespCnt get the error response count
    77  func (that *NodeWeight) GetErrorRespCnt() int {
    78  	return that.errorRespCnt
    79  }
    80  
    81  //AppendNewReqTime append new request time
    82  func (that *NodeWeight) AppendNewReqtime() {
    83  	copy(that.reqTime[0:SYNC_NODE_RECORD_TIME_CNT-1], that.reqTime[1:])
    84  	that.reqTime[SYNC_NODE_RECORD_TIME_CNT-1] = time.Now().UnixNano() / int64(time.Millisecond)
    85  }
    86  
    87  //addNewSpeed apend the new speed to tail, remove the oldest one
    88  func (that *NodeWeight) AppendNewSpeed(s float32) {
    89  	copy(that.speed[0:SYNC_NODE_RECORD_SPEED_CNT-1], that.speed[1:])
    90  	that.speed[SYNC_NODE_RECORD_SPEED_CNT-1] = s
    91  }
    92  
    93  //Weight calculate node's weight for sort. Highest weight node will be accessed first for next request.
    94  func (that *NodeWeight) Weight() float32 {
    95  	avgSpeed := float32(0.0)
    96  	for _, s := range that.speed {
    97  		avgSpeed += s
    98  	}
    99  	avgSpeed = avgSpeed / float32(len(that.speed))
   100  
   101  	avgInterval := float32(0.0)
   102  	now := time.Now().UnixNano() / int64(time.Millisecond)
   103  	for _, t := range that.reqTime {
   104  		avgInterval += float32(now - t)
   105  	}
   106  	avgInterval = avgInterval / float32(len(that.reqTime))
   107  	w := avgSpeed + avgInterval
   108  	return w
   109  }
   110  
   111  //NodeWeights implement sorting
   112  type NodeWeights []*NodeWeight
   113  
   114  func (nws NodeWeights) Len() int {
   115  	return len(nws)
   116  }
   117  
   118  func (nws NodeWeights) Swap(i, j int) {
   119  	nws[i], nws[j] = nws[j], nws[i]
   120  }
   121  func (nws NodeWeights) Less(i, j int) bool {
   122  	ni := nws[i]
   123  	nj := nws[j]
   124  	return ni.Weight() < nj.Weight() && ni.errorRespCnt >= nj.errorRespCnt && ni.timeoutCnt >= nj.timeoutCnt
   125  }
   126  
   127  //SyncFlightInfo record the info of fight object(header or block)
   128  type SyncFlightInfo struct {
   129  	Height      uint32         //BlockHeight of HeaderHeight
   130  	nodeId      uint64         //The current node to send msg
   131  	startTime   time.Time      //Request start time
   132  	failedNodes map[uint64]int //Map nodeId => timeout times
   133  	totalFailed int            //Total timeout times
   134  	lock        sync.RWMutex
   135  }
   136  
   137  //NewSyncFlightInfo return a new SyncFlightInfo instance
   138  func NewSyncFlightInfo(height uint32, nodeId uint64) *SyncFlightInfo {
   139  	return &SyncFlightInfo{
   140  		Height:      height,
   141  		nodeId:      nodeId,
   142  		startTime:   time.Now(),
   143  		failedNodes: make(map[uint64]int, 0),
   144  	}
   145  }
   146  
   147  //GetNodeId return current node id for sending msg
   148  func (that *SyncFlightInfo) GetNodeId() uint64 {
   149  	that.lock.RLock()
   150  	defer that.lock.RUnlock()
   151  	return that.nodeId
   152  }
   153  
   154  //SetNodeId set a new node id
   155  func (that *SyncFlightInfo) SetNodeId(nodeId uint64) {
   156  	that.lock.Lock()
   157  	defer that.lock.Unlock()
   158  	that.nodeId = nodeId
   159  }
   160  
   161  //MarkFailedNode mark node failed, after request timeout
   162  func (that *SyncFlightInfo) MarkFailedNode() {
   163  	that.lock.Lock()
   164  	defer that.lock.Unlock()
   165  	that.failedNodes[that.nodeId] += 1
   166  	that.totalFailed++
   167  }
   168  
   169  //GetFailedTimes return failed times of a node
   170  func (that *SyncFlightInfo) GetFailedTimes(nodeId uint64) int {
   171  	that.lock.RLock()
   172  	defer that.lock.RUnlock()
   173  	times, ok := that.failedNodes[nodeId]
   174  	if !ok {
   175  		return 0
   176  	}
   177  	return times
   178  }
   179  
   180  //GetTotalFailedTimes return the total failed times of request
   181  func (that *SyncFlightInfo) GetTotalFailedTimes() int {
   182  	that.lock.RLock()
   183  	defer that.lock.RUnlock()
   184  	return that.totalFailed
   185  }
   186  
   187  //ResetStartTime
   188  func (that *SyncFlightInfo) ResetStartTime() {
   189  	that.lock.Lock()
   190  	defer that.lock.Unlock()
   191  	that.startTime = time.Now()
   192  }
   193  
   194  //GetStartTime return the start time of request
   195  func (that *SyncFlightInfo) GetStartTime() time.Time {
   196  	that.lock.RLock()
   197  	defer that.lock.RUnlock()
   198  	return that.startTime
   199  }
   200  
   201  //BlockInfo is used for saving block information in cache
   202  type BlockInfo struct {
   203  	nodeID uint64
   204  	block  *types.Block
   205  }
   206  
   207  //OrgBlockSyncMgr is the manager class to deal with block sync
   208  type OrgBlockSyncMgr struct {
   209  	flightBlocks   map[common.Hash][]*SyncFlightInfo //Map BlockHash => []SyncFlightInfo, using for manager all of those block flights
   210  	flightHeaders  map[uint32]*SyncFlightInfo        //Map HeaderHeight => SyncFlightInfo, using for manager all of those header flights
   211  	blocksCache    map[uint32]*BlockInfo             //Map BlockHash => BlockInfo, using for cache the blocks receive from net, and waiting for commit to ledger
   212  	server         p2pserprotocol.SyncP2PSer         //Pointer to the local node
   213  	syncBlockLock  bool                              //Help to avoid send block sync request duplicate
   214  	syncHeaderLock bool                              //Help to avoid send header sync request duplicate
   215  	saveBlockLock  bool                              //Help to avoid saving block concurrently
   216  	exitCh         chan interface{}                  //ExitCh to receive exit signal
   217  	ledger         *ledger.LedgerStoreImp            //ledger
   218  	lock           sync.RWMutex                      //lock
   219  	nodeWeights    map[uint64]*NodeWeight            //Map NodeID => NodeStatus, using for getNextNode
   220  	// org
   221  	orgID common.Address
   222  }
   223  
   224  //NewOrgBlockSyncMgr return a OrgBlockSyncMgr instance
   225  func NewOrgBlockSyncMgr(server p2pserprotocol.SyncP2PSer, orgID common.Address) *OrgBlockSyncMgr {
   226  	return &OrgBlockSyncMgr{
   227  		flightBlocks:  make(map[common.Hash][]*SyncFlightInfo, 0),
   228  		flightHeaders: make(map[uint32]*SyncFlightInfo, 0),
   229  		blocksCache:   make(map[uint32]*BlockInfo, 0),
   230  		server:        server,
   231  		// ledger:        server.GetLedger(),
   232  		ledger: temp.GetLedger(orgID),
   233  
   234  		exitCh:      make(chan interface{}, 1),
   235  		nodeWeights: make(map[uint64]*NodeWeight, 0),
   236  		orgID:       orgID,
   237  	}
   238  }
   239  
   240  //Start to sync
   241  func (that *OrgBlockSyncMgr) Start() {
   242  	getledger := func() {
   243  		if that.ledger == nil {
   244  			that.ledger = temp.GetLedger(that.orgID)
   245  		}
   246  	}
   247  	for true {
   248  		getledger()
   249  		if that.ledger != nil {
   250  			break
   251  		}
   252  		time.Sleep(time.Second)
   253  		//fmt.Println(" ****** for true for true for true ...... ")
   254  	}
   255  
   256  	go that.sync()
   257  	go that.printHeight()
   258  	ticker := time.NewTicker(time.Second)
   259  	for {
   260  		select {
   261  		case <-that.exitCh:
   262  			return
   263  		case <-ticker.C:
   264  			go that.checkTimeout()
   265  			go that.sync()
   266  			go that.saveBlock()
   267  		}
   268  	}
   269  }
   270  
   271  
   272  func (that *OrgBlockSyncMgr) printHeight() {
   273  	t := time.NewTicker(p2pComm.DEFAULT_GEN_BLOCK_TIME * time.Second)
   274  	defer t.Stop()
   275  
   276  	for {
   277  		select {
   278  		case <-t.C:
   279  			log.Info(" **** orgID", "orgID", that.orgID, "CurrentBlockHeight", that.ledger.GetCurrentBlockHeight( /*that.orgID*/ ))
   280  			//fmt.Println(" ******* CurrentHeaderHeight:", that.ledger.GetCurrentHeaderHeight())
   281  		case <-that.exitCh:
   282  			return
   283  		}
   284  	}
   285  }
   286  
   287  func (that *OrgBlockSyncMgr) checkTimeout() {
   288  	now := time.Now()
   289  	headerTimeoutFlights := make(map[uint32]*SyncFlightInfo, 0)
   290  	blockTimeoutFlights := make(map[common.Hash][]*SyncFlightInfo, 0)
   291  	that.lock.RLock()
   292  	//
   293  	for height, flightInfo := range that.flightHeaders {
   294  		//
   295  		if int(now.Sub(flightInfo.startTime).Seconds()) >= SYNC_HEADER_REQUEST_TIMEOUT {
   296  			headerTimeoutFlights[height] = flightInfo
   297  		}
   298  	}
   299  
   300  	for blockHash, flightInfos := range that.flightBlocks {
   301  		for _, flightInfo := range flightInfos {
   302  			if int(now.Sub(flightInfo.startTime).Seconds()) >= SYNC_BLOCK_REQUEST_TIMEOUT {
   303  				blockTimeoutFlights[blockHash] = append(blockTimeoutFlights[blockHash], flightInfo)
   304  			}
   305  		}
   306  	}
   307  	that.lock.RUnlock()
   308  
   309  	curHeaderHeight := that.ledger.GetCurrentHeaderHeight( /*that.orgID*/ )
   310  	curBlockHeight := that.ledger.GetCurrentBlockHeight( /*that.orgID*/ )
   311  
   312  	//Header request processing after timeout
   313  	for height, flightInfo := range headerTimeoutFlights {
   314  		that.addTimeoutCnt(flightInfo.GetNodeId())
   315  		if height <= uint32(curHeaderHeight) {
   316  			that.delFlightHeader(height)
   317  			continue
   318  		}
   319  		flightInfo.ResetStartTime()
   320  		flightInfo.MarkFailedNode()
   321  		log.Trace("[p2p]checkTimeout org sync headers from", "id", flightInfo.GetNodeId(),
   322  			"height", height, "after", SYNC_HEADER_REQUEST_TIMEOUT, "Times", flightInfo.GetTotalFailedTimes())
   323  		reqNode := that.getNodeWithMinFailedTimes(flightInfo, uint32(curBlockHeight))
   324  		if reqNode == nil {
   325  			break
   326  		}
   327  		flightInfo.SetNodeId(reqNode.GetID())
   328  
   329  		headerHash := that.ledger.GetCurrentHeaderHash( /*that.orgID*/ )
   330  		msg := msgpack.NewHeadersReq(headerHash, that.orgID, p2pComm.SYNC_DATA_ORG)
   331  		err := that.server.Send(reqNode, msg, false)
   332  		if err != nil {
   333  			log.Warn("[p2p]checkTimeout failed to send a new headersReq", "err", err)
   334  		} else {
   335  			that.appendReqTime(reqNode.GetID())
   336  		}
   337  	}
   338  	//
   339  	for blockHash, flightInfos := range blockTimeoutFlights {
   340  		for _, flightInfo := range flightInfos {
   341  			that.addTimeoutCnt(flightInfo.GetNodeId())
   342  			if flightInfo.Height <= uint32(curBlockHeight) {
   343  				that.delFlightBlock(blockHash)
   344  				continue
   345  			}
   346  			flightInfo.ResetStartTime()
   347  			flightInfo.MarkFailedNode()
   348  			log.Trace("[p2p]checkTimeout sync", "height", flightInfo.Height, "block", blockHash, "after", SYNC_BLOCK_REQUEST_TIMEOUT, "times", flightInfo.GetTotalFailedTimes())
   349  			reqNode := that.getNodeWithMinFailedTimes(flightInfo, uint32(curBlockHeight))
   350  			if reqNode == nil {
   351  				break
   352  			}
   353  			flightInfo.SetNodeId(reqNode.GetID())
   354  
   355  			msg := msgpack.NewBlkDataReq(blockHash, that.orgID, p2pComm.SYNC_DATA_ORG)
   356  			err := that.server.Send(reqNode, msg, false)
   357  			if err != nil {
   358  				log.Warn("[p2p]checkTimeout reqNode", "ID", reqNode.GetID(), "err", err)
   359  				continue
   360  			} else {
   361  				that.appendReqTime(reqNode.GetID())
   362  			}
   363  		}
   364  	}
   365  }
   366  
   367  func (that *OrgBlockSyncMgr) sync() {
   368  	that.syncHeader()
   369  	that.syncBlock()
   370  }
   371  
   372  func (that *OrgBlockSyncMgr) reachMinConnection() bool {
   373  
   374  	minCount := p2pComm.ORG_MIN_NODE_NUM
   375  
   376  	that.lock.Lock()
   377  	defer that.lock.Unlock()
   378  
   379  	return len(that.nodeWeights) >= minCount
   380  }
   381  
   382  func (that *OrgBlockSyncMgr) syncHeader() {
   383  
   384  	if !that.reachMinConnection() {
   385  		log.Info("[OrgBlockSyncMgr] orgid:%v Wait for minimum connection", "orgID", that.orgID)
   386  		return
   387  	}
   388  
   389  	if that.tryGetSyncHeaderLock() {
   390  		return
   391  	}
   392  	defer that.releaseSyncHeaderLock()
   393  
   394  
   395  	if that.getFlightHeaderCount() >= SYNC_MAX_FLIGHT_HEADER_SIZE {
   396  		return
   397  	}
   398  	curBlockHeight := that.ledger.GetCurrentBlockHeight( /*that.orgID*/ )
   399  
   400  	curHeaderHeight := that.ledger.GetCurrentHeaderHeight( /*that.orgID*/ )
   401  	//Waiting for block catch up header
   402  	if curHeaderHeight-curBlockHeight >= SYNC_MAX_HEADER_FORWARD_SIZE {
   403  		return
   404  	}
   405  	NextHeaderId := uint32(curHeaderHeight) + 1
   406  	reqNode := that.getNextNode(NextHeaderId)
   407  	if reqNode == nil {
   408  		return
   409  	}
   410  	that.addFlightHeader(reqNode.GetID(), NextHeaderId)
   411  
   412  	headerHash := that.ledger.GetCurrentHeaderHash( /*that.orgID*/ )
   413  
   414  	testHeight := that.ledger.GetCurrentHeaderHeight()
   415  	msg := msgpack.NewHeadersReq(headerHash, that.orgID, p2pComm.SYNC_DATA_ORG, testHeight)
   416  
   417  	err := that.server.Send(reqNode, msg, false)
   418  	if err != nil {
   419  		log.Warn("[p2p]syncHeader failed to send a new headersReq")
   420  	} else {
   421  		that.appendReqTime(reqNode.GetID())
   422  	}
   423  
   424  	log.Info("sub chain--> Header sync request ", "height", NextHeaderId)
   425  }
   426  
   427  // Storage provides two interfaces, one is to take data from the database, and the other is to take data from memory.
   428  func (that *OrgBlockSyncMgr) MainGetBlockHashByHeight(nextBlockHeight uint64) common.Hash {
   429  	nextBlockHeaderHash := that.ledger.GetBlockHeaderHashByHeight(nextBlockHeight)
   430  	empty := common.Hash{}
   431  	if nextBlockHeaderHash != empty {
   432  		return nextBlockHeaderHash
   433  	}
   434  	nextBlockHash, _ := that.ledger.GetBlockHashByHeight(nextBlockHeight)
   435  	return nextBlockHash
   436  }
   437  
   438  func (that *OrgBlockSyncMgr) syncBlock() {
   439  	if that.tryGetSyncBlockLock() {
   440  		return
   441  	}
   442  	defer that.releaseSyncBlockLock()
   443  
   444  	availCount := SYNC_MAX_FLIGHT_BLOCK_SIZE - that.getFlightBlockCount()
   445  	if availCount <= 0 {
   446  		return
   447  	}
   448  	curBlockHeight := uint32(that.ledger.GetCurrentBlockHeight( /*that.orgID*/ ))
   449  	curHeaderHeight := uint32(that.ledger.GetCurrentHeaderHeight( /*that.orgID*/ ))
   450  	count := int(curHeaderHeight - curBlockHeight)
   451  	if count <= 0 {
   452  		return
   453  	}
   454  	if count > availCount {
   455  		count = availCount
   456  	}
   457  	cacheCap := SYNC_MAX_BLOCK_CACHE_SIZE - that.getBlockCacheSize()
   458  	if count > cacheCap {
   459  		count = cacheCap
   460  	}
   461  
   462  	counter := 1
   463  	i := uint32(0)
   464  	reqTimes := 1
   465  	for {
   466  		if counter > count {
   467  			break
   468  		}
   469  		i++
   470  		nextBlockHeight := curBlockHeight + i
   471  		// nextBlockHash,_ := that.ledger.GetBlockHashByHeight(uint64(nextBlockHeight)/*,that.orgID*/)
   472  		nextBlockHash := that.MainGetBlockHashByHeight(uint64(nextBlockHeight))
   473  		empty := common.Hash{}
   474  		if nextBlockHash == empty {
   475  			return
   476  		}
   477  		if that.isBlockOnFlight(nextBlockHash) {
   478  			if nextBlockHeight <= curBlockHeight+SYNC_NEXT_BLOCKS_HEIGHT {
   479  				//request more nodes for next block height
   480  				reqTimes = SYNC_NEXT_BLOCK_TIMES
   481  			} else {
   482  				continue
   483  			}
   484  		}
   485  		if that.isInBlockCache(nextBlockHeight) {
   486  			continue
   487  		}
   488  		if nextBlockHeight <= curBlockHeight+SYNC_NEXT_BLOCKS_HEIGHT {
   489  			reqTimes = SYNC_NEXT_BLOCK_TIMES
   490  		}
   491  		for t := 0; t < reqTimes; t++ {
   492  			reqNode := that.getNextNode(nextBlockHeight)
   493  			if reqNode == nil {
   494  				return
   495  			}
   496  			that.addFlightBlock(reqNode.GetID(), nextBlockHeight, nextBlockHash)
   497  			msg := msgpack.NewBlkDataReq(nextBlockHash, that.orgID, p2pComm.SYNC_DATA_ORG)
   498  			err := that.server.Send(reqNode, msg, false)
   499  			if err != nil {
   500  				log.Warn("[p2p]syncBlock ", "Height", nextBlockHeight, "ReqBlkData error", err)
   501  				return
   502  			} else {
   503  				that.appendReqTime(reqNode.GetID())
   504  			}
   505  		}
   506  		counter++
   507  		reqTimes = 1
   508  	}
   509  }
   510  
   511  //OnHeaderReceive receive header from net
   512  func (that *OrgBlockSyncMgr) OnHeaderReceive(fromID uint64, headers []*types.Header) {
   513  	if len(headers) == 0 {
   514  		return
   515  	}
   516  	log.Info("Header receive ", "height", headers[0].Height, "Height", headers[len(headers)-1].Height)
   517  	height := uint32(headers[0].Height)
   518  	curHeaderHeight := uint32(that.ledger.GetCurrentHeaderHeight( /*that.orgID*/ ))
   519  
   520  	//Means another gorountinue is adding header
   521  	if height <= curHeaderHeight {
   522  		return
   523  	}
   524  	if !that.isHeaderOnFlight(height) {
   525  		return
   526  	}
   527  	err := that.ledger.AddHeaders(headers /*,that.orgID*/)
   528  	that.delFlightHeader(height)
   529  	if err != nil {
   530  		that.addErrorRespCnt(fromID)
   531  		n := that.getNodeWeight(fromID)
   532  		if n != nil && n.GetErrorRespCnt() >= SYNC_MAX_ERROR_RESP_TIMES {
   533  			that.delNode(fromID)
   534  		}
   535  		log.Warn("[p2p]OnHeaderReceive AddHeaders ", "error", err)
   536  		return
   537  	}
   538  	that.syncHeader()
   539  }
   540  
   541  //OnBlockReceive receive block from net
   542  func (that *OrgBlockSyncMgr) OnBlockReceive(fromID uint64, blockSize uint32, block *types.Block) {
   543  	height := uint32(block.Header.Height)
   544  	blockHash := block.Hash()
   545  	log.Trace("[p2p]OnBlockReceive ", "Height", height)
   546  	that.lock.Lock()
   547  	flightInfos := that.flightBlocks[blockHash]
   548  	that.lock.Unlock()
   549  
   550  	for _, flightInfo := range flightInfos {
   551  		if flightInfo.GetNodeId() == fromID {
   552  			t := (time.Now().UnixNano() - flightInfo.GetStartTime().UnixNano()) / int64(time.Millisecond)
   553  			s := float32(blockSize) / float32(t) * 1000.0 / 1024.0
   554  			that.addNewSpeed(fromID, s)
   555  			break
   556  		}
   557  	}
   558  
   559  	that.delFlightBlock(blockHash)
   560  	curHeaderHeight := uint32(that.ledger.GetCurrentHeaderHeight( /*that.orgID*/ ))
   561  	nextHeader := curHeaderHeight + 1
   562  	if height > nextHeader {
   563  		return
   564  	}
   565  	curBlockHeight := that.ledger.GetCurrentBlockHeight( /*that.orgID*/ )
   566  	if height <= uint32(curBlockHeight) {
   567  		return
   568  	}
   569  
   570  	that.addBlockCache(fromID, block)
   571  	go that.saveBlock()
   572  	that.syncBlock()
   573  }
   574  
   575  //OnAddNode to node list when a new node added
   576  func (that *OrgBlockSyncMgr) OnAddNode(nodeId uint64) {
   577  	log.Debug("[p2p]OnAddNode", "nodeId", nodeId)
   578  	that.lock.Lock()
   579  	defer that.lock.Unlock()
   580  	if _, ok := that.nodeWeights[nodeId]; !ok {
   581  		that.server.SentConnectToBootNode(nodeId)
   582  
   583  		w := NewNodeWeight(nodeId)
   584  		that.nodeWeights[nodeId] = w
   585  		//fmt.Println(" ****** OrgBlockSyncMgr OnAddNode nodeId:", nodeId)
   586  	}
   587  }
   588  
   589  //OnDelNode remove from node list. When the node disconnect
   590  func (that *OrgBlockSyncMgr) OnDelNode(nodeId uint64) {
   591  	that.delNode(nodeId)
   592  }
   593  
   594  //delNode remove from node list
   595  
   596  func (that *OrgBlockSyncMgr) delNode(nodeId uint64) {
   597  	that.lock.Lock()
   598  	defer that.lock.Unlock()
   599  
   600  	if _, ok := that.nodeWeights[nodeId]; ok {
   601  		that.server.SentDisconnectToBootNode(nodeId, false)
   602  		remote := that.server.GetNode(nodeId)
   603  		if remote != nil {
   604  			remote.DelRemoteOrg(that.orgID)
   605  		}
   606  		log.Info(" ***** OnDelNode", "nodeId", nodeId)
   607  	}
   608  
   609  	delete(that.nodeWeights, nodeId)
   610  	log.Info("delNode", "nodeId", nodeId)
   611  	if len(that.nodeWeights) == 0 {
   612  		log.Warn("no sync nodes")
   613  	}
   614  }
   615  
   616  func (that *OrgBlockSyncMgr) tryGetSyncHeaderLock() bool {
   617  	that.lock.Lock()
   618  	defer that.lock.Unlock()
   619  	if that.syncHeaderLock {
   620  		return true
   621  	}
   622  	that.syncHeaderLock = true
   623  	return false
   624  }
   625  
   626  func (that *OrgBlockSyncMgr) releaseSyncHeaderLock() {
   627  	that.lock.Lock()
   628  	defer that.lock.Unlock()
   629  	that.syncHeaderLock = false
   630  }
   631  
   632  func (that *OrgBlockSyncMgr) tryGetSyncBlockLock() bool {
   633  	that.lock.Lock()
   634  	defer that.lock.Unlock()
   635  	if that.syncBlockLock {
   636  		return true
   637  	}
   638  	that.syncBlockLock = true
   639  	return false
   640  }
   641  
   642  func (that *OrgBlockSyncMgr) releaseSyncBlockLock() {
   643  	that.lock.Lock()
   644  	defer that.lock.Unlock()
   645  	that.syncBlockLock = false
   646  }
   647  
   648  func (that *OrgBlockSyncMgr) addBlockCache(nodeID uint64, block *types.Block) bool {
   649  	that.lock.Lock()
   650  	defer that.lock.Unlock()
   651  	blockInfo := &BlockInfo{
   652  		nodeID: nodeID,
   653  		block:  block,
   654  	}
   655  	that.blocksCache[uint32(block.Header.Height)] = blockInfo
   656  	return true
   657  }
   658  
   659  func (that *OrgBlockSyncMgr) getBlockCache(blockHeight uint32) (uint64, *types.Block) {
   660  	that.lock.RLock()
   661  	defer that.lock.RUnlock()
   662  	blockInfo, ok := that.blocksCache[blockHeight]
   663  	if !ok {
   664  		return 0, nil
   665  	}
   666  	return blockInfo.nodeID, blockInfo.block
   667  }
   668  
   669  func (that *OrgBlockSyncMgr) delBlockCache(blockHeight uint32) {
   670  	that.lock.Lock()
   671  	defer that.lock.Unlock()
   672  	delete(that.blocksCache, blockHeight)
   673  }
   674  
   675  // used
   676  func (that *OrgBlockSyncMgr) tryGetSaveBlockLock() bool {
   677  	that.lock.Lock()
   678  	defer that.lock.Unlock()
   679  	if that.saveBlockLock {
   680  		return true
   681  	}
   682  	that.saveBlockLock = true
   683  	return false
   684  }
   685  
   686  func (that *OrgBlockSyncMgr) releaseSaveBlockLock() {
   687  	that.lock.Lock()
   688  	defer that.lock.Unlock()
   689  	that.saveBlockLock = false
   690  }
   691  
   692  func (that *OrgBlockSyncMgr) saveBlock() {
   693  	// 只有这里用
   694  	if that.tryGetSaveBlockLock() {
   695  		return
   696  	}
   697  	defer that.releaseSaveBlockLock()
   698  	curBlockHeight := uint32(that.ledger.GetCurrentBlockHeight( /*that.orgID*/ ))
   699  	nextBlockHeight := curBlockHeight + 1
   700  	that.lock.Lock()
   701  	for height := range that.blocksCache {
   702  		if height <= curBlockHeight {
   703  			delete(that.blocksCache, height)
   704  		}
   705  	}
   706  	that.lock.Unlock()
   707  	for {
   708  		fromID, nextBlock := that.getBlockCache(nextBlockHeight)
   709  		if nextBlock == nil {
   710  			return
   711  		}
   712  		// err := that.ledger.AddBlock(nextBlock,that.orgID)
   713  		// swp
   714  		blkInfo, err := validation.ValidateBlock(nextBlock, that.ledger)
   715  		if err == nil {
   716  			err = that.ledger.SaveAll(blkInfo)
   717  		}
   718  
   719  		that.delBlockCache(nextBlockHeight)
   720  		if err != nil {
   721  			that.addErrorRespCnt(fromID)
   722  			n := that.getNodeWeight(fromID)
   723  			if n != nil && n.GetErrorRespCnt() >= SYNC_MAX_ERROR_RESP_TIMES {
   724  				that.delNode(fromID)
   725  			}
   726  			log.Warn("[p2p]saveBlock ", "Height", nextBlockHeight, " AddBlock error", err)
   727  			reqNode := that.getNextNode(nextBlockHeight)
   728  			if reqNode == nil {
   729  				return
   730  			}
   731  			that.addFlightBlock(reqNode.GetID(), nextBlockHeight, nextBlock.Hash())
   732  			msg := msgpack.NewBlkDataReq(nextBlock.Hash(), that.orgID, p2pComm.SYNC_DATA_ORG)
   733  			err := that.server.Send(reqNode, msg, false)
   734  			if err != nil {
   735  				log.Warn("[p2p]require new block", " error", err)
   736  				return
   737  			} else {
   738  				that.appendReqTime(reqNode.GetID())
   739  			}
   740  			return
   741  		}
   742  		nextBlockHeight++
   743  		that.pingOutsyncNodes(nextBlockHeight - 1)
   744  	}
   745  }
   746  
   747  func (that *OrgBlockSyncMgr) isInBlockCache(blockHeight uint32) bool {
   748  	that.lock.RLock()
   749  	defer that.lock.RUnlock()
   750  	_, ok := that.blocksCache[blockHeight]
   751  	return ok
   752  }
   753  
   754  func (that *OrgBlockSyncMgr) getBlockCacheSize() int {
   755  	that.lock.RLock()
   756  	defer that.lock.RUnlock()
   757  	return len(that.blocksCache)
   758  }
   759  
   760  func (that *OrgBlockSyncMgr) addFlightHeader(nodeId uint64, height uint32) {
   761  	that.lock.Lock()
   762  	defer that.lock.Unlock()
   763  	that.flightHeaders[height] = NewSyncFlightInfo(height, nodeId)
   764  }
   765  
   766  func (that *OrgBlockSyncMgr) getFlightHeader(height uint32) *SyncFlightInfo {
   767  	that.lock.RLock()
   768  	defer that.lock.RUnlock()
   769  	info, ok := that.flightHeaders[height]
   770  	if !ok {
   771  		return nil
   772  	}
   773  	return info
   774  }
   775  
   776  func (that *OrgBlockSyncMgr) delFlightHeader(height uint32) bool {
   777  	that.lock.Lock()
   778  	defer that.lock.Unlock()
   779  	_, ok := that.flightHeaders[height]
   780  	if !ok {
   781  		return false
   782  	}
   783  	delete(that.flightHeaders, height)
   784  	return true
   785  }
   786  
   787  func (that *OrgBlockSyncMgr) getFlightHeaderCount() int {
   788  	that.lock.RLock()
   789  	defer that.lock.RUnlock()
   790  	return len(that.flightHeaders)
   791  }
   792  
   793  // used
   794  func (that *OrgBlockSyncMgr) isHeaderOnFlight(height uint32) bool {
   795  	flightInfo := that.getFlightHeader(height)
   796  	return flightInfo != nil
   797  }
   798  
   799  // used
   800  func (that *OrgBlockSyncMgr) addFlightBlock(nodeId uint64, height uint32, blockHash common.Hash) {
   801  	that.lock.Lock()
   802  	defer that.lock.Unlock()
   803  	that.flightBlocks[blockHash] = append(that.flightBlocks[blockHash], NewSyncFlightInfo(height, nodeId))
   804  }
   805  
   806  // used
   807  func (that *OrgBlockSyncMgr) getFlightBlock(blockHash common.Hash) []*SyncFlightInfo {
   808  	that.lock.RLock()
   809  	defer that.lock.RUnlock()
   810  	info, ok := that.flightBlocks[blockHash]
   811  	if !ok {
   812  		return nil
   813  	}
   814  	return info
   815  }
   816  
   817  // used
   818  func (that *OrgBlockSyncMgr) delFlightBlock(blockHash common.Hash) bool {
   819  	that.lock.Lock()
   820  	defer that.lock.Unlock()
   821  	_, ok := that.flightBlocks[blockHash]
   822  	if !ok {
   823  		return false
   824  	}
   825  	delete(that.flightBlocks, blockHash)
   826  	return true
   827  }
   828  
   829  // used
   830  func (that *OrgBlockSyncMgr) getFlightBlockCount() int {
   831  	that.lock.RLock()
   832  	defer that.lock.RUnlock()
   833  	cnt := 0
   834  	for hash := range that.flightBlocks {
   835  		cnt += len(that.flightBlocks[hash])
   836  	}
   837  	return cnt
   838  }
   839  
   840  // used
   841  func (that *OrgBlockSyncMgr) isBlockOnFlight(blockHash common.Hash) bool {
   842  	flightInfos := that.getFlightBlock(blockHash)
   843  	if len(flightInfos) != 0 {
   844  		return true
   845  	}
   846  	return false
   847  }
   848  
   849  func (that *OrgBlockSyncMgr) getNextNode(nextBlockHeight uint32) *peer.Peer {
   850  	weights := that.getAllNodeWeights()
   851  	sort.Sort(sort.Reverse(weights))
   852  	nodelist := make([]uint64, 0)
   853  	for _, n := range weights {
   854  		nodelist = append(nodelist, n.id)
   855  	}
   856  	nextNodeIndex := 0
   857  	triedNode := make(map[uint64]bool, 0)
   858  	for {
   859  		var nextNodeId uint64
   860  		nextNodeIndex, nextNodeId = getNextNodeId(nextNodeIndex, nodelist)
   861  		if nextNodeId == 0 {
   862  			return nil
   863  		}
   864  		_, ok := triedNode[nextNodeId]
   865  		if ok {
   866  			return nil
   867  		}
   868  		triedNode[nextNodeId] = true
   869  		n := that.server.GetNode(nextNodeId)
   870  		if n == nil {
   871  			continue
   872  		}
   873  		if n.GetSyncState() != p2pComm.ESTABLISH {
   874  			continue
   875  		}
   876  		nodeBlockHeight := n.GetRemoteOrgHeight(that.orgID)
   877  		if nextBlockHeight <= uint32(nodeBlockHeight) {
   878  			return n
   879  		}
   880  	}
   881  }
   882  
   883  // used
   884  func (that *OrgBlockSyncMgr) getNodeWithMinFailedTimes(flightInfo *SyncFlightInfo, curBlockHeight uint32) *peer.Peer {
   885  	var minFailedTimes = math.MaxInt64
   886  	var minFailedTimesNode *peer.Peer
   887  	triedNode := make(map[uint64]bool, 0)
   888  	for {
   889  		nextNode := that.getNextNode(curBlockHeight + 1)
   890  		if nextNode == nil {
   891  			return nil
   892  		}
   893  		failedTimes := flightInfo.GetFailedTimes(nextNode.GetID())
   894  		if failedTimes == 0 {
   895  			return nextNode
   896  		}
   897  		_, ok := triedNode[nextNode.GetID()]
   898  		if ok {
   899  			return minFailedTimesNode
   900  		}
   901  		triedNode[nextNode.GetID()] = true
   902  		if failedTimes < minFailedTimes {
   903  			minFailedTimes = failedTimes
   904  			minFailedTimesNode = nextNode
   905  		}
   906  	}
   907  }
   908  
   909  //Stop to sync
   910  func (that *OrgBlockSyncMgr) Close() {
   911  	close(that.exitCh)
   912  }
   913  
   914  //getNodeWeight get nodeweight by id // used
   915  func (that *OrgBlockSyncMgr) getNodeWeight(nodeId uint64) *NodeWeight {
   916  	that.lock.RLock()
   917  	defer that.lock.RUnlock()
   918  	return that.nodeWeights[nodeId]
   919  }
   920  
   921  //getAllNodeWeights get all nodeweight and return a slice
   922  func (that *OrgBlockSyncMgr) getAllNodeWeights() NodeWeights {
   923  	that.lock.RLock()
   924  	defer that.lock.RUnlock()
   925  	weights := make(NodeWeights, 0, len(that.nodeWeights))
   926  	for _, w := range that.nodeWeights {
   927  		weights = append(weights, w)
   928  	}
   929  	return weights
   930  }
   931  
   932  //addTimeoutCnt incre a node's timeout count // used
   933  func (that *OrgBlockSyncMgr) addTimeoutCnt(nodeId uint64) {
   934  	n := that.getNodeWeight(nodeId)
   935  	if n != nil {
   936  		n.AddTimeoutCnt()
   937  	}
   938  }
   939  
   940  //addErrorRespCnt incre a node's error resp count // used
   941  func (that *OrgBlockSyncMgr) addErrorRespCnt(nodeId uint64) {
   942  	n := that.getNodeWeight(nodeId)
   943  	if n != nil {
   944  		n.AddErrorRespCnt()
   945  	}
   946  }
   947  
   948  //appendReqTime append a node's request time // used
   949  func (that *OrgBlockSyncMgr) appendReqTime(nodeId uint64) {
   950  	n := that.getNodeWeight(nodeId)
   951  	if n != nil {
   952  		n.AppendNewReqtime()
   953  	}
   954  }
   955  
   956  //addNewSpeed apend the new speed to tail, remove the oldest one
   957  func (that *OrgBlockSyncMgr) addNewSpeed(nodeId uint64, speed float32) {
   958  	n := that.getNodeWeight(nodeId)
   959  	if n != nil {
   960  		n.AppendNewSpeed(speed)
   961  	}
   962  }
   963  
   964  //pingOutsyncNodes send ping msg to lower height nodes for syncing
   965  func (that *OrgBlockSyncMgr) pingOutsyncNodes(curHeight uint32) {
   966  	peers := make([]*peer.Peer, 0)
   967  	that.lock.RLock()
   968  	maxHeight := curHeight
   969  	for id := range that.nodeWeights {
   970  		peer := that.server.GetNode(id)
   971  		if peer == nil {
   972  			continue
   973  		}
   974  		peerHeight := uint32(peer.GetRemoteOrgHeight(that.orgID))
   975  		if peerHeight >= maxHeight {
   976  			maxHeight = peerHeight
   977  		}
   978  		if peerHeight < curHeight {
   979  			peers = append(peers, peer)
   980  		}
   981  	}
   982  	that.lock.RUnlock()
   983  	if curHeight > maxHeight-SYNC_MAX_HEIGHT_OFFSET && len(peers) > 0 {
   984  		that.server.PingTo(peers, false, that.orgID)
   985  	}
   986  }
   987  
   988  //Using polling for load balance
   989  func getNextNodeId(nextNodeIndex int, nodeList []uint64) (int, uint64) {
   990  	num := len(nodeList)
   991  	if num == 0 {
   992  		return 0, 0
   993  	}
   994  	if nextNodeIndex >= num {
   995  		nextNodeIndex = 0
   996  	}
   997  	index := nextNodeIndex
   998  	nextNodeIndex++
   999  	return nextNodeIndex, nodeList[index]
  1000  }