github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/eth/peer.go (about) 1 // Copyright 2015 The go-simplechain Authors 2 // This file is part of the go-simplechain library. 3 // 4 // The go-simplechain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-simplechain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-simplechain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package eth 18 19 import ( 20 "errors" 21 "fmt" 22 "math/big" 23 "math/rand" 24 "sync" 25 "time" 26 27 "github.com/bigzoro/my_simplechain/common" 28 "github.com/bigzoro/my_simplechain/core/forkid" 29 "github.com/bigzoro/my_simplechain/core/types" 30 "github.com/bigzoro/my_simplechain/p2p" 31 "github.com/bigzoro/my_simplechain/rlp" 32 mapset "github.com/deckarep/golang-set" 33 ) 34 35 var ( 36 errClosed = errors.New("peer set is closed") 37 errAlreadyRegistered = errors.New("peer is already registered") 38 errNotRegistered = errors.New("peer is not registered") 39 ) 40 41 const ( 42 maxKnownTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) 43 maxKnownBlocks = 1024 // Maximum block hashes to keep in the known list (prevent DOS) 44 45 // maxQueuedTxs is the maximum number of transaction lists to queue up before 46 // dropping broadcasts. This is a sensitive number as a transaction list might 47 // contain a single transaction, or thousands. 48 //todo 4096 49 maxQueuedTxs = 4096 50 51 // maxQueuedProps is the maximum number of block propagations to queue up before 52 // dropping broadcasts. There's not much point in queueing stale blocks, so a few 53 // that might cover uncles should be enough. 54 maxQueuedProps = 4 55 56 // maxQueuedAnns is the maximum number of block announcements to queue up before 57 // dropping broadcasts. Similarly to block propagations, there's no point to queue 58 // above some healthy uncle limit, so use that. 59 maxQueuedAnns = 4 60 61 handshakeTimeout = 5 * time.Second 62 63 maxKnownCRLs = 1024 64 ) 65 66 // PeerInfo represents a short summary of the SimpleService sub-protocol metadata known 67 // about a connected peer. 68 type PeerInfo struct { 69 Version int `json:"version"` // SimpleService protocol version negotiated 70 Difficulty *big.Int `json:"difficulty"` // Total difficulty of the peer's blockchain 71 Head string `json:"head"` // SHA3 hash of the peer's best owned block 72 } 73 74 // propEvent is a block propagation, waiting for its turn in the broadcast queue. 75 type propEvent struct { 76 block *types.Block 77 td *big.Int 78 } 79 80 type peer struct { 81 id string 82 83 *p2p.Peer 84 rw p2p.MsgReadWriter 85 86 version int // Protocol version negotiated 87 syncDrop *time.Timer // Timed connection dropper if sync progress isn't validated in time 88 89 head common.Hash 90 td *big.Int 91 lock sync.RWMutex 92 93 knownTxs mapset.Set // Set of transaction hashes known to be known by this peer 94 knownBlocks mapset.Set // Set of block hashes known to be known by this peer 95 queuedTxs chan []*types.Transaction // Queue of transactions to broadcast to the peer 96 queuedProps chan *propEvent // Queue of blocks to broadcast to the peer 97 queuedAnns chan *types.Block // Queue of blocks to announce to the peer 98 term chan struct{} // Termination channel to stop the broadcaster 99 100 knownCRLs mapset.Set 101 102 queuedCRLs chan *types.CertificateContent 103 } 104 105 // 构造peer 106 func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { 107 return &peer{ 108 Peer: p, 109 rw: rw, 110 version: version, 111 id: fmt.Sprintf("%x", p.ID().Bytes()[:8]), 112 knownTxs: mapset.NewSet(), 113 knownBlocks: mapset.NewSet(), 114 queuedTxs: make(chan []*types.Transaction, maxQueuedTxs), 115 queuedProps: make(chan *propEvent, maxQueuedProps), 116 queuedAnns: make(chan *types.Block, maxQueuedAnns), 117 term: make(chan struct{}), 118 knownCRLs: mapset.NewSet(), 119 queuedCRLs: make(chan *types.CertificateContent, 1), 120 } 121 } 122 123 // broadcast is a write loop that multiplexes block propagations, announcements 124 // and transaction broadcasts into the remote peer. The goal is to have an async 125 // writer that does not lock up node internals. 126 func (p *peer) broadcast() { 127 for { 128 select { 129 case txs := <-p.queuedTxs: 130 if err := p.SendTransactions(txs); err != nil { 131 return 132 } 133 p.Log().Trace("Broadcast transactions", "count", len(txs)) 134 135 case prop := <-p.queuedProps: 136 if err := p.SendNewBlock(prop.block, prop.td); err != nil { 137 return 138 } 139 p.Log().Trace("Propagated block", "number", prop.block.Number(), "hash", prop.block.Hash(), "td", prop.td) 140 141 case block := <-p.queuedAnns: 142 if err := p.SendNewBlockHashes([]common.Hash{block.Hash()}, []uint64{block.NumberU64()}); err != nil { 143 return 144 } 145 p.Log().Trace("Announced block", "number", block.Number(), "hash", block.Hash()) 146 case content := <-p.queuedCRLs: 147 err := p.SendCRL(content.Content, content.Signature) 148 if err != nil { 149 fmt.Println("SendCRL error:", err) 150 } 151 p.Log().Error("Broadcast crl", "hash", rlpHash(content)) 152 case <-p.term: 153 return 154 } 155 } 156 } 157 158 // close signals the broadcast goroutine to terminate. 159 func (p *peer) close() { 160 close(p.term) 161 } 162 163 // Info gathers and returns a collection of metadata known about a peer. 164 func (p *peer) Info() *PeerInfo { 165 hash, td := p.Head() 166 167 return &PeerInfo{ 168 Version: p.version, 169 Difficulty: td, 170 Head: hash.Hex(), 171 } 172 } 173 174 // Head retrieves a copy of the current head hash and total difficulty of the 175 // peer. 176 func (p *peer) Head() (hash common.Hash, td *big.Int) { 177 p.lock.RLock() 178 defer p.lock.RUnlock() 179 180 copy(hash[:], p.head[:]) 181 return hash, new(big.Int).Set(p.td) 182 } 183 184 // SetHead updates the head hash and total difficulty of the peer. 185 func (p *peer) SetHead(hash common.Hash, td *big.Int) { 186 p.lock.Lock() 187 defer p.lock.Unlock() 188 189 copy(p.head[:], hash[:]) 190 p.td.Set(td) 191 } 192 193 // MarkBlock marks a block as known for the peer, ensuring that the block will 194 // never be propagated to this particular peer. 195 func (p *peer) MarkBlock(hash common.Hash) { 196 // If we reached the memory allowance, drop a previously known block hash 197 for p.knownBlocks.Cardinality() >= maxKnownBlocks { 198 p.knownBlocks.Pop() 199 } 200 p.knownBlocks.Add(hash) 201 } 202 203 // MarkTransaction marks a transaction as known for the peer, ensuring that it 204 // will never be propagated to this particular peer. 205 func (p *peer) MarkTransaction(hash common.Hash) { 206 // If we reached the memory allowance, drop a previously known transaction hash 207 for p.knownTxs.Cardinality() >= maxKnownTxs { 208 p.knownTxs.Pop() 209 } 210 p.knownTxs.Add(hash) 211 } 212 213 // SendTransactions sends transactions to the peer and includes the hashes 214 // in its transaction hash set for future reference. 215 func (p *peer) SendTransactions(txs types.Transactions) error { 216 // Mark all the transactions as known, but ensure we don't overflow our limits 217 for _, tx := range txs { 218 p.knownTxs.Add(tx.Hash()) 219 } 220 for p.knownTxs.Cardinality() >= maxKnownTxs { 221 p.knownTxs.Pop() 222 } 223 return p2p.Send(p.rw, TxMsg, txs) 224 } 225 226 // AsyncSendTransactions queues list of transactions propagation to a remote 227 // peer. If the peer's broadcast queue is full, the event is silently dropped. 228 func (p *peer) AsyncSendTransactions(txs []*types.Transaction) { 229 select { 230 case p.queuedTxs <- txs: 231 // Mark all the transactions as known, but ensure we don't overflow our limits 232 for _, tx := range txs { 233 p.knownTxs.Add(tx.Hash()) 234 } 235 for p.knownTxs.Cardinality() >= maxKnownTxs { 236 p.knownTxs.Pop() 237 } 238 default: 239 p.Log().Debug("Dropping transaction propagation", "count", len(txs)) 240 } 241 } 242 243 // SendNewBlockHashes announces the availability of a number of blocks through 244 // a hash notification. 245 func (p *peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error { 246 // Mark all the block hashes as known, but ensure we don't overflow our limits 247 for _, hash := range hashes { 248 p.knownBlocks.Add(hash) 249 } 250 for p.knownBlocks.Cardinality() >= maxKnownBlocks { 251 p.knownBlocks.Pop() 252 } 253 request := make(newBlockHashesData, len(hashes)) 254 for i := 0; i < len(hashes); i++ { 255 request[i].Hash = hashes[i] 256 request[i].Number = numbers[i] 257 } 258 return p2p.Send(p.rw, NewBlockHashesMsg, request) 259 } 260 261 // AsyncSendNewBlockHash queues the availability of a block for propagation to a 262 // remote peer. If the peer's broadcast queue is full, the event is silently 263 // dropped. 264 func (p *peer) AsyncSendNewBlockHash(block *types.Block) { 265 select { 266 case p.queuedAnns <- block: 267 // Mark all the block hash as known, but ensure we don't overflow our limits 268 p.knownBlocks.Add(block.Hash()) 269 for p.knownBlocks.Cardinality() >= maxKnownBlocks { 270 p.knownBlocks.Pop() 271 } 272 default: 273 p.Log().Debug("Dropping block announcement", "number", block.NumberU64(), "hash", block.Hash()) 274 } 275 } 276 277 // SendNewBlock propagates an entire block to a remote peer. 278 func (p *peer) SendNewBlock(block *types.Block, td *big.Int) error { 279 // Mark all the block hash as known, but ensure we don't overflow our limits 280 p.knownBlocks.Add(block.Hash()) 281 for p.knownBlocks.Cardinality() >= maxKnownBlocks { 282 p.knownBlocks.Pop() 283 } 284 return p2p.Send(p.rw, NewBlockMsg, []interface{}{block, td}) 285 } 286 287 // AsyncSendNewBlock queues an entire block for propagation to a remote peer. If 288 // the peer's broadcast queue is full, the event is silently dropped. 289 func (p *peer) AsyncSendNewBlock(block *types.Block, td *big.Int) { 290 select { 291 case p.queuedProps <- &propEvent{block: block, td: td}: 292 // Mark all the block hash as known, but ensure we don't overflow our limits 293 p.knownBlocks.Add(block.Hash()) 294 for p.knownBlocks.Cardinality() >= maxKnownBlocks { 295 p.knownBlocks.Pop() 296 } 297 default: 298 p.Log().Debug("Dropping block propagation", "number", block.NumberU64(), "hash", block.Hash()) 299 } 300 } 301 302 // SendBlockHeaders sends a batch of block headers to the remote peer. 303 func (p *peer) SendBlockHeaders(headers []*types.Header) error { 304 return p2p.Send(p.rw, BlockHeadersMsg, headers) 305 } 306 307 // SendBlockBodies sends a batch of block contents to the remote peer. 308 func (p *peer) SendBlockBodies(bodies []*blockBody) error { 309 return p2p.Send(p.rw, BlockBodiesMsg, blockBodiesData(bodies)) 310 } 311 312 // SendBlockBodiesRLP sends a batch of block contents to the remote peer from 313 // an already RLP encoded format. 314 func (p *peer) SendBlockBodiesRLP(bodies []rlp.RawValue) error { 315 return p2p.Send(p.rw, BlockBodiesMsg, bodies) 316 } 317 318 // SendNodeDataRLP sends a batch of arbitrary internal data, corresponding to the 319 // hashes requested. 320 func (p *peer) SendNodeData(data [][]byte) error { 321 return p2p.Send(p.rw, NodeDataMsg, data) 322 } 323 324 // SendReceiptsRLP sends a batch of transaction receipts, corresponding to the 325 // ones requested from an already RLP encoded format. 326 func (p *peer) SendReceiptsRLP(receipts []rlp.RawValue) error { 327 return p2p.Send(p.rw, ReceiptsMsg, receipts) 328 } 329 330 // RequestOneHeader is a wrapper around the header query functions to fetch a 331 // single header. It is used solely by the fetcher. 332 func (p *peer) RequestOneHeader(hash common.Hash) error { 333 p.Log().Debug("Fetching single header", "hash", hash) 334 return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}, Amount: uint64(1), Skip: uint64(0), Reverse: false}) 335 } 336 337 // RequestHeadersByHash fetches a batch of blocks' headers corresponding to the 338 // specified header query, based on the hash of an origin block. 339 func (p *peer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error { 340 p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse) 341 return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 342 } 343 344 // RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the 345 // specified header query, based on the number of an origin block. 346 func (p *peer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error { 347 p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse) 348 return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 349 } 350 351 // RequestBodies fetches a batch of blocks' bodies corresponding to the hashes 352 // specified. 353 func (p *peer) RequestBodies(hashes []common.Hash) error { 354 p.Log().Debug("Fetching batch of block bodies", "count", len(hashes)) 355 return p2p.Send(p.rw, GetBlockBodiesMsg, hashes) 356 } 357 358 // RequestNodeData fetches a batch of arbitrary data from a node's known state 359 // data, corresponding to the specified hashes. 360 func (p *peer) RequestNodeData(hashes []common.Hash) error { 361 p.Log().Debug("Fetching batch of state data", "count", len(hashes)) 362 return p2p.Send(p.rw, GetNodeDataMsg, hashes) 363 } 364 365 // RequestReceipts fetches a batch of transaction receipts from a remote node. 366 func (p *peer) RequestReceipts(hashes []common.Hash) error { 367 p.Log().Debug("Fetching batch of receipts", "count", len(hashes)) 368 return p2p.Send(p.rw, GetReceiptsMsg, hashes) 369 } 370 371 // Handshake executes the eth protocol handshake, negotiating version number, 372 // network IDs, difficulties, head and genesis blocks. 373 func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter) error { 374 // Send out own handshake in a new thread 375 errc := make(chan error, 2) 376 377 var ( 378 status63 statusData63 // safe to read after two values have been received from errc 379 status statusData // safe to read after two values have been received from errc 380 ) 381 go func() { 382 switch { 383 case p.version == eth63: 384 errc <- p2p.Send(p.rw, StatusMsg, &statusData63{ 385 ProtocolVersion: uint32(p.version), 386 NetworkId: network, 387 TD: td, 388 CurrentBlock: head, 389 GenesisBlock: genesis, 390 }) 391 case p.version == eth64: 392 errc <- p2p.Send(p.rw, StatusMsg, &statusData{ 393 ProtocolVersion: uint32(p.version), 394 NetworkID: network, 395 TD: td, 396 Head: head, 397 Genesis: genesis, 398 ForkID: forkID, 399 }) 400 default: 401 panic(fmt.Sprintf("unsupported eth protocol version: %d", p.version)) 402 } 403 }() 404 go func() { 405 switch { 406 case p.version == eth63: 407 errc <- p.readStatusLegacy(network, &status63, genesis) 408 case p.version == eth64: 409 errc <- p.readStatus(network, &status, genesis, forkFilter) 410 default: 411 panic(fmt.Sprintf("unsupported eth protocol version: %d", p.version)) 412 } 413 }() 414 timeout := time.NewTimer(handshakeTimeout) 415 defer timeout.Stop() 416 for i := 0; i < 2; i++ { 417 select { 418 case err := <-errc: 419 if err != nil { 420 return err 421 } 422 case <-timeout.C: 423 return p2p.DiscReadTimeout 424 } 425 } 426 switch { 427 case p.version == eth63: 428 p.td, p.head = status63.TD, status63.CurrentBlock 429 case p.version == eth64: 430 p.td, p.head = status.TD, status.Head 431 default: 432 panic(fmt.Sprintf("unsupported eth protocol version: %d", p.version)) 433 } 434 return nil 435 } 436 437 func (p *peer) readStatusLegacy(network uint64, status *statusData63, genesis common.Hash) error { 438 msg, err := p.rw.ReadMsg() 439 if err != nil { 440 return err 441 } 442 if msg.Code != StatusMsg { 443 return errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) 444 } 445 if msg.Size > protocolMaxMsgSize { 446 return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, protocolMaxMsgSize) 447 } 448 // Decode the handshake and make sure everything matches 449 if err := msg.Decode(&status); err != nil { 450 return errResp(ErrDecode, "msg %v: %v", msg, err) 451 } 452 if status.GenesisBlock != genesis { 453 return errResp(ErrGenesisMismatch, "%x (!= %x)", status.GenesisBlock[:8], genesis[:8]) 454 } 455 if status.NetworkId != network { 456 return errResp(ErrNetworkIDMismatch, "%d (!= %d)", status.NetworkId, network) 457 } 458 if int(status.ProtocolVersion) != p.version { 459 return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", status.ProtocolVersion, p.version) 460 } 461 return nil 462 } 463 464 func (p *peer) readStatus(network uint64, status *statusData, genesis common.Hash, forkFilter forkid.Filter) error { 465 msg, err := p.rw.ReadMsg() 466 if err != nil { 467 return err 468 } 469 if msg.Code != StatusMsg { 470 return errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) 471 } 472 if msg.Size > protocolMaxMsgSize { 473 return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, protocolMaxMsgSize) 474 } 475 // Decode the handshake and make sure everything matches 476 if err := msg.Decode(&status); err != nil { 477 return errResp(ErrDecode, "msg %v: %v", msg, err) 478 } 479 if status.NetworkID != network { 480 return errResp(ErrNetworkIDMismatch, "%d (!= %d)", status.NetworkID, network) 481 } 482 if int(status.ProtocolVersion) != p.version { 483 return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", status.ProtocolVersion, p.version) 484 } 485 if status.Genesis != genesis { 486 return errResp(ErrGenesisMismatch, "%x (!= %x)", status.Genesis, genesis) 487 } 488 if err := forkFilter(status.ForkID); err != nil { 489 return errResp(ErrForkIDRejected, "%v", err) 490 } 491 return nil 492 } 493 494 // String implements fmt.Stringer. 495 func (p *peer) String() string { 496 return fmt.Sprintf("Peer %s [%s]", p.id, 497 fmt.Sprintf("eth/%2d", p.version), 498 ) 499 } 500 501 func (p *peer) AsyncSendCRL(certificate *types.CertificateContent) { 502 hash := rlpHash(certificate.Content) 503 select { 504 case p.queuedCRLs <- certificate: 505 // Mark all the block hash as known, but ensure we don't overflow our limits 506 p.knownCRLs.Add(hash) 507 for p.knownCRLs.Cardinality() >= maxKnownCRLs { 508 p.knownCRLs.Pop() 509 } 510 default: 511 p.Log().Debug("Dropping crl propagation", "hash", hash) 512 } 513 } 514 func (p *peer) SendCRL(content []byte, signature []byte) error { 515 p.Log().Info("broadcast Certificate Revocation List") 516 id := rand.Uint64() 517 return p2p.Send(p.rw, CertificateRevocationListMsg, &CertificateRevocationListPacket{ 518 ID: id, 519 Content: content, 520 Signature: signature, 521 }) 522 } 523 524 // peerSet represents the collection of active peers currently participating in 525 // the SimpleService sub-protocol. 526 type peerSet struct { 527 peers map[string]*peer 528 lock sync.RWMutex 529 closed bool 530 } 531 532 // newPeerSet creates a new peer set to track the active participants. 533 func newPeerSet() *peerSet { 534 return &peerSet{ 535 peers: make(map[string]*peer), 536 } 537 } 538 539 // Register injects a new peer into the working set, or returns an error if the 540 // peer is already known. If a new peer it registered, its broadcast loop is also 541 // started. 542 func (ps *peerSet) Register(p *peer) error { 543 ps.lock.Lock() 544 defer ps.lock.Unlock() 545 546 if ps.closed { 547 return errClosed 548 } 549 if _, ok := ps.peers[p.id]; ok { 550 return errAlreadyRegistered 551 } 552 ps.peers[p.id] = p 553 go p.broadcast() 554 555 return nil 556 } 557 558 // Unregister removes a remote peer from the active set, disabling any further 559 // actions to/from that particular entity. 560 func (ps *peerSet) Unregister(id string) error { 561 ps.lock.Lock() 562 defer ps.lock.Unlock() 563 564 p, ok := ps.peers[id] 565 if !ok { 566 return errNotRegistered 567 } 568 delete(ps.peers, id) 569 p.close() 570 571 return nil 572 } 573 574 // Peer retrieves the registered peer with the given id. 575 func (ps *peerSet) Peer(id string) *peer { 576 ps.lock.RLock() 577 defer ps.lock.RUnlock() 578 579 return ps.peers[id] 580 } 581 582 // Len returns if the current number of peers in the set. 583 func (ps *peerSet) Len() int { 584 ps.lock.RLock() 585 defer ps.lock.RUnlock() 586 587 return len(ps.peers) 588 } 589 590 // PeersWithoutBlock retrieves a list of peers that do not have a given block in 591 // their set of known hashes. 592 func (ps *peerSet) PeersWithoutBlock(hash common.Hash) []*peer { 593 ps.lock.RLock() 594 defer ps.lock.RUnlock() 595 596 list := make([]*peer, 0, len(ps.peers)) 597 for _, p := range ps.peers { 598 if !p.knownBlocks.Contains(hash) { 599 list = append(list, p) 600 } 601 } 602 return list 603 } 604 605 // PeersWithoutTx retrieves a list of peers that do not have a given transaction 606 // in their set of known hashes. 607 func (ps *peerSet) PeersWithoutTx(hash common.Hash) []*peer { 608 ps.lock.RLock() 609 defer ps.lock.RUnlock() 610 611 list := make([]*peer, 0, len(ps.peers)) 612 for _, p := range ps.peers { 613 if !p.knownTxs.Contains(hash) { 614 list = append(list, p) 615 } 616 } 617 return list 618 } 619 620 // BestPeer retrieves the known peer with the currently highest total difficulty. 621 func (ps *peerSet) BestPeer() *peer { 622 ps.lock.RLock() 623 defer ps.lock.RUnlock() 624 625 var ( 626 bestPeer *peer 627 bestTd *big.Int 628 ) 629 for _, p := range ps.peers { 630 if _, td := p.Head(); bestPeer == nil || td.Cmp(bestTd) > 0 { 631 bestPeer, bestTd = p, td 632 } 633 } 634 return bestPeer 635 } 636 637 // Close disconnects all peers. 638 // No new peers can be registered after Close has returned. 639 func (ps *peerSet) Close() { 640 ps.lock.Lock() 641 defer ps.lock.Unlock() 642 643 for _, p := range ps.peers { 644 p.Disconnect(p2p.DiscQuitting) 645 } 646 ps.closed = true 647 } 648 649 // PeersWithoutCRL return 650 func (ps *peerSet) PeersWithoutCRL(hash common.Hash) []*peer { 651 ps.lock.RLock() 652 defer ps.lock.RUnlock() 653 list := make([]*peer, 0, len(ps.peers)) 654 for _, p := range ps.peers { 655 if !p.knownCRLs.Contains(hash) { 656 list = append(list, p) 657 } 658 } 659 return list 660 }