github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/p2pserver/p2pserver.go (about) 1 package p2pserver 2 3 import ( 4 "crypto/ecdsa" 5 //"fmt" 6 7 // "encoding/json" 8 "errors" 9 // "io/ioutil" 10 "math/rand" 11 "net" 12 13 // "os" 14 "reflect" 15 "strconv" 16 17 // "strings" 18 "sync" 19 "time" 20 21 evtActor "github.com/ontio/ontology-eventbus/actor" 22 comm "github.com/sixexorg/magnetic-ring/common" 23 "github.com/sixexorg/magnetic-ring/config" 24 "github.com/sixexorg/magnetic-ring/core/mainchain/types" 25 "github.com/sixexorg/magnetic-ring/log" 26 ledger "github.com/sixexorg/magnetic-ring/store/mainchain/storages" 27 28 // orgtypes "github.com/sixexorg/magnetic-ring/core/orgchain/types" 29 "github.com/ethereum/go-ethereum/crypto" 30 "github.com/sixexorg/magnetic-ring/p2pserver/common" 31 msgpack "github.com/sixexorg/magnetic-ring/p2pserver/message" 32 "github.com/sixexorg/magnetic-ring/p2pserver/net/netserver" 33 p2pnet "github.com/sixexorg/magnetic-ring/p2pserver/net/protocol" 34 "github.com/sixexorg/magnetic-ring/p2pserver/peer" 35 utils "github.com/sixexorg/magnetic-ring/p2pserver/sync" 36 37 // table 38 "github.com/sixexorg/magnetic-ring/p2pserver/discover" 39 "github.com/sixexorg/magnetic-ring/p2pserver/spcnode" 40 41 // org 42 43 "fmt" 44 45 mainsync "github.com/sixexorg/magnetic-ring/p2pserver/sync/main" 46 "github.com/sixexorg/magnetic-ring/p2pserver/temp" 47 ) 48 49 type recentData struct { 50 addr string 51 nodestr string 52 } 53 54 //P2PServer control all network activities 55 type P2PServer struct { 56 network p2pnet.P2P 57 msgRouter *utils.MessageRouter 58 pid *evtActor.PID 59 blockSync *mainsync.BlockSyncMgr 60 ledger *ledger.LedgerStoreImp 61 ReconnectAddrs 62 quitSyncRecent chan bool 63 quitOnline chan bool 64 quitHeartBeat chan bool 65 quitCheckConn chan bool 66 // table 67 ntab *discover.Table 68 bootnodes []*discover.Node 69 nodeKey *ecdsa.PrivateKey 70 // org 71 orgman *OrgMan 72 nodeA *spcnode.NodeA 73 nodeStar *spcnode.NodeStar 74 } 75 76 type retryPeerInfo struct { 77 num int 78 nodestr string 79 } 80 81 //ReconnectAddrs contain addr need to reconnect 82 type ReconnectAddrs struct { 83 sync.RWMutex 84 RetryAddrs map[string]*retryPeerInfo 85 } 86 87 //NewServer return a new p2pserver according to the pubkey 88 func NewServer() *P2PServer { 89 common.InitP2PVariable() 90 91 p := &P2PServer{} 92 n := netserver.NewNetServer(p) 93 94 p.network = n 95 p.ledger = ledger.GetLedgerStore() 96 97 p.msgRouter = utils.NewMsgRouter(p.network) 98 p.blockSync = mainsync.NewBlockSyncMgr(p) 99 p.quitSyncRecent = make(chan bool) 100 p.quitOnline = make(chan bool) 101 p.quitHeartBeat = make(chan bool) 102 p.quitCheckConn = make(chan bool) 103 p.orgman = NewAddOrg() 104 p.nodeA = spcnode.NewNodeA(p) 105 p.nodeStar = spcnode.NewNodeStar(p) 106 return p 107 } 108 109 //GetConnectionCnt return the established connect count 110 func (this *P2PServer) GetLedger() *ledger.LedgerStoreImp { 111 return this.ledger 112 } 113 114 //GetConnectionCnt return the established connect count 115 func (this *P2PServer) GetConnectionCnt() uint32 { 116 return this.network.GetConnectionCnt() 117 } 118 119 func (this *P2PServer) genPrikey() error { 120 var ( 121 nodeKey *ecdsa.PrivateKey 122 err error 123 ) 124 nodeKey, err = crypto.GenerateKey() 125 if err != nil { 126 return err 127 } 128 this.nodeKey = nodeKey 129 130 portstr := strconv.Itoa(int(config.GlobalConfig.P2PCfg.NodePort)) 131 ntab, err := discover.ListenUDP(this.nodeKey, "0.0.0.0:"+portstr, nil, "", nil, 132 this.TabCallPeerConnectInfo, this.TabCallPeerOrgInfo, this.TabCallSendConnectOrg, false, comm.Address{}) 133 if err != nil { 134 return err 135 } 136 137 this.ntab = ntab 138 this.bootnodes = make([]*discover.Node, 0) 139 // gen bootnode 140 for _, nodestr := range common.BootNodes { 141 node, err := discover.ParseNode(nodestr) 142 if err != nil { 143 return err 144 } 145 this.bootnodes = append(this.bootnodes, node) 146 } 147 148 if err := ntab.SetFallbackNodes(this.bootnodes); err != nil { 149 return err 150 } 151 // deliver prvikey to network 152 this.network.SetPrivateKey(this.nodeKey, this.ntab) 153 this.network.SetBootNodes(this.bootnodes) 154 155 return nil 156 } 157 158 //Start create all services 159 func (this *P2PServer) Start() error { 160 if this.genPrikey() != nil { 161 return errors.New("[p2p]genPrikey invalid") 162 } 163 164 if this.network == nil { 165 return errors.New("[p2p]network invalid") 166 } 167 168 this.network.Start() 169 170 if this.msgRouter == nil { 171 return errors.New("[p2p]msg router invalid") 172 } 173 174 this.msgRouter.Start() 175 176 go this.connectSeedService() 177 go this.keepOnlineService() 178 go this.heartBeatService() 179 go this.blockSync.Start() 180 // NodeA 181 this.nodeA.Start() 182 // NodeStar 183 this.nodeStar.Start() 184 // for test 185 // go this.testOrg() 186 return nil 187 } 188 189 //Stop halt all service by send signal to channels 190 func (this *P2PServer) Stop() { 191 this.network.Halt() 192 this.quitSyncRecent <- true 193 this.quitOnline <- true 194 this.quitHeartBeat <- true 195 this.quitCheckConn <- true 196 this.msgRouter.Stop() 197 this.blockSync.Close() 198 this.nodeA.Close() 199 this.nodeStar.Close() 200 201 this.orgman.RLock() 202 for _, orgsync := range this.orgman.OrgSync { 203 orgsync.Close() 204 } 205 this.orgman.Reset() 206 this.orgman.RUnlock() 207 } 208 209 // GetNetWork returns the low level netserver 210 func (this *P2PServer) GetNetWork() p2pnet.P2P { 211 return this.network 212 } 213 214 //GetPort return two network port 215 func (this *P2PServer) GetPort() (uint16, uint16) { 216 return this.network.GetSyncPort(), this.network.GetConsPort() 217 } 218 219 //GetVersion return self version 220 func (this *P2PServer) GetVersion() uint32 { 221 return this.network.GetVersion() 222 } 223 224 //GetNeighborAddrs return all nbr`s address 225 func (this *P2PServer) GetNeighborAddrs() []common.PeerAddr { 226 return this.network.GetNeighborAddrs() 227 } 228 229 //Xmit called by other module to broadcast msg 230 func (this *P2PServer) Xmit(message interface{}) error { 231 log.Debug("[p2p] Xmit Start...") 232 var msg common.Message 233 isConsensus := false 234 switch message.(type) { 235 case *types.Transaction: // 236 log.Debug("[p2p]TX transaction message ••••••••••••••••") 237 txn := message.(*types.Transaction) 238 msg = msgpack.NewTxn(txn, nil, comm.Address{}, common.SYNC_DATA_MAIN) 239 240 241 case *common.OrgTx: // 242 log.Debug("[p2p]TX transaction message") 243 orgtx := message.(*common.OrgTx) 244 txn := orgtx.Tx 245 msg = msgpack.NewTxn(nil, txn, comm.Address{}, common.SYNC_DATA_ORG) 246 247 case *types.Block: // sync bblock // 248 log.Debug("[p2p]TX block message") 249 block := message.(*types.Block) 250 msg = msgpack.NewBlock(block, nil, comm.Address{}, common.SYNC_DATA_MAIN) 251 case *common.ConsensusPayload: 252 log.Debug("[p2p]TX consensus message") 253 consensusPayload := message.(*common.ConsensusPayload) 254 msg = msgpack.NewConsensus(consensusPayload) 255 isConsensus = true 256 257 case *common.NotifyBlk: 258 //return nil 259 blkntf := message.(*common.NotifyBlk) 260 //time.Sleep(time.Millisecond*500) 261 262 log.Info("[p2p]TX block hash message unique", "hash", blkntf) 263 264 // construct inv message 265 invPayload := msgpack.NewInvPayload(comm.BLOCK, []comm.Hash{blkntf.BlkHash}, []uint64{blkntf.BlkHeight}) 266 267 msg = msgpack.NewInv(invPayload) 268 case *common.EarthNotifyBlk: 269 ntf := message.(*common.EarthNotifyBlk) 270 271 msg = msgpack.NewEarthNotifyHash(ntf) 272 case *comm.NodeLH: 273 fmt.Println("🌐 📩 p2p receive nodeLH") 274 nodeLH := message.(*comm.NodeLH) 275 msg = msgpack.NewNodeLHMsg(nodeLH) 276 case *common.ExtDataRequest: 277 fmt.Println("🌐 📩 p2p extData requtst") 278 extData := message.(*common.ExtDataRequest) 279 msg = msgpack.NewExtDataRequestMsg(extData) 280 default: 281 log.Info("[p2p]Unknown Xmit ", "message", message, "type", reflect.TypeOf(message)) 282 return errors.New("[p2p]Unknown Xmit message type") 283 } 284 this.network.Xmit(msg, isConsensus) 285 return nil 286 } 287 288 //Send tranfer buffer to peer 289 func (this *P2PServer) Send(p *peer.Peer, msg common.Message, 290 isConsensus bool) error { 291 if this.network.IsPeerEstablished(p) { 292 return this.network.Send(p, msg, isConsensus) 293 } 294 log.Warn("[p2p]send to a not ESTABLISH ", "peerid", p.GetID()) 295 return errors.New("[p2p]send to a not ESTABLISH peer") 296 } 297 298 // GetID returns local node id 299 func (this *P2PServer) GetID() uint64 { 300 return this.network.GetID() 301 } 302 303 // OnAddNode adds the peer id to the block sync mgr 304 func (this *P2PServer) SetSyncStatus(status bool,lockHeight uint64) { 305 this.blockSync.SetSyncStatus(status,lockHeight) 306 } 307 308 // OnAddNode adds the peer id to the block sync mgr 309 func (this *P2PServer) OnAddNode(id uint64) { 310 this.blockSync.OnAddNode(id) 311 } 312 313 // OnDelNode removes the peer id from the block sync mgr 314 func (this *P2PServer) OnDelNode(id uint64) { 315 this.blockSync.OnDelNode(id) 316 } 317 318 // OnHeaderReceive adds the header list from network 319 func (this *P2PServer) OnHeaderReceive(fromID uint64, headers []*types.Header) { 320 this.blockSync.OnHeaderReceive(fromID, headers) 321 } 322 323 // OnBlockReceive adds the block from network 324 func (this *P2PServer) OnBlockReceive(fromID uint64, blockSize uint32, block *types.Block) { 325 this.blockSync.OnBlockReceive(fromID, blockSize, block) 326 } 327 328 // Todo: remove it if no use 329 func (this *P2PServer) GetConnectionState() uint32 { 330 return common.INIT 331 } 332 333 //GetTime return lastet contact time 334 func (this *P2PServer) GetTime() int64 { 335 return this.network.GetTime() 336 } 337 338 // SetPID sets p2p actor 339 func (this *P2PServer) SetPID(pid *evtActor.PID) { 340 this.pid = pid 341 this.msgRouter.SetPID(pid) 342 } 343 344 // GetPID returns p2p actor 345 func (this *P2PServer) GetPID() *evtActor.PID { 346 return this.pid 347 } 348 349 //blockSyncFinished compare all nbr peers and self height at beginning 350 func (this *P2PServer) blockSyncFinished() bool { 351 peers := this.network.GetNeighbors() 352 if len(peers) == 0 { 353 return false 354 } 355 356 blockHeight := this.ledger.GetCurrentBlockHeight() 357 358 for _, v := range peers { 359 if blockHeight < v.GetHeight() { 360 return false 361 } 362 } 363 return true 364 } 365 366 //WaitForSyncBlkFinish compare the height of self and remote peer in loop 367 func (this *P2PServer) WaitForSyncBlkFinish() { 368 for { 369 headerHeight := this.ledger.GetCurrentHeaderHeight() 370 currentBlkHeight := this.ledger.GetCurrentBlockHeight() 371 log.Info("[p2p]WaitForSyncBlkFinish... current block height is ", "currentBlkHeight", 372 currentBlkHeight, " ,current header height is ", headerHeight) 373 374 if this.blockSyncFinished() { 375 break 376 } 377 378 <-time.After(time.Second * (time.Duration(common.SYNC_BLK_WAIT))) 379 } 380 } 381 382 //WaitForPeersStart check whether enough peer linked in loop 383 func (this *P2PServer) WaitForPeersStart() { 384 periodTime := common.DEFAULT_GEN_BLOCK_TIME / common.UPDATE_RATE_PER_BLOCK 385 for { 386 log.Info("[p2p]Wait for minimum connection...") 387 if this.ReachMinConnection() { 388 break 389 } 390 391 <-time.After(time.Second * (time.Duration(periodTime))) 392 } 393 } 394 395 func (this *P2PServer) getRandList() map[string]*discover.Node { 396 nodes := make([]*discover.Node, 5) 397 num := this.ntab.ReadRandomNodes(nodes) 398 lennode := len(nodes) 399 seedNodes := make(map[string]*discover.Node) 400 401 bootmap := make(map[discover.NodeID]bool) 402 for _, node := range this.bootnodes { 403 bootmap[node.ID] = true 404 } 405 406 for i := 0; i < num && i < lennode; i++ { 407 if nodes[i] == nil { 408 continue 409 } 410 if ok := bootmap[nodes[i].ID]; !ok { 411 addr := &net.TCPAddr{IP: nodes[i].IP, Port: int(nodes[i].TCP)} 412 seedNodes[addr.String()] = nodes[i] 413 } 414 } 415 return seedNodes 416 } 417 418 //connectSeeds connect the seeds in seedlist and call for nbr list 419 func (this *P2PServer) connectSeeds() { 420 seedNodes := make(map[string]*discover.Node) 421 pList := make([]*peer.Peer, 0) 422 423 seedNodes = this.getRandList() 424 425 for nodeAddr, _ := range seedNodes { 426 var ip net.IP 427 np := this.network.GetNp() 428 np.Lock() 429 for _, tn := range np.List { 430 ipAddr, _ := tn.GetAddr16() 431 ip = ipAddr[:] 432 addrString := ip.To16().String() + ":" + 433 strconv.Itoa(int(tn.GetSyncPort())) 434 if nodeAddr == addrString && tn.GetSyncState() == common.ESTABLISH { 435 pList = append(pList, tn) 436 } 437 } 438 np.Unlock() 439 } 440 if len(pList) > 0 { 441 rand.Seed(time.Now().UnixNano()) 442 index := rand.Intn(len(pList)) 443 this.reqNbrList(pList[index]) 444 } else { //not found 445 for nodeAddr, node := range seedNodes { 446 go this.network.Connect(nodeAddr, false, node, false) 447 } 448 } 449 } 450 451 //reachMinConnection return whether net layer have enough link under different config 452 func (this *P2PServer) ReachMinConnection() bool { 453 // consensusType := strings.ToLower(config.DefConfig.Genesis.ConsensusType) 454 // if consensusType == "" { 455 // consensusType = "dbft" 456 // } 457 // minCount := config.DBFT_MIN_NODE_NUM 458 // switch consensusType { 459 // case "dbft": 460 // case "solo": 461 // minCount = config.SOLO_MIN_NODE_NUM 462 // case "vbft": 463 // minCount = config.VBFT_MIN_NODE_NUM 464 465 // } 466 // for test 467 minCount := 2 468 return int(this.GetConnectionCnt())+1 >= minCount 469 } 470 471 //getNode returns the peer with the id 472 func (this *P2PServer) GetNode(id uint64) *peer.Peer { 473 return this.network.GetPeer(id) 474 } 475 476 //getNode returns the peer with the id 477 func (this *P2PServer) GetNodeFromDiscoverID(discoverNodeID string) *peer.Peer { 478 return this.network.GetNp().GetPeerFromDiscoverNodeId(discoverNodeID) 479 } 480 481 //retryInactivePeer try to connect peer in INACTIVITY state 482 func (this *P2PServer) retryInactivePeer() { 483 np := this.network.GetNp() 484 np.Lock() 485 var ip net.IP 486 neighborPeers := make(map[uint64]*peer.Peer) 487 for _, p := range np.List { 488 addr, _ := p.GetAddr16() 489 ip = addr[:] 490 nodeAddr := ip.To16().String() + ":" + 491 strconv.Itoa(int(p.GetSyncPort())) 492 if p.GetSyncState() == common.INACTIVITY { 493 log.Debug("[p2p] try reconnect", "nodeAddr", nodeAddr) 494 //add addr to retry list 495 this.addToRetryList(nodeAddr, p.GetNode()) 496 p.CloseSync() 497 p.CloseCons() 498 } else { 499 //add others to tmp node map 500 this.removeFromRetryList(nodeAddr) 501 neighborPeers[p.GetID()] = p 502 } 503 } 504 505 np.List = neighborPeers 506 np.Unlock() 507 508 connCount := uint(this.network.GetOutConnRecordLen()) 509 if connCount >= config.GlobalConfig.P2PCfg.MaxConnOutBound { 510 log.Warn("[p2p]Connect: out connections", "connCount", connCount, 511 "reach the max limit", config.GlobalConfig.P2PCfg.MaxConnOutBound) 512 return 513 } 514 515 //try connect 516 if len(this.RetryAddrs) > 0 { 517 this.ReconnectAddrs.Lock() 518 519 list := make(map[string]*retryPeerInfo) 520 addrs := make([]string, 0, len(this.RetryAddrs)) 521 nodestr := make([]string, 0, len(this.RetryAddrs)) 522 for addr, v := range this.RetryAddrs { 523 v.num += 1 524 addrs = append(addrs, addr) 525 nodestr = append(nodestr, v.nodestr) 526 if v.num < common.MAX_RETRY_COUNT { 527 list[addr] = v 528 } 529 if v.num >= common.MAX_RETRY_COUNT { 530 this.network.RemoveFromConnectingList(addr) 531 remotePeer := this.network.GetPeerFromAddr(addr) 532 if remotePeer != nil { 533 if remotePeer.SyncLink.GetAddr() == addr { 534 this.network.RemovePeerSyncAddress(addr) 535 this.network.RemovePeerConsAddress(addr) 536 } 537 if remotePeer.ConsLink.GetAddr() == addr { 538 this.network.RemovePeerConsAddress(addr) 539 } 540 this.network.DelNbrNode(remotePeer.GetID()) 541 } 542 } 543 } 544 545 this.RetryAddrs = list 546 this.ReconnectAddrs.Unlock() 547 for index, addr := range addrs { 548 rand.Seed(time.Now().UnixNano()) 549 log.Debug("[p2p]Try to reconnect peer, peer addr is ", "addr", addr) 550 <-time.After(time.Duration(rand.Intn(common.CONN_MAX_BACK)) * time.Millisecond) 551 log.Debug("[p2p]Back off time`s up, start connect node") 552 if index < len(nodestr) && index >= 0 { 553 temnode, err := discover.ParseNode(nodestr[index]) 554 if err != nil { 555 continue 556 } 557 this.network.Connect(addr, false, temnode, false) 558 } 559 } 560 561 } 562 } 563 564 //connectSeedService make sure seed peer be connected 565 func (this *P2PServer) connectSeedService() { 566 t := time.NewTimer(time.Second * common.CONN_MONITOR) 567 for { 568 select { 569 case <-t.C: 570 this.connectSeeds() 571 t.Stop() 572 if this.ReachMinConnection() { 573 t.Reset(time.Second * time.Duration(10*common.CONN_MONITOR)) 574 } else { 575 t.Reset(time.Second * common.CONN_MONITOR) 576 } 577 case <-this.quitOnline: 578 t.Stop() 579 break 580 } 581 } 582 } 583 584 //keepOnline try connect lost peer 585 func (this *P2PServer) keepOnlineService() { 586 t := time.NewTimer(time.Second * common.CONN_MONITOR) 587 for { 588 select { 589 case <-t.C: 590 this.retryInactivePeer() 591 t.Stop() 592 t.Reset(time.Second * common.CONN_MONITOR) 593 case <-this.quitOnline: 594 t.Stop() 595 break 596 } 597 } 598 } 599 600 //reqNbrList ask the peer for its neighbor list 601 func (this *P2PServer) reqNbrList(p *peer.Peer) { 602 msg := msgpack.NewAddrReq() 603 go this.Send(p, msg, false) 604 } 605 606 //heartBeat send ping to nbr peers and check the timeout 607 func (this *P2PServer) heartBeatService() { 608 var periodTime uint 609 periodTime = common.DEFAULT_GEN_BLOCK_TIME / common.UPDATE_RATE_PER_BLOCK 610 t := time.NewTicker(time.Second * (time.Duration(periodTime))) 611 612 for { 613 select { 614 case <-t.C: 615 this.ping() 616 this.timeout() 617 case <-this.quitHeartBeat: 618 t.Stop() 619 break 620 } 621 } 622 } 623 624 //ping send pkg to get pong msg from others 625 func (this *P2PServer) ping() { 626 627 peers := this.network.GetNeighbors() 628 fmt.Println("==========>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", time.Now().String(), "len(peers):",len(peers)) 629 this.PingTo(peers, true) 630 } 631 632 // pings send pkgs to get pong msg from others 633 // add org and StellarNode need call this func 634 func (this *P2PServer) PingTo(peers []*peer.Peer, bTimer bool, orgID ...comm.Address) { 635 for _, p := range peers { 636 fmt.Println("P2PServerPingTo out", "time", time.Now().String(), "GetSyncState", p.GetSyncState()) 637 log.Info("P2PServerPingTo out", "time", time.Now().String(), "GetSyncState", p.GetSyncState()) 638 if p.GetSyncState() == common.ESTABLISH { 639 if bTimer { 640 height := this.ledger.GetCurrentBlockHeight() 641 // 642 orgs := this.network.PeerGetOrg() 643 orgpings := this.getOrgInfo(orgs) 644 ping := msgpack.NewPingMsg(uint64(height), orgpings, common.PING_INFO_ALL) 645 log.Info("P2PServerPingTo", "height", height, "time", time.Now().String()) 646 go this.Send(p, ping, false) 647 } else { 648 if len(orgID) <= 0 { // main 649 height := this.ledger.GetCurrentBlockHeight() 650 ping := msgpack.NewPingMsg(uint64(height), nil, common.PING_INFO_MAIN) 651 go this.Send(p, ping, false) 652 } else { 653 orgs := []comm.Address{orgID[0]} 654 orgpings := this.getOrgInfo(orgs) 655 ping := msgpack.NewPingMsg(uint64(0), orgpings, common.PING_INFO_ORG) 656 go this.Send(p, ping, false) 657 } 658 } 659 } 660 } 661 } 662 663 func (this *P2PServer) getOrgInfo(orgIDArr []comm.Address) []*common.OrgPIPOInfo { 664 result := make([]*common.OrgPIPOInfo, 0) 665 for _, id := range orgIDArr { 666 if id == common.StellarNodeID { // 667 result = append(result, msgpack.NewOrgPIPOMsg(id, uint64(0))) 668 } else { 669 // SFC, 670 //height := this.ledger.GetCurrentBlockHeight(/*id*/) 671 orgLedger := temp.GetLedger(id) 672 if orgLedger == nil { 673 continue 674 } 675 height := orgLedger.GetCurrentBlockHeight( /*id*/ ) 676 result = append(result, msgpack.NewOrgPIPOMsg(id, uint64(height))) 677 } 678 } 679 return result 680 } 681 682 //timeout trace whether some peer be long time no response 683 func (this *P2PServer) timeout() { 684 peers := this.network.GetNeighbors() 685 var periodTime uint 686 periodTime = common.DEFAULT_GEN_BLOCK_TIME / common.UPDATE_RATE_PER_BLOCK 687 for _, p := range peers { 688 if p.GetSyncState() == common.ESTABLISH { 689 t := p.GetContactTime() 690 if t.Before(time.Now().Add(-1 * time.Second * 691 time.Duration(periodTime) * common.KEEPALIVE_TIMEOUT)) { 692 log.Warn("[p2p]keep alive timeout!!!lost remote", "peer", p.GetID(), "Addr", p.SyncLink.GetAddr(), "Addr", t.String()) 693 p.CloseSync() 694 p.CloseCons() 695 } 696 } 697 } 698 } 699 700 //addToRetryList add retry address to ReconnectAddrs 701 func (this *P2PServer) addToRetryList(addr string, node *discover.Node) { 702 this.ReconnectAddrs.Lock() 703 defer this.ReconnectAddrs.Unlock() 704 if this.RetryAddrs == nil { 705 this.RetryAddrs = make(map[string]*retryPeerInfo) 706 } 707 if _, ok := this.RetryAddrs[addr]; ok { 708 delete(this.RetryAddrs, addr) 709 } 710 //alway set retry to 0 711 this.RetryAddrs[addr] = &retryPeerInfo{ 712 num: 0, 713 nodestr: node.String(), 714 } 715 } 716 717 //removeFromRetryList remove connected address from ReconnectAddrs 718 func (this *P2PServer) removeFromRetryList(addr string) { 719 this.ReconnectAddrs.Lock() 720 defer this.ReconnectAddrs.Unlock() 721 if len(this.RetryAddrs) > 0 { 722 if _, ok := this.RetryAddrs[addr]; ok { 723 delete(this.RetryAddrs, addr) 724 } 725 } 726 }