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