github.com/hardtosaygoodbye/go-ethereum@v1.10.16-0.20220122011429-97003b9e6c15/les/peer.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package les 18 19 import ( 20 "crypto/ecdsa" 21 "errors" 22 "fmt" 23 "math/big" 24 "math/rand" 25 "net" 26 "sync" 27 "sync/atomic" 28 "time" 29 30 "github.com/hardtosaygoodbye/go-ethereum/common" 31 "github.com/hardtosaygoodbye/go-ethereum/common/mclock" 32 "github.com/hardtosaygoodbye/go-ethereum/core" 33 "github.com/hardtosaygoodbye/go-ethereum/core/forkid" 34 "github.com/hardtosaygoodbye/go-ethereum/core/types" 35 "github.com/hardtosaygoodbye/go-ethereum/les/flowcontrol" 36 "github.com/hardtosaygoodbye/go-ethereum/les/utils" 37 vfc "github.com/hardtosaygoodbye/go-ethereum/les/vflux/client" 38 vfs "github.com/hardtosaygoodbye/go-ethereum/les/vflux/server" 39 "github.com/hardtosaygoodbye/go-ethereum/light" 40 "github.com/hardtosaygoodbye/go-ethereum/p2p" 41 "github.com/hardtosaygoodbye/go-ethereum/p2p/enode" 42 "github.com/hardtosaygoodbye/go-ethereum/params" 43 "github.com/hardtosaygoodbye/go-ethereum/rlp" 44 ) 45 46 var ( 47 errClosed = errors.New("peer set is closed") 48 errAlreadyRegistered = errors.New("peer is already registered") 49 errNotRegistered = errors.New("peer is not registered") 50 ) 51 52 const ( 53 maxRequestErrors = 20 // number of invalid requests tolerated (makes the protocol less brittle but still avoids spam) 54 maxResponseErrors = 50 // number of invalid responses tolerated (makes the protocol less brittle but still avoids spam) 55 56 allowedUpdateBytes = 100000 // initial/maximum allowed update size 57 allowedUpdateRate = time.Millisecond * 10 // time constant for recharging one byte of allowance 58 59 freezeTimeBase = time.Millisecond * 700 // fixed component of client freeze time 60 freezeTimeRandom = time.Millisecond * 600 // random component of client freeze time 61 freezeCheckPeriod = time.Millisecond * 100 // buffer value recheck period after initial freeze time has elapsed 62 63 // If the total encoded size of a sent transaction batch is over txSizeCostLimit 64 // per transaction then the request cost is calculated as proportional to the 65 // encoded size instead of the transaction count 66 txSizeCostLimit = 0x4000 67 68 // handshakeTimeout is the timeout LES handshake will be treated as failed. 69 handshakeTimeout = 5 * time.Second 70 ) 71 72 const ( 73 announceTypeNone = iota 74 announceTypeSimple 75 announceTypeSigned 76 ) 77 78 type keyValueEntry struct { 79 Key string 80 Value rlp.RawValue 81 } 82 83 type keyValueList []keyValueEntry 84 type keyValueMap map[string]rlp.RawValue 85 86 func (l keyValueList) add(key string, val interface{}) keyValueList { 87 var entry keyValueEntry 88 entry.Key = key 89 if val == nil { 90 val = uint64(0) 91 } 92 enc, err := rlp.EncodeToBytes(val) 93 if err == nil { 94 entry.Value = enc 95 } 96 return append(l, entry) 97 } 98 99 func (l keyValueList) decode() (keyValueMap, uint64) { 100 m := make(keyValueMap) 101 var size uint64 102 for _, entry := range l { 103 m[entry.Key] = entry.Value 104 size += uint64(len(entry.Key)) + uint64(len(entry.Value)) + 8 105 } 106 return m, size 107 } 108 109 func (m keyValueMap) get(key string, val interface{}) error { 110 enc, ok := m[key] 111 if !ok { 112 return errResp(ErrMissingKey, "%s", key) 113 } 114 if val == nil { 115 return nil 116 } 117 return rlp.DecodeBytes(enc, val) 118 } 119 120 // peerCommons contains fields needed by both server peer and client peer. 121 type peerCommons struct { 122 *p2p.Peer 123 rw p2p.MsgReadWriter 124 125 id string // Peer identity. 126 version int // Protocol version negotiated. 127 network uint64 // Network ID being on. 128 frozen uint32 // Flag whether the peer is frozen. 129 announceType uint64 // New block announcement type. 130 serving uint32 // The status indicates the peer is served. 131 headInfo blockInfo // Last announced block information. 132 133 // Background task queue for caching peer tasks and executing in order. 134 sendQueue *utils.ExecQueue 135 136 // Flow control agreement. 137 fcParams flowcontrol.ServerParams // The config for token bucket. 138 fcCosts requestCostTable // The Maximum request cost table. 139 140 closeCh chan struct{} 141 lock sync.RWMutex // Lock used to protect all thread-sensitive fields. 142 } 143 144 // isFrozen returns true if the client is frozen or the server has put our 145 // client in frozen state 146 func (p *peerCommons) isFrozen() bool { 147 return atomic.LoadUint32(&p.frozen) != 0 148 } 149 150 // canQueue returns an indicator whether the peer can queue an operation. 151 func (p *peerCommons) canQueue() bool { 152 return p.sendQueue.CanQueue() && !p.isFrozen() 153 } 154 155 // queueSend caches a peer operation in the background task queue. 156 // Please ensure to check `canQueue` before call this function 157 func (p *peerCommons) queueSend(f func()) bool { 158 return p.sendQueue.Queue(f) 159 } 160 161 // String implements fmt.Stringer. 162 func (p *peerCommons) String() string { 163 return fmt.Sprintf("Peer %s [%s]", p.id, fmt.Sprintf("les/%d", p.version)) 164 } 165 166 // PeerInfo represents a short summary of the `eth` sub-protocol metadata known 167 // about a connected peer. 168 type PeerInfo struct { 169 Version int `json:"version"` // Ethereum protocol version negotiated 170 Difficulty *big.Int `json:"difficulty"` // Total difficulty of the peer's blockchain 171 Head string `json:"head"` // SHA3 hash of the peer's best owned block 172 } 173 174 // Info gathers and returns a collection of metadata known about a peer. 175 func (p *peerCommons) Info() *PeerInfo { 176 return &PeerInfo{ 177 Version: p.version, 178 Difficulty: p.Td(), 179 Head: fmt.Sprintf("%x", p.Head()), 180 } 181 } 182 183 // Head retrieves a copy of the current head (most recent) hash of the peer. 184 func (p *peerCommons) Head() (hash common.Hash) { 185 p.lock.RLock() 186 defer p.lock.RUnlock() 187 188 return p.headInfo.Hash 189 } 190 191 // Td retrieves the current total difficulty of a peer. 192 func (p *peerCommons) Td() *big.Int { 193 p.lock.RLock() 194 defer p.lock.RUnlock() 195 196 return new(big.Int).Set(p.headInfo.Td) 197 } 198 199 // HeadAndTd retrieves the current head hash and total difficulty of a peer. 200 func (p *peerCommons) HeadAndTd() (hash common.Hash, td *big.Int) { 201 p.lock.RLock() 202 defer p.lock.RUnlock() 203 204 return p.headInfo.Hash, new(big.Int).Set(p.headInfo.Td) 205 } 206 207 // sendReceiveHandshake exchanges handshake packet with remote peer and returns any error 208 // if failed to send or receive packet. 209 func (p *peerCommons) sendReceiveHandshake(sendList keyValueList) (keyValueList, error) { 210 var ( 211 errc = make(chan error, 2) 212 recvList keyValueList 213 ) 214 // Send out own handshake in a new thread 215 go func() { 216 errc <- p2p.Send(p.rw, StatusMsg, sendList) 217 }() 218 go func() { 219 // In the mean time retrieve the remote status message 220 msg, err := p.rw.ReadMsg() 221 if err != nil { 222 errc <- err 223 return 224 } 225 if msg.Code != StatusMsg { 226 errc <- errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) 227 return 228 } 229 if msg.Size > ProtocolMaxMsgSize { 230 errc <- errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) 231 return 232 } 233 // Decode the handshake 234 if err := msg.Decode(&recvList); err != nil { 235 errc <- errResp(ErrDecode, "msg %v: %v", msg, err) 236 return 237 } 238 errc <- nil 239 }() 240 timeout := time.NewTimer(handshakeTimeout) 241 defer timeout.Stop() 242 for i := 0; i < 2; i++ { 243 select { 244 case err := <-errc: 245 if err != nil { 246 return nil, err 247 } 248 case <-timeout.C: 249 return nil, p2p.DiscReadTimeout 250 } 251 } 252 return recvList, nil 253 } 254 255 // handshake executes the les protocol handshake, negotiating version number, 256 // network IDs, difficulties, head and genesis blocks. Besides the basic handshake 257 // fields, server and client can exchange and resolve some specified fields through 258 // two callback functions. 259 func (p *peerCommons) handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter, sendCallback func(*keyValueList), recvCallback func(keyValueMap) error) error { 260 p.lock.Lock() 261 defer p.lock.Unlock() 262 263 var send keyValueList 264 265 // Add some basic handshake fields 266 send = send.add("protocolVersion", uint64(p.version)) 267 send = send.add("networkId", p.network) 268 // Note: the head info announced at handshake is only used in case of server peers 269 // but dummy values are still announced by clients for compatibility with older servers 270 send = send.add("headTd", td) 271 send = send.add("headHash", head) 272 send = send.add("headNum", headNum) 273 send = send.add("genesisHash", genesis) 274 275 // If the protocol version is beyond les4, then pass the forkID 276 // as well. Check http://eips.ethereum.org/EIPS/eip-2124 for more 277 // spec detail. 278 if p.version >= lpv4 { 279 send = send.add("forkID", forkID) 280 } 281 // Add client-specified or server-specified fields 282 if sendCallback != nil { 283 sendCallback(&send) 284 } 285 // Exchange the handshake packet and resolve the received one. 286 recvList, err := p.sendReceiveHandshake(send) 287 if err != nil { 288 return err 289 } 290 recv, size := recvList.decode() 291 if size > allowedUpdateBytes { 292 return errResp(ErrRequestRejected, "") 293 } 294 var rGenesis common.Hash 295 var rVersion, rNetwork uint64 296 if err := recv.get("protocolVersion", &rVersion); err != nil { 297 return err 298 } 299 if err := recv.get("networkId", &rNetwork); err != nil { 300 return err 301 } 302 if err := recv.get("genesisHash", &rGenesis); err != nil { 303 return err 304 } 305 if rGenesis != genesis { 306 return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", rGenesis[:8], genesis[:8]) 307 } 308 if rNetwork != p.network { 309 return errResp(ErrNetworkIdMismatch, "%d (!= %d)", rNetwork, p.network) 310 } 311 if int(rVersion) != p.version { 312 return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", rVersion, p.version) 313 } 314 // Check forkID if the protocol version is beyond the les4 315 if p.version >= lpv4 { 316 var forkID forkid.ID 317 if err := recv.get("forkID", &forkID); err != nil { 318 return err 319 } 320 if err := forkFilter(forkID); err != nil { 321 return errResp(ErrForkIDRejected, "%v", err) 322 } 323 } 324 if recvCallback != nil { 325 return recvCallback(recv) 326 } 327 return nil 328 } 329 330 // close closes the channel and notifies all background routines to exit. 331 func (p *peerCommons) close() { 332 close(p.closeCh) 333 p.sendQueue.Quit() 334 } 335 336 // serverPeer represents each node to which the client is connected. 337 // The node here refers to the les server. 338 type serverPeer struct { 339 peerCommons 340 341 // Status fields 342 trusted bool // The flag whether the server is selected as trusted server. 343 onlyAnnounce bool // The flag whether the server sends announcement only. 344 chainSince, chainRecent uint64 // The range of chain server peer can serve. 345 stateSince, stateRecent uint64 // The range of state server peer can serve. 346 txHistory uint64 // The length of available tx history, 0 means all, 1 means disabled 347 348 // Advertised checkpoint fields 349 checkpointNumber uint64 // The block height which the checkpoint is registered. 350 checkpoint params.TrustedCheckpoint // The advertised checkpoint sent by server. 351 352 fcServer *flowcontrol.ServerNode // Client side mirror token bucket. 353 vtLock sync.Mutex 354 nodeValueTracker *vfc.NodeValueTracker 355 sentReqs map[uint64]sentReqEntry 356 357 // Statistics 358 errCount utils.LinearExpiredValue // Counter the invalid responses server has replied 359 updateCount uint64 360 updateTime mclock.AbsTime 361 362 // Test callback hooks 363 hasBlockHook func(common.Hash, uint64, bool) bool // Used to determine whether the server has the specified block. 364 } 365 366 func newServerPeer(version int, network uint64, trusted bool, p *p2p.Peer, rw p2p.MsgReadWriter) *serverPeer { 367 return &serverPeer{ 368 peerCommons: peerCommons{ 369 Peer: p, 370 rw: rw, 371 id: p.ID().String(), 372 version: version, 373 network: network, 374 sendQueue: utils.NewExecQueue(100), 375 closeCh: make(chan struct{}), 376 }, 377 trusted: trusted, 378 errCount: utils.LinearExpiredValue{Rate: mclock.AbsTime(time.Hour)}, 379 } 380 } 381 382 // rejectUpdate returns true if a parameter update has to be rejected because 383 // the size and/or rate of updates exceed the capacity limitation 384 func (p *serverPeer) rejectUpdate(size uint64) bool { 385 now := mclock.Now() 386 if p.updateCount == 0 { 387 p.updateTime = now 388 } else { 389 dt := now - p.updateTime 390 p.updateTime = now 391 392 r := uint64(dt / mclock.AbsTime(allowedUpdateRate)) 393 if p.updateCount > r { 394 p.updateCount -= r 395 } else { 396 p.updateCount = 0 397 } 398 } 399 p.updateCount += size 400 return p.updateCount > allowedUpdateBytes 401 } 402 403 // freeze processes Stop messages from the given server and set the status as 404 // frozen. 405 func (p *serverPeer) freeze() { 406 if atomic.CompareAndSwapUint32(&p.frozen, 0, 1) { 407 p.sendQueue.Clear() 408 } 409 } 410 411 // unfreeze processes Resume messages from the given server and set the status 412 // as unfrozen. 413 func (p *serverPeer) unfreeze() { 414 atomic.StoreUint32(&p.frozen, 0) 415 } 416 417 // sendRequest send a request to the server based on the given message type 418 // and content. 419 func sendRequest(w p2p.MsgWriter, msgcode, reqID uint64, data interface{}) error { 420 type req struct { 421 ReqID uint64 422 Data interface{} 423 } 424 return p2p.Send(w, msgcode, req{reqID, data}) 425 } 426 427 func (p *serverPeer) sendRequest(msgcode, reqID uint64, data interface{}, amount int) error { 428 p.sentRequest(reqID, uint32(msgcode), uint32(amount)) 429 return sendRequest(p.rw, msgcode, reqID, data) 430 } 431 432 // requestHeadersByHash fetches a batch of blocks' headers corresponding to the 433 // specified header query, based on the hash of an origin block. 434 func (p *serverPeer) requestHeadersByHash(reqID uint64, origin common.Hash, amount int, skip int, reverse bool) error { 435 p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse) 436 return p.sendRequest(GetBlockHeadersMsg, reqID, &GetBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}, amount) 437 } 438 439 // requestHeadersByNumber fetches a batch of blocks' headers corresponding to the 440 // specified header query, based on the number of an origin block. 441 func (p *serverPeer) requestHeadersByNumber(reqID, origin uint64, amount int, skip int, reverse bool) error { 442 p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse) 443 return p.sendRequest(GetBlockHeadersMsg, reqID, &GetBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}, amount) 444 } 445 446 // requestBodies fetches a batch of blocks' bodies corresponding to the hashes 447 // specified. 448 func (p *serverPeer) requestBodies(reqID uint64, hashes []common.Hash) error { 449 p.Log().Debug("Fetching batch of block bodies", "count", len(hashes)) 450 return p.sendRequest(GetBlockBodiesMsg, reqID, hashes, len(hashes)) 451 } 452 453 // requestCode fetches a batch of arbitrary data from a node's known state 454 // data, corresponding to the specified hashes. 455 func (p *serverPeer) requestCode(reqID uint64, reqs []CodeReq) error { 456 p.Log().Debug("Fetching batch of codes", "count", len(reqs)) 457 return p.sendRequest(GetCodeMsg, reqID, reqs, len(reqs)) 458 } 459 460 // requestReceipts fetches a batch of transaction receipts from a remote node. 461 func (p *serverPeer) requestReceipts(reqID uint64, hashes []common.Hash) error { 462 p.Log().Debug("Fetching batch of receipts", "count", len(hashes)) 463 return p.sendRequest(GetReceiptsMsg, reqID, hashes, len(hashes)) 464 } 465 466 // requestProofs fetches a batch of merkle proofs from a remote node. 467 func (p *serverPeer) requestProofs(reqID uint64, reqs []ProofReq) error { 468 p.Log().Debug("Fetching batch of proofs", "count", len(reqs)) 469 return p.sendRequest(GetProofsV2Msg, reqID, reqs, len(reqs)) 470 } 471 472 // requestHelperTrieProofs fetches a batch of HelperTrie merkle proofs from a remote node. 473 func (p *serverPeer) requestHelperTrieProofs(reqID uint64, reqs []HelperTrieReq) error { 474 p.Log().Debug("Fetching batch of HelperTrie proofs", "count", len(reqs)) 475 return p.sendRequest(GetHelperTrieProofsMsg, reqID, reqs, len(reqs)) 476 } 477 478 // requestTxStatus fetches a batch of transaction status records from a remote node. 479 func (p *serverPeer) requestTxStatus(reqID uint64, txHashes []common.Hash) error { 480 p.Log().Debug("Requesting transaction status", "count", len(txHashes)) 481 return p.sendRequest(GetTxStatusMsg, reqID, txHashes, len(txHashes)) 482 } 483 484 // sendTxs creates a reply with a batch of transactions to be added to the remote transaction pool. 485 func (p *serverPeer) sendTxs(reqID uint64, amount int, txs rlp.RawValue) error { 486 p.Log().Debug("Sending batch of transactions", "amount", amount, "size", len(txs)) 487 sizeFactor := (len(txs) + txSizeCostLimit/2) / txSizeCostLimit 488 if sizeFactor > amount { 489 amount = sizeFactor 490 } 491 return p.sendRequest(SendTxV2Msg, reqID, txs, amount) 492 } 493 494 // waitBefore implements distPeer interface 495 func (p *serverPeer) waitBefore(maxCost uint64) (time.Duration, float64) { 496 return p.fcServer.CanSend(maxCost) 497 } 498 499 // getRequestCost returns an estimated request cost according to the flow control 500 // rules negotiated between the server and the client. 501 func (p *serverPeer) getRequestCost(msgcode uint64, amount int) uint64 { 502 p.lock.RLock() 503 defer p.lock.RUnlock() 504 505 costs := p.fcCosts[msgcode] 506 if costs == nil { 507 return 0 508 } 509 cost := costs.baseCost + costs.reqCost*uint64(amount) 510 if cost > p.fcParams.BufLimit { 511 cost = p.fcParams.BufLimit 512 } 513 return cost 514 } 515 516 // getTxRelayCost returns an estimated relay cost according to the flow control 517 // rules negotiated between the server and the client. 518 func (p *serverPeer) getTxRelayCost(amount, size int) uint64 { 519 p.lock.RLock() 520 defer p.lock.RUnlock() 521 522 costs := p.fcCosts[SendTxV2Msg] 523 if costs == nil { 524 return 0 525 } 526 cost := costs.baseCost + costs.reqCost*uint64(amount) 527 sizeCost := costs.baseCost + costs.reqCost*uint64(size)/txSizeCostLimit 528 if sizeCost > cost { 529 cost = sizeCost 530 } 531 if cost > p.fcParams.BufLimit { 532 cost = p.fcParams.BufLimit 533 } 534 return cost 535 } 536 537 // HasBlock checks if the peer has a given block 538 func (p *serverPeer) HasBlock(hash common.Hash, number uint64, hasState bool) bool { 539 p.lock.RLock() 540 defer p.lock.RUnlock() 541 542 if p.hasBlockHook != nil { 543 return p.hasBlockHook(hash, number, hasState) 544 } 545 head := p.headInfo.Number 546 var since, recent uint64 547 if hasState { 548 since = p.stateSince 549 recent = p.stateRecent 550 } else { 551 since = p.chainSince 552 recent = p.chainRecent 553 } 554 return head >= number && number >= since && (recent == 0 || number+recent+4 > head) 555 } 556 557 // updateFlowControl updates the flow control parameters belonging to the server 558 // node if the announced key/value set contains relevant fields 559 func (p *serverPeer) updateFlowControl(update keyValueMap) { 560 p.lock.Lock() 561 defer p.lock.Unlock() 562 563 // If any of the flow control params is nil, refuse to update. 564 var params flowcontrol.ServerParams 565 if update.get("flowControl/BL", ¶ms.BufLimit) == nil && update.get("flowControl/MRR", ¶ms.MinRecharge) == nil { 566 // todo can light client set a minimal acceptable flow control params? 567 p.fcParams = params 568 p.fcServer.UpdateParams(params) 569 } 570 var MRC RequestCostList 571 if update.get("flowControl/MRC", &MRC) == nil { 572 costUpdate := MRC.decode(ProtocolLengths[uint(p.version)]) 573 for code, cost := range costUpdate { 574 p.fcCosts[code] = cost 575 } 576 } 577 } 578 579 // updateHead updates the head information based on the announcement from 580 // the peer. 581 func (p *serverPeer) updateHead(hash common.Hash, number uint64, td *big.Int) { 582 p.lock.Lock() 583 defer p.lock.Unlock() 584 585 p.headInfo = blockInfo{Hash: hash, Number: number, Td: td} 586 } 587 588 // Handshake executes the les protocol handshake, negotiating version number, 589 // network IDs and genesis blocks. 590 func (p *serverPeer) Handshake(genesis common.Hash, forkid forkid.ID, forkFilter forkid.Filter) error { 591 // Note: there is no need to share local head with a server but older servers still 592 // require these fields so we announce zero values. 593 return p.handshake(common.Big0, common.Hash{}, 0, genesis, forkid, forkFilter, func(lists *keyValueList) { 594 // Add some client-specific handshake fields 595 // 596 // Enable signed announcement randomly even the server is not trusted. 597 p.announceType = announceTypeSimple 598 if p.trusted { 599 p.announceType = announceTypeSigned 600 } 601 *lists = (*lists).add("announceType", p.announceType) 602 }, func(recv keyValueMap) error { 603 var ( 604 rHash common.Hash 605 rNum uint64 606 rTd *big.Int 607 ) 608 if err := recv.get("headTd", &rTd); err != nil { 609 return err 610 } 611 if err := recv.get("headHash", &rHash); err != nil { 612 return err 613 } 614 if err := recv.get("headNum", &rNum); err != nil { 615 return err 616 } 617 p.headInfo = blockInfo{Hash: rHash, Number: rNum, Td: rTd} 618 if recv.get("serveChainSince", &p.chainSince) != nil { 619 p.onlyAnnounce = true 620 } 621 if recv.get("serveRecentChain", &p.chainRecent) != nil { 622 p.chainRecent = 0 623 } 624 if recv.get("serveStateSince", &p.stateSince) != nil { 625 p.onlyAnnounce = true 626 } 627 if recv.get("serveRecentState", &p.stateRecent) != nil { 628 p.stateRecent = 0 629 } 630 if recv.get("txRelay", nil) != nil { 631 p.onlyAnnounce = true 632 } 633 if p.version >= lpv4 { 634 var recentTx uint 635 if err := recv.get("recentTxLookup", &recentTx); err != nil { 636 return err 637 } 638 p.txHistory = uint64(recentTx) 639 } else { 640 // The weak assumption is held here that legacy les server(les2,3) 641 // has unlimited transaction history. The les serving in these legacy 642 // versions is disabled if the transaction is unindexed. 643 p.txHistory = txIndexUnlimited 644 } 645 if p.onlyAnnounce && !p.trusted { 646 return errResp(ErrUselessPeer, "peer cannot serve requests") 647 } 648 // Parse flow control handshake packet. 649 var sParams flowcontrol.ServerParams 650 if err := recv.get("flowControl/BL", &sParams.BufLimit); err != nil { 651 return err 652 } 653 if err := recv.get("flowControl/MRR", &sParams.MinRecharge); err != nil { 654 return err 655 } 656 var MRC RequestCostList 657 if err := recv.get("flowControl/MRC", &MRC); err != nil { 658 return err 659 } 660 p.fcParams = sParams 661 p.fcServer = flowcontrol.NewServerNode(sParams, &mclock.System{}) 662 p.fcCosts = MRC.decode(ProtocolLengths[uint(p.version)]) 663 664 recv.get("checkpoint/value", &p.checkpoint) 665 recv.get("checkpoint/registerHeight", &p.checkpointNumber) 666 667 if !p.onlyAnnounce { 668 for msgCode := range reqAvgTimeCost { 669 if p.fcCosts[msgCode] == nil { 670 return errResp(ErrUselessPeer, "peer does not support message %d", msgCode) 671 } 672 } 673 } 674 return nil 675 }) 676 } 677 678 // setValueTracker sets the value tracker references for connected servers. Note that the 679 // references should be removed upon disconnection by setValueTracker(nil, nil). 680 func (p *serverPeer) setValueTracker(nvt *vfc.NodeValueTracker) { 681 p.vtLock.Lock() 682 p.nodeValueTracker = nvt 683 if nvt != nil { 684 p.sentReqs = make(map[uint64]sentReqEntry) 685 } else { 686 p.sentReqs = nil 687 } 688 p.vtLock.Unlock() 689 } 690 691 // updateVtParams updates the server's price table in the value tracker. 692 func (p *serverPeer) updateVtParams() { 693 p.vtLock.Lock() 694 defer p.vtLock.Unlock() 695 696 if p.nodeValueTracker == nil { 697 return 698 } 699 reqCosts := make([]uint64, len(requestList)) 700 for code, costs := range p.fcCosts { 701 if m, ok := requestMapping[uint32(code)]; ok { 702 reqCosts[m.first] = costs.baseCost + costs.reqCost 703 if m.rest != -1 { 704 reqCosts[m.rest] = costs.reqCost 705 } 706 } 707 } 708 p.nodeValueTracker.UpdateCosts(reqCosts) 709 } 710 711 // sentReqEntry remembers sent requests and their sending times 712 type sentReqEntry struct { 713 reqType, amount uint32 714 at mclock.AbsTime 715 } 716 717 // sentRequest marks a request sent at the current moment to this server. 718 func (p *serverPeer) sentRequest(id uint64, reqType, amount uint32) { 719 p.vtLock.Lock() 720 if p.sentReqs != nil { 721 p.sentReqs[id] = sentReqEntry{reqType, amount, mclock.Now()} 722 } 723 p.vtLock.Unlock() 724 } 725 726 // answeredRequest marks a request answered at the current moment by this server. 727 func (p *serverPeer) answeredRequest(id uint64) { 728 p.vtLock.Lock() 729 if p.sentReqs == nil { 730 p.vtLock.Unlock() 731 return 732 } 733 e, ok := p.sentReqs[id] 734 delete(p.sentReqs, id) 735 nvt := p.nodeValueTracker 736 p.vtLock.Unlock() 737 if !ok { 738 return 739 } 740 var ( 741 vtReqs [2]vfc.ServedRequest 742 reqCount int 743 ) 744 m := requestMapping[e.reqType] 745 if m.rest == -1 || e.amount <= 1 { 746 reqCount = 1 747 vtReqs[0] = vfc.ServedRequest{ReqType: uint32(m.first), Amount: e.amount} 748 } else { 749 reqCount = 2 750 vtReqs[0] = vfc.ServedRequest{ReqType: uint32(m.first), Amount: 1} 751 vtReqs[1] = vfc.ServedRequest{ReqType: uint32(m.rest), Amount: e.amount - 1} 752 } 753 dt := time.Duration(mclock.Now() - e.at) 754 nvt.Served(vtReqs[:reqCount], dt) 755 } 756 757 // clientPeer represents each node to which the les server is connected. 758 // The node here refers to the light client. 759 type clientPeer struct { 760 peerCommons 761 762 // responseLock ensures that responses are queued in the same order as 763 // RequestProcessed is called 764 responseLock sync.Mutex 765 responseCount uint64 // Counter to generate an unique id for request processing. 766 767 balance vfs.ConnectedBalance 768 769 // invalidLock is used for protecting invalidCount. 770 invalidLock sync.RWMutex 771 invalidCount utils.LinearExpiredValue // Counter the invalid request the client peer has made. 772 773 capacity uint64 774 // lastAnnounce is the last broadcast created by the server; may be newer than the last head 775 // sent to the specific client (stored in headInfo) if capacity is zero. In this case the 776 // latest head is sent when the client gains non-zero capacity. 777 lastAnnounce announceData 778 779 connectedAt mclock.AbsTime 780 server bool 781 errCh chan error 782 fcClient *flowcontrol.ClientNode // Server side mirror token bucket. 783 } 784 785 func newClientPeer(version int, network uint64, p *p2p.Peer, rw p2p.MsgReadWriter) *clientPeer { 786 return &clientPeer{ 787 peerCommons: peerCommons{ 788 Peer: p, 789 rw: rw, 790 id: p.ID().String(), 791 version: version, 792 network: network, 793 sendQueue: utils.NewExecQueue(100), 794 closeCh: make(chan struct{}), 795 }, 796 invalidCount: utils.LinearExpiredValue{Rate: mclock.AbsTime(time.Hour)}, 797 errCh: make(chan error, 1), 798 } 799 } 800 801 // FreeClientId returns a string identifier for the peer. Multiple peers with 802 // the same identifier can not be connected in free mode simultaneously. 803 func (p *clientPeer) FreeClientId() string { 804 if addr, ok := p.RemoteAddr().(*net.TCPAddr); ok { 805 if addr.IP.IsLoopback() { 806 // using peer id instead of loopback ip address allows multiple free 807 // connections from local machine to own server 808 return p.id 809 } else { 810 return addr.IP.String() 811 } 812 } 813 return p.id 814 } 815 816 // sendStop notifies the client about being in frozen state 817 func (p *clientPeer) sendStop() error { 818 return p2p.Send(p.rw, StopMsg, struct{}{}) 819 } 820 821 // sendResume notifies the client about getting out of frozen state 822 func (p *clientPeer) sendResume(bv uint64) error { 823 return p2p.Send(p.rw, ResumeMsg, bv) 824 } 825 826 // freeze temporarily puts the client in a frozen state which means all unprocessed 827 // and subsequent requests are dropped. Unfreezing happens automatically after a short 828 // time if the client's buffer value is at least in the slightly positive region. 829 // The client is also notified about being frozen/unfrozen with a Stop/Resume message. 830 func (p *clientPeer) freeze() { 831 if p.version < lpv3 { 832 // if Stop/Resume is not supported then just drop the peer after setting 833 // its frozen status permanently 834 atomic.StoreUint32(&p.frozen, 1) 835 p.Peer.Disconnect(p2p.DiscUselessPeer) 836 return 837 } 838 if atomic.SwapUint32(&p.frozen, 1) == 0 { 839 go func() { 840 p.sendStop() 841 time.Sleep(freezeTimeBase + time.Duration(rand.Int63n(int64(freezeTimeRandom)))) 842 for { 843 bufValue, bufLimit := p.fcClient.BufferStatus() 844 if bufLimit == 0 { 845 return 846 } 847 if bufValue <= bufLimit/8 { 848 time.Sleep(freezeCheckPeriod) 849 continue 850 } 851 atomic.StoreUint32(&p.frozen, 0) 852 p.sendResume(bufValue) 853 return 854 } 855 }() 856 } 857 } 858 859 // reply struct represents a reply with the actual data already RLP encoded and 860 // only the bv (buffer value) missing. This allows the serving mechanism to 861 // calculate the bv value which depends on the data size before sending the reply. 862 type reply struct { 863 w p2p.MsgWriter 864 msgcode, reqID uint64 865 data rlp.RawValue 866 } 867 868 // send sends the reply with the calculated buffer value 869 func (r *reply) send(bv uint64) error { 870 type resp struct { 871 ReqID, BV uint64 872 Data rlp.RawValue 873 } 874 return p2p.Send(r.w, r.msgcode, resp{r.reqID, bv, r.data}) 875 } 876 877 // size returns the RLP encoded size of the message data 878 func (r *reply) size() uint32 { 879 return uint32(len(r.data)) 880 } 881 882 // replyBlockHeaders creates a reply with a batch of block headers 883 func (p *clientPeer) replyBlockHeaders(reqID uint64, headers []*types.Header) *reply { 884 data, _ := rlp.EncodeToBytes(headers) 885 return &reply{p.rw, BlockHeadersMsg, reqID, data} 886 } 887 888 // replyBlockBodiesRLP creates a reply with a batch of block contents from 889 // an already RLP encoded format. 890 func (p *clientPeer) replyBlockBodiesRLP(reqID uint64, bodies []rlp.RawValue) *reply { 891 data, _ := rlp.EncodeToBytes(bodies) 892 return &reply{p.rw, BlockBodiesMsg, reqID, data} 893 } 894 895 // replyCode creates a reply with a batch of arbitrary internal data, corresponding to the 896 // hashes requested. 897 func (p *clientPeer) replyCode(reqID uint64, codes [][]byte) *reply { 898 data, _ := rlp.EncodeToBytes(codes) 899 return &reply{p.rw, CodeMsg, reqID, data} 900 } 901 902 // replyReceiptsRLP creates a reply with a batch of transaction receipts, corresponding to the 903 // ones requested from an already RLP encoded format. 904 func (p *clientPeer) replyReceiptsRLP(reqID uint64, receipts []rlp.RawValue) *reply { 905 data, _ := rlp.EncodeToBytes(receipts) 906 return &reply{p.rw, ReceiptsMsg, reqID, data} 907 } 908 909 // replyProofsV2 creates a reply with a batch of merkle proofs, corresponding to the ones requested. 910 func (p *clientPeer) replyProofsV2(reqID uint64, proofs light.NodeList) *reply { 911 data, _ := rlp.EncodeToBytes(proofs) 912 return &reply{p.rw, ProofsV2Msg, reqID, data} 913 } 914 915 // replyHelperTrieProofs creates a reply with a batch of HelperTrie proofs, corresponding to the ones requested. 916 func (p *clientPeer) replyHelperTrieProofs(reqID uint64, resp HelperTrieResps) *reply { 917 data, _ := rlp.EncodeToBytes(resp) 918 return &reply{p.rw, HelperTrieProofsMsg, reqID, data} 919 } 920 921 // replyTxStatus creates a reply with a batch of transaction status records, corresponding to the ones requested. 922 func (p *clientPeer) replyTxStatus(reqID uint64, stats []light.TxStatus) *reply { 923 data, _ := rlp.EncodeToBytes(stats) 924 return &reply{p.rw, TxStatusMsg, reqID, data} 925 } 926 927 // sendAnnounce announces the availability of a number of blocks through 928 // a hash notification. 929 func (p *clientPeer) sendAnnounce(request announceData) error { 930 return p2p.Send(p.rw, AnnounceMsg, request) 931 } 932 933 // InactiveAllowance implements vfs.clientPeer 934 func (p *clientPeer) InactiveAllowance() time.Duration { 935 return 0 // will return more than zero for les/5 clients 936 } 937 938 // getCapacity returns the current capacity of the peer 939 func (p *clientPeer) getCapacity() uint64 { 940 p.lock.RLock() 941 defer p.lock.RUnlock() 942 943 return p.capacity 944 } 945 946 // UpdateCapacity updates the request serving capacity assigned to a given client 947 // and also sends an announcement about the updated flow control parameters. 948 // Note: UpdateCapacity implements vfs.clientPeer and should not block. The requested 949 // parameter is true if the callback was initiated by ClientPool.SetCapacity on the given peer. 950 func (p *clientPeer) UpdateCapacity(newCap uint64, requested bool) { 951 p.lock.Lock() 952 defer p.lock.Unlock() 953 954 if newCap != p.fcParams.MinRecharge { 955 p.fcParams = flowcontrol.ServerParams{MinRecharge: newCap, BufLimit: newCap * bufLimitRatio} 956 p.fcClient.UpdateParams(p.fcParams) 957 var kvList keyValueList 958 kvList = kvList.add("flowControl/MRR", newCap) 959 kvList = kvList.add("flowControl/BL", newCap*bufLimitRatio) 960 p.queueSend(func() { p.sendAnnounce(announceData{Update: kvList}) }) 961 } 962 963 if p.capacity == 0 && newCap != 0 { 964 p.sendLastAnnounce() 965 } 966 p.capacity = newCap 967 } 968 969 // announceOrStore sends the given head announcement to the client if the client is 970 // active (capacity != 0) and the same announcement hasn't been sent before. If the 971 // client is inactive the announcement is stored and sent later if the client is 972 // activated again. 973 func (p *clientPeer) announceOrStore(announce announceData) { 974 p.lock.Lock() 975 defer p.lock.Unlock() 976 977 p.lastAnnounce = announce 978 if p.capacity != 0 { 979 p.sendLastAnnounce() 980 } 981 } 982 983 // announce sends the given head announcement to the client if it hasn't been sent before 984 func (p *clientPeer) sendLastAnnounce() { 985 if p.lastAnnounce.Td == nil { 986 return 987 } 988 if p.headInfo.Td == nil || p.lastAnnounce.Td.Cmp(p.headInfo.Td) > 0 { 989 if !p.queueSend(func() { p.sendAnnounce(p.lastAnnounce) }) { 990 p.Log().Debug("Dropped announcement because queue is full", "number", p.lastAnnounce.Number, "hash", p.lastAnnounce.Hash) 991 } else { 992 p.Log().Debug("Sent announcement", "number", p.lastAnnounce.Number, "hash", p.lastAnnounce.Hash) 993 } 994 p.headInfo = blockInfo{Hash: p.lastAnnounce.Hash, Number: p.lastAnnounce.Number, Td: p.lastAnnounce.Td} 995 } 996 } 997 998 // freezeClient temporarily puts the client in a frozen state which means all 999 // unprocessed and subsequent requests are dropped. Unfreezing happens automatically 1000 // after a short time if the client's buffer value is at least in the slightly positive 1001 // region. The client is also notified about being frozen/unfrozen with a Stop/Resume 1002 // message. 1003 func (p *clientPeer) freezeClient() { 1004 if p.version < lpv3 { 1005 // if Stop/Resume is not supported then just drop the peer after setting 1006 // its frozen status permanently 1007 atomic.StoreUint32(&p.frozen, 1) 1008 p.Peer.Disconnect(p2p.DiscUselessPeer) 1009 return 1010 } 1011 if atomic.SwapUint32(&p.frozen, 1) == 0 { 1012 go func() { 1013 p.sendStop() 1014 time.Sleep(freezeTimeBase + time.Duration(rand.Int63n(int64(freezeTimeRandom)))) 1015 for { 1016 bufValue, bufLimit := p.fcClient.BufferStatus() 1017 if bufLimit == 0 { 1018 return 1019 } 1020 if bufValue <= bufLimit/8 { 1021 time.Sleep(freezeCheckPeriod) 1022 } else { 1023 atomic.StoreUint32(&p.frozen, 0) 1024 p.sendResume(bufValue) 1025 break 1026 } 1027 } 1028 }() 1029 } 1030 } 1031 1032 // Handshake executes the les protocol handshake, negotiating version number, 1033 // network IDs, difficulties, head and genesis blocks. 1034 func (p *clientPeer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter, server *LesServer) error { 1035 recentTx := server.handler.blockchain.TxLookupLimit() 1036 if recentTx != txIndexUnlimited { 1037 if recentTx < blockSafetyMargin { 1038 recentTx = txIndexDisabled 1039 } else { 1040 recentTx -= blockSafetyMargin - txIndexRecentOffset 1041 } 1042 } 1043 if server.config.UltraLightOnlyAnnounce { 1044 recentTx = txIndexDisabled 1045 } 1046 if recentTx != txIndexUnlimited && p.version < lpv4 { 1047 return errors.New("Cannot serve old clients without a complete tx index") 1048 } 1049 // Note: clientPeer.headInfo should contain the last head announced to the client by us. 1050 // The values announced in the handshake are dummy values for compatibility reasons and should be ignored. 1051 p.headInfo = blockInfo{Hash: head, Number: headNum, Td: td} 1052 return p.handshake(td, head, headNum, genesis, forkID, forkFilter, func(lists *keyValueList) { 1053 // Add some information which services server can offer. 1054 if !server.config.UltraLightOnlyAnnounce { 1055 *lists = (*lists).add("serveHeaders", nil) 1056 *lists = (*lists).add("serveChainSince", uint64(0)) 1057 *lists = (*lists).add("serveStateSince", uint64(0)) 1058 1059 // If local ethereum node is running in archive mode, advertise ourselves we have 1060 // all version state data. Otherwise only recent state is available. 1061 stateRecent := uint64(core.TriesInMemory - blockSafetyMargin) 1062 if server.archiveMode { 1063 stateRecent = 0 1064 } 1065 *lists = (*lists).add("serveRecentState", stateRecent) 1066 *lists = (*lists).add("txRelay", nil) 1067 } 1068 if p.version >= lpv4 { 1069 *lists = (*lists).add("recentTxLookup", recentTx) 1070 } 1071 *lists = (*lists).add("flowControl/BL", server.defParams.BufLimit) 1072 *lists = (*lists).add("flowControl/MRR", server.defParams.MinRecharge) 1073 1074 var costList RequestCostList 1075 if server.costTracker.testCostList != nil { 1076 costList = server.costTracker.testCostList 1077 } else { 1078 costList = server.costTracker.makeCostList(server.costTracker.globalFactor()) 1079 } 1080 *lists = (*lists).add("flowControl/MRC", costList) 1081 p.fcCosts = costList.decode(ProtocolLengths[uint(p.version)]) 1082 p.fcParams = server.defParams 1083 1084 // Add advertised checkpoint and register block height which 1085 // client can verify the checkpoint validity. 1086 if server.oracle != nil && server.oracle.IsRunning() { 1087 cp, height := server.oracle.StableCheckpoint() 1088 if cp != nil { 1089 *lists = (*lists).add("checkpoint/value", cp) 1090 *lists = (*lists).add("checkpoint/registerHeight", height) 1091 } 1092 } 1093 }, func(recv keyValueMap) error { 1094 p.server = recv.get("flowControl/MRR", nil) == nil 1095 if p.server { 1096 p.announceType = announceTypeNone // connected to another server, send no messages 1097 } else { 1098 if recv.get("announceType", &p.announceType) != nil { 1099 // set default announceType on server side 1100 p.announceType = announceTypeSimple 1101 } 1102 } 1103 return nil 1104 }) 1105 } 1106 1107 func (p *clientPeer) bumpInvalid() { 1108 p.invalidLock.Lock() 1109 p.invalidCount.Add(1, mclock.Now()) 1110 p.invalidLock.Unlock() 1111 } 1112 1113 func (p *clientPeer) getInvalid() uint64 { 1114 p.invalidLock.RLock() 1115 defer p.invalidLock.RUnlock() 1116 return p.invalidCount.Value(mclock.Now()) 1117 } 1118 1119 // Disconnect implements vfs.clientPeer 1120 func (p *clientPeer) Disconnect() { 1121 p.Peer.Disconnect(p2p.DiscRequested) 1122 } 1123 1124 // serverPeerSubscriber is an interface to notify services about added or 1125 // removed server peers 1126 type serverPeerSubscriber interface { 1127 registerPeer(*serverPeer) 1128 unregisterPeer(*serverPeer) 1129 } 1130 1131 // serverPeerSet represents the set of active server peers currently 1132 // participating in the Light Ethereum sub-protocol. 1133 type serverPeerSet struct { 1134 peers map[string]*serverPeer 1135 // subscribers is a batch of subscribers and peerset will notify 1136 // these subscribers when the peerset changes(new server peer is 1137 // added or removed) 1138 subscribers []serverPeerSubscriber 1139 closed bool 1140 lock sync.RWMutex 1141 } 1142 1143 // newServerPeerSet creates a new peer set to track the active server peers. 1144 func newServerPeerSet() *serverPeerSet { 1145 return &serverPeerSet{peers: make(map[string]*serverPeer)} 1146 } 1147 1148 // subscribe adds a service to be notified about added or removed 1149 // peers and also register all active peers into the given service. 1150 func (ps *serverPeerSet) subscribe(sub serverPeerSubscriber) { 1151 ps.lock.Lock() 1152 defer ps.lock.Unlock() 1153 1154 ps.subscribers = append(ps.subscribers, sub) 1155 for _, p := range ps.peers { 1156 sub.registerPeer(p) 1157 } 1158 } 1159 1160 // unSubscribe removes the specified service from the subscriber pool. 1161 func (ps *serverPeerSet) unSubscribe(sub serverPeerSubscriber) { 1162 ps.lock.Lock() 1163 defer ps.lock.Unlock() 1164 1165 for i, s := range ps.subscribers { 1166 if s == sub { 1167 ps.subscribers = append(ps.subscribers[:i], ps.subscribers[i+1:]...) 1168 return 1169 } 1170 } 1171 } 1172 1173 // register adds a new server peer into the set, or returns an error if the 1174 // peer is already known. 1175 func (ps *serverPeerSet) register(peer *serverPeer) error { 1176 ps.lock.Lock() 1177 defer ps.lock.Unlock() 1178 1179 if ps.closed { 1180 return errClosed 1181 } 1182 if _, exist := ps.peers[peer.id]; exist { 1183 return errAlreadyRegistered 1184 } 1185 ps.peers[peer.id] = peer 1186 for _, sub := range ps.subscribers { 1187 sub.registerPeer(peer) 1188 } 1189 return nil 1190 } 1191 1192 // unregister removes a remote peer from the active set, disabling any further 1193 // actions to/from that particular entity. It also initiates disconnection at 1194 // the networking layer. 1195 func (ps *serverPeerSet) unregister(id string) error { 1196 ps.lock.Lock() 1197 defer ps.lock.Unlock() 1198 1199 p, ok := ps.peers[id] 1200 if !ok { 1201 return errNotRegistered 1202 } 1203 delete(ps.peers, id) 1204 for _, sub := range ps.subscribers { 1205 sub.unregisterPeer(p) 1206 } 1207 p.Peer.Disconnect(p2p.DiscRequested) 1208 return nil 1209 } 1210 1211 // ids returns a list of all registered peer IDs 1212 func (ps *serverPeerSet) ids() []string { 1213 ps.lock.RLock() 1214 defer ps.lock.RUnlock() 1215 1216 var ids []string 1217 for id := range ps.peers { 1218 ids = append(ids, id) 1219 } 1220 return ids 1221 } 1222 1223 // peer retrieves the registered peer with the given id. 1224 func (ps *serverPeerSet) peer(id string) *serverPeer { 1225 ps.lock.RLock() 1226 defer ps.lock.RUnlock() 1227 1228 return ps.peers[id] 1229 } 1230 1231 // len returns if the current number of peers in the set. 1232 func (ps *serverPeerSet) len() int { 1233 ps.lock.RLock() 1234 defer ps.lock.RUnlock() 1235 1236 return len(ps.peers) 1237 } 1238 1239 // bestPeer retrieves the known peer with the currently highest total difficulty. 1240 // If the peerset is "client peer set", then nothing meaningful will return. The 1241 // reason is client peer never send back their latest status to server. 1242 func (ps *serverPeerSet) bestPeer() *serverPeer { 1243 ps.lock.RLock() 1244 defer ps.lock.RUnlock() 1245 1246 var ( 1247 bestPeer *serverPeer 1248 bestTd *big.Int 1249 ) 1250 for _, p := range ps.peers { 1251 if td := p.Td(); bestTd == nil || td.Cmp(bestTd) > 0 { 1252 bestPeer, bestTd = p, td 1253 } 1254 } 1255 return bestPeer 1256 } 1257 1258 // allServerPeers returns all server peers in a list. 1259 func (ps *serverPeerSet) allPeers() []*serverPeer { 1260 ps.lock.RLock() 1261 defer ps.lock.RUnlock() 1262 1263 list := make([]*serverPeer, 0, len(ps.peers)) 1264 for _, p := range ps.peers { 1265 list = append(list, p) 1266 } 1267 return list 1268 } 1269 1270 // close disconnects all peers. No new peers can be registered 1271 // after close has returned. 1272 func (ps *serverPeerSet) close() { 1273 ps.lock.Lock() 1274 defer ps.lock.Unlock() 1275 1276 for _, p := range ps.peers { 1277 p.Disconnect(p2p.DiscQuitting) 1278 } 1279 ps.closed = true 1280 } 1281 1282 // clientPeerSet represents the set of active client peers currently 1283 // participating in the Light Ethereum sub-protocol. 1284 type clientPeerSet struct { 1285 peers map[enode.ID]*clientPeer 1286 lock sync.RWMutex 1287 closed bool 1288 1289 privateKey *ecdsa.PrivateKey 1290 lastAnnounce, signedAnnounce announceData 1291 } 1292 1293 // newClientPeerSet creates a new peer set to track the client peers. 1294 func newClientPeerSet() *clientPeerSet { 1295 return &clientPeerSet{peers: make(map[enode.ID]*clientPeer)} 1296 } 1297 1298 // register adds a new peer into the peer set, or returns an error if the 1299 // peer is already known. 1300 func (ps *clientPeerSet) register(peer *clientPeer) error { 1301 ps.lock.Lock() 1302 defer ps.lock.Unlock() 1303 1304 if ps.closed { 1305 return errClosed 1306 } 1307 if _, exist := ps.peers[peer.ID()]; exist { 1308 return errAlreadyRegistered 1309 } 1310 ps.peers[peer.ID()] = peer 1311 ps.announceOrStore(peer) 1312 return nil 1313 } 1314 1315 // unregister removes a remote peer from the peer set, disabling any further 1316 // actions to/from that particular entity. It also initiates disconnection 1317 // at the networking layer. 1318 func (ps *clientPeerSet) unregister(id enode.ID) error { 1319 ps.lock.Lock() 1320 defer ps.lock.Unlock() 1321 1322 p, ok := ps.peers[id] 1323 if !ok { 1324 return errNotRegistered 1325 } 1326 delete(ps.peers, id) 1327 p.Peer.Disconnect(p2p.DiscRequested) 1328 return nil 1329 } 1330 1331 // ids returns a list of all registered peer IDs 1332 func (ps *clientPeerSet) ids() []enode.ID { 1333 ps.lock.RLock() 1334 defer ps.lock.RUnlock() 1335 1336 var ids []enode.ID 1337 for id := range ps.peers { 1338 ids = append(ids, id) 1339 } 1340 return ids 1341 } 1342 1343 // peer retrieves the registered peer with the given id. 1344 func (ps *clientPeerSet) peer(id enode.ID) *clientPeer { 1345 ps.lock.RLock() 1346 defer ps.lock.RUnlock() 1347 1348 return ps.peers[id] 1349 } 1350 1351 // len returns if the current number of peers in the set. 1352 func (ps *clientPeerSet) len() int { 1353 ps.lock.RLock() 1354 defer ps.lock.RUnlock() 1355 1356 return len(ps.peers) 1357 } 1358 1359 // setSignerKey sets the signer key for signed announcements. Should be called before 1360 // starting the protocol handler. 1361 func (ps *clientPeerSet) setSignerKey(privateKey *ecdsa.PrivateKey) { 1362 ps.privateKey = privateKey 1363 } 1364 1365 // broadcast sends the given announcements to all active peers 1366 func (ps *clientPeerSet) broadcast(announce announceData) { 1367 ps.lock.Lock() 1368 defer ps.lock.Unlock() 1369 1370 ps.lastAnnounce = announce 1371 for _, peer := range ps.peers { 1372 ps.announceOrStore(peer) 1373 } 1374 } 1375 1376 // announceOrStore sends the requested type of announcement to the given peer or stores 1377 // it for later if the peer is inactive (capacity == 0). 1378 func (ps *clientPeerSet) announceOrStore(p *clientPeer) { 1379 if ps.lastAnnounce.Td == nil { 1380 return 1381 } 1382 switch p.announceType { 1383 case announceTypeSimple: 1384 p.announceOrStore(ps.lastAnnounce) 1385 case announceTypeSigned: 1386 if ps.signedAnnounce.Hash != ps.lastAnnounce.Hash { 1387 ps.signedAnnounce = ps.lastAnnounce 1388 ps.signedAnnounce.sign(ps.privateKey) 1389 } 1390 p.announceOrStore(ps.signedAnnounce) 1391 } 1392 } 1393 1394 // close disconnects all peers. No new peers can be registered 1395 // after close has returned. 1396 func (ps *clientPeerSet) close() { 1397 ps.lock.Lock() 1398 defer ps.lock.Unlock() 1399 1400 for _, p := range ps.peers { 1401 p.Peer.Disconnect(p2p.DiscQuitting) 1402 } 1403 ps.closed = true 1404 } 1405 1406 // serverSet is a special set which contains all connected les servers. 1407 // Les servers will also be discovered by discovery protocol because they 1408 // also run the LES protocol. We can't drop them although they are useless 1409 // for us(server) but for other protocols(e.g. ETH) upon the devp2p they 1410 // may be useful. 1411 type serverSet struct { 1412 lock sync.Mutex 1413 set map[string]*clientPeer 1414 closed bool 1415 } 1416 1417 func newServerSet() *serverSet { 1418 return &serverSet{set: make(map[string]*clientPeer)} 1419 } 1420 1421 func (s *serverSet) register(peer *clientPeer) error { 1422 s.lock.Lock() 1423 defer s.lock.Unlock() 1424 1425 if s.closed { 1426 return errClosed 1427 } 1428 if _, exist := s.set[peer.id]; exist { 1429 return errAlreadyRegistered 1430 } 1431 s.set[peer.id] = peer 1432 return nil 1433 } 1434 1435 func (s *serverSet) unregister(peer *clientPeer) error { 1436 s.lock.Lock() 1437 defer s.lock.Unlock() 1438 1439 if s.closed { 1440 return errClosed 1441 } 1442 if _, exist := s.set[peer.id]; !exist { 1443 return errNotRegistered 1444 } 1445 delete(s.set, peer.id) 1446 peer.Peer.Disconnect(p2p.DiscQuitting) 1447 return nil 1448 } 1449 1450 func (s *serverSet) close() { 1451 s.lock.Lock() 1452 defer s.lock.Unlock() 1453 1454 for _, p := range s.set { 1455 p.Peer.Disconnect(p2p.DiscQuitting) 1456 } 1457 s.closed = true 1458 }