github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/p2pserver/peer/peer.go (about) 1 package peer 2 3 import ( 4 "errors" 5 "net" 6 "runtime" 7 "sync" 8 "sync/atomic" 9 "time" 10 11 comm "github.com/sixexorg/magnetic-ring/common" 12 "github.com/sixexorg/magnetic-ring/log" 13 "github.com/sixexorg/magnetic-ring/p2pserver/common" 14 "github.com/sixexorg/magnetic-ring/p2pserver/discover" 15 "github.com/sixexorg/magnetic-ring/p2pserver/sync/conn" 16 ) 17 18 // PeerCom provides the basic information of a peer 19 type PeerCom struct { 20 id uint64 21 version uint32 22 services uint64 23 relay bool 24 httpInfoPort uint16 25 syncPort uint16 26 consPort uint16 27 height uint64 28 orgheight map[comm.Address]uint64 // org info 29 syncorg sync.RWMutex 30 } 31 32 // SetID sets a peer's id 33 func (this *PeerCom) SetID(id uint64) { 34 this.id = id 35 } 36 37 // GetID returns a peer's id 38 func (this *PeerCom) GetID() uint64 { 39 return this.id 40 } 41 42 // SetVersion sets a peer's version 43 func (this *PeerCom) SetVersion(version uint32) { 44 this.version = version 45 } 46 47 // GetVersion returns a peer's version 48 func (this *PeerCom) GetVersion() uint32 { 49 return this.version 50 } 51 52 // SetServices sets a peer's services 53 func (this *PeerCom) SetServices(services uint64) { 54 this.services = services 55 } 56 57 // GetServices returns a peer's services 58 func (this *PeerCom) GetServices() uint64 { 59 return this.services 60 } 61 62 // SerRelay sets a peer's relay 63 func (this *PeerCom) SetRelay(relay bool) { 64 this.relay = relay 65 } 66 67 // GetRelay returns a peer's relay 68 func (this *PeerCom) GetRelay() bool { 69 return this.relay 70 } 71 72 // SetSyncPort sets a peer's sync port 73 func (this *PeerCom) SetSyncPort(port uint16) { 74 this.syncPort = port 75 } 76 77 // GetSyncPort returns a peer's sync port 78 func (this *PeerCom) GetSyncPort() uint16 { 79 return this.syncPort 80 } 81 82 // SetConsPort sets a peer's consensus port 83 func (this *PeerCom) SetConsPort(port uint16) { 84 this.consPort = port 85 } 86 87 // GetConsPort returns a peer's consensus port 88 func (this *PeerCom) GetConsPort() uint16 { 89 return this.consPort 90 } 91 92 // SetHttpInfoPort sets a peer's http info port 93 func (this *PeerCom) SetHttpInfoPort(port uint16) { 94 this.httpInfoPort = port 95 } 96 97 // GetHttpInfoPort returns a peer's http info port 98 func (this *PeerCom) GetHttpInfoPort() uint16 { 99 return this.httpInfoPort 100 } 101 102 // SetHeight sets a peer's height 103 func (this *PeerCom) SetHeight(height uint64) { 104 this.height = height 105 } 106 107 // GetHeight returns a peer's height 108 func (this *PeerCom) GetHeight() uint64 { 109 return this.height 110 } 111 112 // p2pserver call the PeerAddOrg fuc ownnode 113 func (this *PeerCom) PeerAddOrg(id comm.Address) { 114 this.syncorg.Lock() 115 defer this.syncorg.Unlock() 116 if this.orgheight == nil { 117 this.orgheight = make(map[comm.Address]uint64) 118 } 119 120 this.orgheight[id] = 0 121 } 122 123 // p2pserver call the PeerDelOrg fuc ownnode 124 func (this *PeerCom) PeerDelOrg(id comm.Address) { 125 this.syncorg.Lock() 126 defer this.syncorg.Unlock() 127 if this.orgheight == nil { 128 this.orgheight = make(map[comm.Address]uint64) 129 } 130 131 delete(this.orgheight, id) 132 if len(this.orgheight) == 0 { 133 this.orgheight = make(map[comm.Address]uint64) 134 } 135 } 136 137 // p2pserver call the PeerGetOrg fuc ownnode 138 func (this *PeerCom) PeerGetOrg() []comm.Address { 139 this.syncorg.Lock() 140 defer this.syncorg.Unlock() 141 if this.orgheight == nil { 142 this.orgheight = make(map[comm.Address]uint64) 143 } 144 result := make([]comm.Address, 0) 145 for id, _ := range this.orgheight { 146 result = append(result, id) 147 } 148 149 return result 150 } 151 152 func (this *PeerCom) PeerGetRealOrg() []comm.Address { 153 this.syncorg.Lock() 154 defer this.syncorg.Unlock() 155 if this.orgheight == nil { 156 this.orgheight = make(map[comm.Address]uint64) 157 } 158 result := make([]comm.Address, 0) 159 for id, _ := range this.orgheight { 160 161 if !id.Equals(common.StellarNodeID) { 162 result = append(result, id) 163 } 164 } 165 166 return result 167 } 168 169 // SetOrgHeight sets a org peer's height : ownnode 170 func (this *PeerCom) SetOwnOrgHeight(height uint64, id comm.Address) { 171 this.syncorg.Lock() 172 defer this.syncorg.Unlock() 173 if this.orgheight == nil { 174 this.orgheight = make(map[comm.Address]uint64) 175 } 176 177 this.orgheight[id] = height 178 } 179 180 // GetOwnOrgHeight returns a own org peer's height : ownnode 181 func (this *PeerCom) GetOwnOrgHeight(id comm.Address) uint64 { 182 this.syncorg.Lock() 183 defer this.syncorg.Unlock() 184 if this.orgheight == nil { 185 this.orgheight = make(map[comm.Address]uint64) 186 } 187 188 return this.orgheight[id] 189 } 190 191 // Remote peer handler 192 193 // SetRemoteOrgHeight sets a org peer's height : remotenode 194 func (this *PeerCom) SetRemoteOrgHeight(height uint64, id comm.Address) bool { 195 this.syncorg.Lock() 196 defer this.syncorg.Unlock() 197 if this.orgheight == nil { 198 this.orgheight = make(map[comm.Address]uint64) 199 } 200 bnew := true 201 if _, ok := this.orgheight[id]; ok { 202 bnew = false 203 } 204 this.orgheight[id] = height 205 return bnew 206 } 207 208 // GetRemoteOrgHeight returns a remote org peer's height : remotenode 209 func (this *PeerCom) GetRemoteOrgHeight(id comm.Address) uint64 { 210 this.syncorg.Lock() 211 defer this.syncorg.Unlock() 212 if this.orgheight == nil { 213 this.orgheight = make(map[comm.Address]uint64) 214 } 215 216 return this.orgheight[id] 217 } 218 219 func (this *PeerCom) GetRemoteOrgs() []comm.Address { 220 this.syncorg.Lock() 221 defer this.syncorg.Unlock() 222 223 result := make([]comm.Address, 0) 224 for orgid, _ := range this.orgheight { 225 result = append(result, orgid) 226 } 227 return result 228 } 229 230 func (this *PeerCom) DelRemoteOrg(id comm.Address) bool { 231 this.syncorg.Lock() 232 defer this.syncorg.Unlock() 233 234 if this.orgheight == nil { 235 this.orgheight = make(map[comm.Address]uint64) 236 } 237 238 bhave := false 239 if _, ok := this.orgheight[id]; ok { 240 bhave = true 241 } 242 delete(this.orgheight, id) 243 if len(this.orgheight) == 0 { 244 this.orgheight = make(map[comm.Address]uint64) 245 } 246 return bhave 247 } 248 249 func (this *PeerCom) BHaveOrgs() bool { 250 this.syncorg.Lock() 251 defer this.syncorg.Unlock() 252 253 if this.orgheight == nil { 254 this.orgheight = make(map[comm.Address]uint64) 255 } 256 257 return len(this.orgheight) > 0 258 } 259 260 func (this *PeerCom) BHaveOrgID(id comm.Address) bool { 261 this.syncorg.Lock() 262 defer this.syncorg.Unlock() 263 264 if this.orgheight == nil { 265 this.orgheight = make(map[comm.Address]uint64) 266 } 267 bhave := false 268 if _, ok := this.orgheight[id]; ok { 269 bhave = true 270 } 271 return bhave 272 } 273 274 func (this *PeerCom) BHaveOrgsExceptId(id comm.Address) bool { 275 this.syncorg.Lock() 276 defer this.syncorg.Unlock() 277 if this.orgheight == nil { 278 this.orgheight = make(map[comm.Address]uint64) 279 } 280 bhave := false 281 if len(this.orgheight) > 1 { 282 bhave = true 283 return bhave 284 } else if len(this.orgheight) == 1 { 285 if _, ok := this.orgheight[id]; !ok { 286 bhave = true 287 } 288 } 289 290 return bhave 291 } 292 293 func (this *PeerCom) BHaveOrgsId(id comm.Address) bool { 294 this.syncorg.Lock() 295 defer this.syncorg.Unlock() 296 if this.orgheight == nil { 297 this.orgheight = make(map[comm.Address]uint64) 298 } 299 bhave := false 300 if _, ok := this.orgheight[id]; ok { 301 bhave = true 302 } 303 304 return bhave 305 } 306 307 //Peer represent the node in p2p 308 type Peer struct { 309 base PeerCom 310 cap [32]byte 311 SyncLink *conn.Link 312 ConsLink *conn.Link 313 syncState uint32 314 consState uint32 315 txnCnt uint64 316 rxTxnCnt uint64 317 connLock sync.RWMutex 318 node *discover.Node 319 } 320 321 //NewPeer return new peer without publickey initial 322 func NewPeer() *Peer { 323 p := &Peer{ 324 syncState: common.INIT, 325 consState: common.INIT, 326 } 327 p.SyncLink = conn.NewLink() 328 p.ConsLink = conn.NewLink() 329 p.base.orgheight = make(map[comm.Address]uint64) 330 runtime.SetFinalizer(p, rmPeer) 331 return p 332 } 333 334 //rmPeer print a debug log when peer be finalized by system 335 func rmPeer(p *Peer) { 336 log.Debug("[p2p]Remove unused", "peerid", p.GetID()) 337 } 338 339 //DumpInfo print all information of peer 340 func (this *Peer) DumpInfo() { 341 log.Debug("[p2p]Node info:") 342 log.Debug("[p2p]", "syncState", this.syncState) 343 log.Debug("[p2p]", "consState", this.consState) 344 log.Debug("[p2p]", "id", this.GetID()) 345 log.Debug("[p2p]", "addr", this.SyncLink.GetAddr()) 346 log.Debug("[p2p]", "cap", this.cap) 347 log.Debug("[p2p]", "version", this.GetVersion()) 348 log.Debug("[p2p]", "services", this.GetServices()) 349 log.Debug("[p2p]", "syncPort", this.GetSyncPort()) 350 log.Debug("[p2p]", "consPort", this.GetConsPort()) 351 log.Debug("[p2p]", "relay", this.GetRelay()) 352 log.Debug("[p2p]", "height", this.GetHeight()) 353 } 354 355 //GetVersion return peer`s version 356 func (this *Peer) GetVersion() uint32 { 357 return this.base.GetVersion() 358 } 359 360 //GetHeight return peer`s block height 361 func (this *Peer) GetHeight() uint64 { 362 return this.base.GetHeight() 363 } 364 365 //SetHeight set height to peer 366 func (this *Peer) SetHeight(height uint64) { 367 this.base.SetHeight(height) 368 } 369 370 //GetOrgHeight return org peer`s block height 371 func (this *Peer) GetRemoteOrgHeight(id comm.Address) uint64 { 372 return this.base.GetRemoteOrgHeight(id) 373 } 374 375 //SetOrgHeight set org height to peer 376 func (this *Peer) SetRemoteOrgHeight(height uint64, id comm.Address) bool { 377 return this.base.SetRemoteOrgHeight(height, id) 378 } 379 380 // GetRemoteOrgs get Remote node orgs 381 func (this *Peer) GetRemoteOrgs() []comm.Address { 382 return this.base.GetRemoteOrgs() 383 } 384 385 // DelRemoteOrg del remote org to peer 386 func (this *Peer) DelRemoteOrg(id comm.Address) bool { 387 return this.base.DelRemoteOrg(id) 388 } 389 390 //BHaveOrgs the Remote node have org 391 func (this *Peer) BHaveOrgs() bool { 392 return this.base.BHaveOrgs() 393 } 394 395 //BHaveOrgs the Remote node have org 396 func (this *Peer) BHaveOrgsExceptId(id comm.Address) bool { 397 return this.base.BHaveOrgsExceptId(id) 398 } 399 400 //BHaveOrgID the Remote node have orgid 401 func (this *Peer) BHaveOrgID(id comm.Address) bool { 402 return this.base.BHaveOrgID(id) 403 } 404 405 //GetConsConn return consensus link 406 func (this *Peer) GetConsConn() *conn.Link { 407 return this.ConsLink 408 } 409 410 //SetConsConn set consensue link to peer 411 func (this *Peer) SetConsConn(consLink *conn.Link) { 412 this.ConsLink = consLink 413 } 414 415 //GetSyncState return sync state 416 func (this *Peer) GetSyncState() uint32 { 417 return this.syncState 418 } 419 420 //SetSyncState set sync state to peer 421 func (this *Peer) SetSyncState(state uint32) { 422 atomic.StoreUint32(&(this.syncState), state) 423 } 424 425 //GetConsState return peer`s consensus state 426 func (this *Peer) GetConsState() uint32 { 427 return this.consState 428 } 429 430 //SetConsState set consensus state to peer 431 func (this *Peer) SetConsState(state uint32) { 432 atomic.StoreUint32(&(this.consState), state) 433 } 434 435 //GetSyncPort return peer`s sync port 436 func (this *Peer) GetSyncPort() uint16 { 437 return this.SyncLink.GetPort() 438 } 439 440 //GetConsPort return peer`s consensus port 441 func (this *Peer) GetConsPort() uint16 { 442 return this.ConsLink.GetPort() 443 } 444 445 //SetConsPort set peer`s consensus port 446 func (this *Peer) SetConsPort(port uint16) { 447 this.ConsLink.SetPort(port) 448 } 449 450 //SendToSync call sync link to send buffer 451 func (this *Peer) SendToSync(msg common.Message) error { 452 if this.SyncLink != nil && this.SyncLink.Valid() { 453 return this.SyncLink.Tx(msg) 454 } 455 return errors.New("[p2p]sync link invalid") 456 } 457 458 //SendToCons call consensus link to send buffer 459 func (this *Peer) SendToCons(msg common.Message) error { 460 if this.ConsLink != nil && this.ConsLink.Valid() { 461 return this.ConsLink.Tx(msg) 462 } 463 return errors.New("[p2p]cons link invalid") 464 } 465 466 //CloseSync halt sync connection 467 func (this *Peer) CloseSync() { 468 //fmt.Println(" ********* Peer CloseSync ... ") 469 this.SetSyncState(common.INACTIVITY) 470 conn := this.SyncLink.GetConn() 471 rlpconn := this.SyncLink.GetRLPConn() 472 this.connLock.Lock() 473 if rlpconn != nil { 474 rlpconn.Close() 475 } 476 477 if conn != nil { 478 conn.Close() 479 } 480 this.connLock.Unlock() 481 } 482 483 //CloseCons halt consensus connection 484 func (this *Peer) CloseCons() { 485 this.SetConsState(common.INACTIVITY) 486 conn := this.ConsLink.GetConn() 487 this.connLock.Lock() 488 if conn != nil { 489 conn.Close() 490 491 } 492 this.connLock.Unlock() 493 } 494 495 //GetID return peer`s id 496 func (this *Peer) GetID() uint64 { 497 return this.base.GetID() 498 } 499 500 //GetRelay return peer`s relay state 501 func (this *Peer) GetRelay() bool { 502 return this.base.GetRelay() 503 } 504 505 //GetServices return peer`s service state 506 func (this *Peer) GetServices() uint64 { 507 return this.base.GetServices() 508 } 509 510 //GetTimeStamp return peer`s latest contact time in ticks 511 func (this *Peer) GetTimeStamp() int64 { 512 return this.SyncLink.GetRXTime().UnixNano() 513 } 514 515 //GetContactTime return peer`s latest contact time in Time struct 516 func (this *Peer) GetContactTime() time.Time { 517 return this.SyncLink.GetRXTime() 518 } 519 520 //GetAddr return peer`s sync link address 521 func (this *Peer) GetAddr() string { 522 return this.SyncLink.GetAddr() 523 } 524 525 //GetAddr16 return peer`s sync link address in []byte 526 func (this *Peer) GetAddr16() ([16]byte, error) { 527 var result [16]byte 528 addrIp, err := common.ParseIPAddr(this.GetAddr()) 529 if err != nil { 530 return result, err 531 } 532 ip := net.ParseIP(addrIp).To16() 533 if ip == nil { 534 log.Warn("[p2p]parse ip address error", "Addr", this.GetAddr()) 535 return result, errors.New("[p2p]parse ip address error") 536 } 537 538 copy(result[:], ip[:16]) 539 return result, nil 540 } 541 542 //AttachSyncChan set msg chan to sync link 543 func (this *Peer) AttachSyncChan(msgchan chan *common.MsgPayload) { 544 this.SyncLink.SetChan(msgchan) 545 } 546 547 //AttachConsChan set msg chan to consensus link 548 func (this *Peer) AttachConsChan(msgchan chan *common.MsgPayload) { 549 this.ConsLink.SetChan(msgchan) 550 } 551 552 //Send transfer buffer by sync or cons link 553 func (this *Peer) Send(msg common.Message, isConsensus bool) error { 554 555 if isConsensus && this.ConsLink.Valid() { 556 return this.SendToCons(msg) 557 } 558 return this.SendToSync(msg) 559 } 560 561 //SetHttpInfoState set peer`s httpinfo state 562 func (this *Peer) SetHttpInfoState(httpInfo bool) { 563 if httpInfo { 564 this.cap[common.HTTP_INFO_FLAG] = 0x01 565 } else { 566 this.cap[common.HTTP_INFO_FLAG] = 0x00 567 } 568 } 569 570 //GetHttpInfoState return peer`s httpinfo state 571 func (this *Peer) GetHttpInfoState() bool { 572 return this.cap[common.HTTP_INFO_FLAG] == 1 573 } 574 575 //GetHttpInfoPort return peer`s httpinfo port 576 func (this *Peer) GetHttpInfoPort() uint16 { 577 return this.base.GetHttpInfoPort() 578 } 579 580 //SetHttpInfoPort set peer`s httpinfo port 581 func (this *Peer) SetHttpInfoPort(port uint16) { 582 this.base.SetHttpInfoPort(port) 583 } 584 585 //GetHttpInfoPort return peer`s httpinfo port 586 func (this *Peer) GetNode() *discover.Node { 587 return this.node 588 } 589 590 //SetHttpInfoPort set peer`s httpinfo port 591 func (this *Peer) SetNode(node *discover.Node) { 592 this.node = node 593 } 594 595 //UpdateInfo update peer`s information 596 func (this *Peer) UpdateInfo(t time.Time, version uint32, services uint64, 597 syncPort uint16, consPort uint16, nonce uint64, relay uint8, height uint64) { 598 599 this.SyncLink.UpdateRXTime(t) 600 this.base.SetID(nonce) 601 this.base.SetVersion(version) 602 this.base.SetServices(services) 603 this.base.SetSyncPort(syncPort) 604 this.base.SetConsPort(consPort) 605 this.SyncLink.SetPort(syncPort) 606 this.ConsLink.SetPort(consPort) 607 if relay == 0 { 608 this.base.SetRelay(false) 609 } else { 610 this.base.SetRelay(true) 611 } 612 this.SetHeight(uint64(height)) 613 }