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