github.com/YoungNK/go-ethereum@v1.9.7/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/ethereum/go-ethereum/common" 30 "github.com/ethereum/go-ethereum/common/mclock" 31 "github.com/ethereum/go-ethereum/core" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/eth" 34 "github.com/ethereum/go-ethereum/les/flowcontrol" 35 "github.com/ethereum/go-ethereum/light" 36 "github.com/ethereum/go-ethereum/p2p" 37 "github.com/ethereum/go-ethereum/p2p/enode" 38 "github.com/ethereum/go-ethereum/params" 39 "github.com/ethereum/go-ethereum/rlp" 40 ) 41 42 var ( 43 errClosed = errors.New("peer set is closed") 44 errAlreadyRegistered = errors.New("peer is already registered") 45 errNotRegistered = errors.New("peer is not registered") 46 ) 47 48 const ( 49 maxRequestErrors = 20 // number of invalid requests tolerated (makes the protocol less brittle but still avoids spam) 50 maxResponseErrors = 50 // number of invalid responses tolerated (makes the protocol less brittle but still avoids spam) 51 ) 52 53 // capacity limitation for parameter updates 54 const ( 55 allowedUpdateBytes = 100000 // initial/maximum allowed update size 56 allowedUpdateRate = time.Millisecond * 10 // time constant for recharging one byte of allowance 57 ) 58 59 const ( 60 freezeTimeBase = time.Millisecond * 700 // fixed component of client freeze time 61 freezeTimeRandom = time.Millisecond * 600 // random component of client freeze time 62 freezeCheckPeriod = time.Millisecond * 100 // buffer value recheck period after initial freeze time has elapsed 63 ) 64 65 // if the total encoded size of a sent transaction batch is over txSizeCostLimit 66 // per transaction then the request cost is calculated as proportional to the 67 // encoded size instead of the transaction count 68 const txSizeCostLimit = 0x4000 69 70 const ( 71 announceTypeNone = iota 72 announceTypeSimple 73 announceTypeSigned 74 ) 75 76 type peer struct { 77 *p2p.Peer 78 rw p2p.MsgReadWriter 79 80 version int // Protocol version negotiated 81 network uint64 // Network ID being on 82 83 announceType uint64 84 85 // Checkpoint relative fields 86 checkpoint params.TrustedCheckpoint 87 checkpointNumber uint64 88 89 id string 90 91 headInfo *announceData 92 lock sync.RWMutex 93 94 sendQueue *execQueue 95 96 errCh chan error 97 98 // responseLock ensures that responses are queued in the same order as 99 // RequestProcessed is called 100 responseLock sync.Mutex 101 responseCount uint64 102 invalidCount uint32 103 104 poolEntry *poolEntry 105 hasBlock func(common.Hash, uint64, bool) bool 106 responseErrors int 107 updateCounter uint64 108 updateTime mclock.AbsTime 109 frozen uint32 // 1 if client is in frozen state 110 111 fcClient *flowcontrol.ClientNode // nil if the peer is server only 112 fcServer *flowcontrol.ServerNode // nil if the peer is client only 113 fcParams flowcontrol.ServerParams 114 fcCosts requestCostTable 115 116 trusted bool 117 onlyAnnounce bool 118 chainSince, chainRecent uint64 119 stateSince, stateRecent uint64 120 } 121 122 func newPeer(version int, network uint64, trusted bool, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { 123 return &peer{ 124 Peer: p, 125 rw: rw, 126 version: version, 127 network: network, 128 id: peerIdToString(p.ID()), 129 trusted: trusted, 130 errCh: make(chan error, 1), 131 } 132 } 133 134 // peerIdToString converts enode.ID to a string form 135 func peerIdToString(id enode.ID) string { 136 return fmt.Sprintf("%x", id.Bytes()) 137 } 138 139 // freeClientId returns a string identifier for the peer. Multiple peers with the 140 // same identifier can not be connected in free mode simultaneously. 141 func (p *peer) freeClientId() string { 142 if addr, ok := p.RemoteAddr().(*net.TCPAddr); ok { 143 if addr.IP.IsLoopback() { 144 // using peer id instead of loopback ip address allows multiple free 145 // connections from local machine to own server 146 return p.id 147 } else { 148 return addr.IP.String() 149 } 150 } 151 return p.id 152 } 153 154 // rejectUpdate returns true if a parameter update has to be rejected because 155 // the size and/or rate of updates exceed the capacity limitation 156 func (p *peer) rejectUpdate(size uint64) bool { 157 now := mclock.Now() 158 if p.updateCounter == 0 { 159 p.updateTime = now 160 } else { 161 dt := now - p.updateTime 162 r := uint64(dt / mclock.AbsTime(allowedUpdateRate)) 163 if p.updateCounter > r { 164 p.updateCounter -= r 165 p.updateTime += mclock.AbsTime(allowedUpdateRate * time.Duration(r)) 166 } else { 167 p.updateCounter = 0 168 p.updateTime = now 169 } 170 } 171 p.updateCounter += size 172 return p.updateCounter > allowedUpdateBytes 173 } 174 175 // freezeClient temporarily puts the client in a frozen state which means all 176 // unprocessed and subsequent requests are dropped. Unfreezing happens automatically 177 // after a short time if the client's buffer value is at least in the slightly positive 178 // region. The client is also notified about being frozen/unfrozen with a Stop/Resume 179 // message. 180 func (p *peer) freezeClient() { 181 if p.version < lpv3 { 182 // if Stop/Resume is not supported then just drop the peer after setting 183 // its frozen status permanently 184 atomic.StoreUint32(&p.frozen, 1) 185 p.Peer.Disconnect(p2p.DiscUselessPeer) 186 return 187 } 188 if atomic.SwapUint32(&p.frozen, 1) == 0 { 189 go func() { 190 p.SendStop() 191 time.Sleep(freezeTimeBase + time.Duration(rand.Int63n(int64(freezeTimeRandom)))) 192 for { 193 bufValue, bufLimit := p.fcClient.BufferStatus() 194 if bufLimit == 0 { 195 return 196 } 197 if bufValue <= bufLimit/8 { 198 time.Sleep(freezeCheckPeriod) 199 } else { 200 atomic.StoreUint32(&p.frozen, 0) 201 p.SendResume(bufValue) 202 break 203 } 204 } 205 }() 206 } 207 } 208 209 // freezeServer processes Stop/Resume messages from the given server 210 func (p *peer) freezeServer(frozen bool) { 211 var f uint32 212 if frozen { 213 f = 1 214 } 215 if atomic.SwapUint32(&p.frozen, f) != f && frozen { 216 p.sendQueue.clear() 217 } 218 } 219 220 // isFrozen returns true if the client is frozen or the server has put our 221 // client in frozen state 222 func (p *peer) isFrozen() bool { 223 return atomic.LoadUint32(&p.frozen) != 0 224 } 225 226 func (p *peer) canQueue() bool { 227 return p.sendQueue.canQueue() && !p.isFrozen() 228 } 229 230 func (p *peer) queueSend(f func()) { 231 p.sendQueue.queue(f) 232 } 233 234 // Info gathers and returns a collection of metadata known about a peer. 235 func (p *peer) Info() *eth.PeerInfo { 236 return ð.PeerInfo{ 237 Version: p.version, 238 Difficulty: p.Td(), 239 Head: fmt.Sprintf("%x", p.Head()), 240 } 241 } 242 243 // Head retrieves a copy of the current head (most recent) hash of the peer. 244 func (p *peer) Head() (hash common.Hash) { 245 p.lock.RLock() 246 defer p.lock.RUnlock() 247 248 copy(hash[:], p.headInfo.Hash[:]) 249 return hash 250 } 251 252 func (p *peer) HeadAndTd() (hash common.Hash, td *big.Int) { 253 p.lock.RLock() 254 defer p.lock.RUnlock() 255 256 copy(hash[:], p.headInfo.Hash[:]) 257 return hash, p.headInfo.Td 258 } 259 260 func (p *peer) headBlockInfo() blockInfo { 261 p.lock.RLock() 262 defer p.lock.RUnlock() 263 264 return blockInfo{Hash: p.headInfo.Hash, Number: p.headInfo.Number, Td: p.headInfo.Td} 265 } 266 267 // Td retrieves the current total difficulty of a peer. 268 func (p *peer) Td() *big.Int { 269 p.lock.RLock() 270 defer p.lock.RUnlock() 271 272 return new(big.Int).Set(p.headInfo.Td) 273 } 274 275 // waitBefore implements distPeer interface 276 func (p *peer) waitBefore(maxCost uint64) (time.Duration, float64) { 277 return p.fcServer.CanSend(maxCost) 278 } 279 280 // updateCapacity updates the request serving capacity assigned to a given client 281 // and also sends an announcement about the updated flow control parameters 282 func (p *peer) updateCapacity(cap uint64) { 283 p.responseLock.Lock() 284 defer p.responseLock.Unlock() 285 286 p.fcParams = flowcontrol.ServerParams{MinRecharge: cap, BufLimit: cap * bufLimitRatio} 287 p.fcClient.UpdateParams(p.fcParams) 288 var kvList keyValueList 289 kvList = kvList.add("flowControl/MRR", cap) 290 kvList = kvList.add("flowControl/BL", cap*bufLimitRatio) 291 p.queueSend(func() { p.SendAnnounce(announceData{Update: kvList}) }) 292 } 293 294 func (p *peer) responseID() uint64 { 295 p.responseCount += 1 296 return p.responseCount 297 } 298 299 func sendRequest(w p2p.MsgWriter, msgcode, reqID, cost uint64, data interface{}) error { 300 type req struct { 301 ReqID uint64 302 Data interface{} 303 } 304 return p2p.Send(w, msgcode, req{reqID, data}) 305 } 306 307 // reply struct represents a reply with the actual data already RLP encoded and 308 // only the bv (buffer value) missing. This allows the serving mechanism to 309 // calculate the bv value which depends on the data size before sending the reply. 310 type reply struct { 311 w p2p.MsgWriter 312 msgcode, reqID uint64 313 data rlp.RawValue 314 } 315 316 // send sends the reply with the calculated buffer value 317 func (r *reply) send(bv uint64) error { 318 type resp struct { 319 ReqID, BV uint64 320 Data rlp.RawValue 321 } 322 return p2p.Send(r.w, r.msgcode, resp{r.reqID, bv, r.data}) 323 } 324 325 // size returns the RLP encoded size of the message data 326 func (r *reply) size() uint32 { 327 return uint32(len(r.data)) 328 } 329 330 func (p *peer) GetRequestCost(msgcode uint64, amount int) uint64 { 331 p.lock.RLock() 332 defer p.lock.RUnlock() 333 334 costs := p.fcCosts[msgcode] 335 if costs == nil { 336 return 0 337 } 338 cost := costs.baseCost + costs.reqCost*uint64(amount) 339 if cost > p.fcParams.BufLimit { 340 cost = p.fcParams.BufLimit 341 } 342 return cost 343 } 344 345 func (p *peer) GetTxRelayCost(amount, size int) uint64 { 346 p.lock.RLock() 347 defer p.lock.RUnlock() 348 349 costs := p.fcCosts[SendTxV2Msg] 350 if costs == nil { 351 return 0 352 } 353 cost := costs.baseCost + costs.reqCost*uint64(amount) 354 sizeCost := costs.baseCost + costs.reqCost*uint64(size)/txSizeCostLimit 355 if sizeCost > cost { 356 cost = sizeCost 357 } 358 359 if cost > p.fcParams.BufLimit { 360 cost = p.fcParams.BufLimit 361 } 362 return cost 363 } 364 365 // HasBlock checks if the peer has a given block 366 func (p *peer) HasBlock(hash common.Hash, number uint64, hasState bool) bool { 367 var head, since, recent uint64 368 p.lock.RLock() 369 if p.headInfo != nil { 370 head = p.headInfo.Number 371 } 372 if hasState { 373 since = p.stateSince 374 recent = p.stateRecent 375 } else { 376 since = p.chainSince 377 recent = p.chainRecent 378 } 379 hasBlock := p.hasBlock 380 p.lock.RUnlock() 381 382 return head >= number && number >= since && (recent == 0 || number+recent+4 > head) && hasBlock != nil && hasBlock(hash, number, hasState) 383 } 384 385 // SendAnnounce announces the availability of a number of blocks through 386 // a hash notification. 387 func (p *peer) SendAnnounce(request announceData) error { 388 return p2p.Send(p.rw, AnnounceMsg, request) 389 } 390 391 // SendStop notifies the client about being in frozen state 392 func (p *peer) SendStop() error { 393 return p2p.Send(p.rw, StopMsg, struct{}{}) 394 } 395 396 // SendResume notifies the client about getting out of frozen state 397 func (p *peer) SendResume(bv uint64) error { 398 return p2p.Send(p.rw, ResumeMsg, bv) 399 } 400 401 // ReplyBlockHeaders creates a reply with a batch of block headers 402 func (p *peer) ReplyBlockHeaders(reqID uint64, headers []*types.Header) *reply { 403 data, _ := rlp.EncodeToBytes(headers) 404 return &reply{p.rw, BlockHeadersMsg, reqID, data} 405 } 406 407 // ReplyBlockBodiesRLP creates a reply with a batch of block contents from 408 // an already RLP encoded format. 409 func (p *peer) ReplyBlockBodiesRLP(reqID uint64, bodies []rlp.RawValue) *reply { 410 data, _ := rlp.EncodeToBytes(bodies) 411 return &reply{p.rw, BlockBodiesMsg, reqID, data} 412 } 413 414 // ReplyCode creates a reply with a batch of arbitrary internal data, corresponding to the 415 // hashes requested. 416 func (p *peer) ReplyCode(reqID uint64, codes [][]byte) *reply { 417 data, _ := rlp.EncodeToBytes(codes) 418 return &reply{p.rw, CodeMsg, reqID, data} 419 } 420 421 // ReplyReceiptsRLP creates a reply with a batch of transaction receipts, corresponding to the 422 // ones requested from an already RLP encoded format. 423 func (p *peer) ReplyReceiptsRLP(reqID uint64, receipts []rlp.RawValue) *reply { 424 data, _ := rlp.EncodeToBytes(receipts) 425 return &reply{p.rw, ReceiptsMsg, reqID, data} 426 } 427 428 // ReplyProofsV2 creates a reply with a batch of merkle proofs, corresponding to the ones requested. 429 func (p *peer) ReplyProofsV2(reqID uint64, proofs light.NodeList) *reply { 430 data, _ := rlp.EncodeToBytes(proofs) 431 return &reply{p.rw, ProofsV2Msg, reqID, data} 432 } 433 434 // ReplyHelperTrieProofs creates a reply with a batch of HelperTrie proofs, corresponding to the ones requested. 435 func (p *peer) ReplyHelperTrieProofs(reqID uint64, resp HelperTrieResps) *reply { 436 data, _ := rlp.EncodeToBytes(resp) 437 return &reply{p.rw, HelperTrieProofsMsg, reqID, data} 438 } 439 440 // ReplyTxStatus creates a reply with a batch of transaction status records, corresponding to the ones requested. 441 func (p *peer) ReplyTxStatus(reqID uint64, stats []light.TxStatus) *reply { 442 data, _ := rlp.EncodeToBytes(stats) 443 return &reply{p.rw, TxStatusMsg, reqID, data} 444 } 445 446 // RequestHeadersByHash fetches a batch of blocks' headers corresponding to the 447 // specified header query, based on the hash of an origin block. 448 func (p *peer) RequestHeadersByHash(reqID, cost uint64, origin common.Hash, amount int, skip int, reverse bool) error { 449 p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse) 450 return sendRequest(p.rw, GetBlockHeadersMsg, reqID, cost, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 451 } 452 453 // RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the 454 // specified header query, based on the number of an origin block. 455 func (p *peer) RequestHeadersByNumber(reqID, cost, origin uint64, amount int, skip int, reverse bool) error { 456 p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse) 457 return sendRequest(p.rw, GetBlockHeadersMsg, reqID, cost, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 458 } 459 460 // RequestBodies fetches a batch of blocks' bodies corresponding to the hashes 461 // specified. 462 func (p *peer) RequestBodies(reqID, cost uint64, hashes []common.Hash) error { 463 p.Log().Debug("Fetching batch of block bodies", "count", len(hashes)) 464 return sendRequest(p.rw, GetBlockBodiesMsg, reqID, cost, hashes) 465 } 466 467 // RequestCode fetches a batch of arbitrary data from a node's known state 468 // data, corresponding to the specified hashes. 469 func (p *peer) RequestCode(reqID, cost uint64, reqs []CodeReq) error { 470 p.Log().Debug("Fetching batch of codes", "count", len(reqs)) 471 return sendRequest(p.rw, GetCodeMsg, reqID, cost, reqs) 472 } 473 474 // RequestReceipts fetches a batch of transaction receipts from a remote node. 475 func (p *peer) RequestReceipts(reqID, cost uint64, hashes []common.Hash) error { 476 p.Log().Debug("Fetching batch of receipts", "count", len(hashes)) 477 return sendRequest(p.rw, GetReceiptsMsg, reqID, cost, hashes) 478 } 479 480 // RequestProofs fetches a batch of merkle proofs from a remote node. 481 func (p *peer) RequestProofs(reqID, cost uint64, reqs []ProofReq) error { 482 p.Log().Debug("Fetching batch of proofs", "count", len(reqs)) 483 return sendRequest(p.rw, GetProofsV2Msg, reqID, cost, reqs) 484 } 485 486 // RequestHelperTrieProofs fetches a batch of HelperTrie merkle proofs from a remote node. 487 func (p *peer) RequestHelperTrieProofs(reqID, cost uint64, reqs []HelperTrieReq) error { 488 p.Log().Debug("Fetching batch of HelperTrie proofs", "count", len(reqs)) 489 return sendRequest(p.rw, GetHelperTrieProofsMsg, reqID, cost, reqs) 490 } 491 492 // RequestTxStatus fetches a batch of transaction status records from a remote node. 493 func (p *peer) RequestTxStatus(reqID, cost uint64, txHashes []common.Hash) error { 494 p.Log().Debug("Requesting transaction status", "count", len(txHashes)) 495 return sendRequest(p.rw, GetTxStatusMsg, reqID, cost, txHashes) 496 } 497 498 // SendTxStatus creates a reply with a batch of transactions to be added to the remote transaction pool. 499 func (p *peer) SendTxs(reqID, cost uint64, txs rlp.RawValue) error { 500 p.Log().Debug("Sending batch of transactions", "size", len(txs)) 501 return sendRequest(p.rw, SendTxV2Msg, reqID, cost, txs) 502 } 503 504 type keyValueEntry struct { 505 Key string 506 Value rlp.RawValue 507 } 508 type keyValueList []keyValueEntry 509 type keyValueMap map[string]rlp.RawValue 510 511 func (l keyValueList) add(key string, val interface{}) keyValueList { 512 var entry keyValueEntry 513 entry.Key = key 514 if val == nil { 515 val = uint64(0) 516 } 517 enc, err := rlp.EncodeToBytes(val) 518 if err == nil { 519 entry.Value = enc 520 } 521 return append(l, entry) 522 } 523 524 func (l keyValueList) decode() (keyValueMap, uint64) { 525 m := make(keyValueMap) 526 var size uint64 527 for _, entry := range l { 528 m[entry.Key] = entry.Value 529 size += uint64(len(entry.Key)) + uint64(len(entry.Value)) + 8 530 } 531 return m, size 532 } 533 534 func (m keyValueMap) get(key string, val interface{}) error { 535 enc, ok := m[key] 536 if !ok { 537 return errResp(ErrMissingKey, "%s", key) 538 } 539 if val == nil { 540 return nil 541 } 542 return rlp.DecodeBytes(enc, val) 543 } 544 545 func (p *peer) sendReceiveHandshake(sendList keyValueList) (keyValueList, error) { 546 // Send out own handshake in a new thread 547 errc := make(chan error, 1) 548 go func() { 549 errc <- p2p.Send(p.rw, StatusMsg, sendList) 550 }() 551 // In the mean time retrieve the remote status message 552 msg, err := p.rw.ReadMsg() 553 if err != nil { 554 return nil, err 555 } 556 if msg.Code != StatusMsg { 557 return nil, errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) 558 } 559 if msg.Size > ProtocolMaxMsgSize { 560 return nil, errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) 561 } 562 // Decode the handshake 563 var recvList keyValueList 564 if err := msg.Decode(&recvList); err != nil { 565 return nil, errResp(ErrDecode, "msg %v: %v", msg, err) 566 } 567 if err := <-errc; err != nil { 568 return nil, err 569 } 570 return recvList, nil 571 } 572 573 // Handshake executes the les protocol handshake, negotiating version number, 574 // network IDs, difficulties, head and genesis blocks. 575 func (p *peer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, server *LesServer) error { 576 p.lock.Lock() 577 defer p.lock.Unlock() 578 579 var send keyValueList 580 581 // Add some basic handshake fields 582 send = send.add("protocolVersion", uint64(p.version)) 583 send = send.add("networkId", p.network) 584 send = send.add("headTd", td) 585 send = send.add("headHash", head) 586 send = send.add("headNum", headNum) 587 send = send.add("genesisHash", genesis) 588 if server != nil { 589 // Add some information which services server can offer. 590 if !server.config.UltraLightOnlyAnnounce { 591 send = send.add("serveHeaders", nil) 592 send = send.add("serveChainSince", uint64(0)) 593 send = send.add("serveStateSince", uint64(0)) 594 595 // If local ethereum node is running in archive mode, advertise ourselves we have 596 // all version state data. Otherwise only recent state is available. 597 stateRecent := uint64(core.TriesInMemory - 4) 598 if server.archiveMode { 599 stateRecent = 0 600 } 601 send = send.add("serveRecentState", stateRecent) 602 send = send.add("txRelay", nil) 603 } 604 send = send.add("flowControl/BL", server.defParams.BufLimit) 605 send = send.add("flowControl/MRR", server.defParams.MinRecharge) 606 607 var costList RequestCostList 608 if server.costTracker.testCostList != nil { 609 costList = server.costTracker.testCostList 610 } else { 611 costList = server.costTracker.makeCostList(server.costTracker.globalFactor()) 612 } 613 send = send.add("flowControl/MRC", costList) 614 p.fcCosts = costList.decode(ProtocolLengths[uint(p.version)]) 615 p.fcParams = server.defParams 616 617 // Add advertised checkpoint and register block height which 618 // client can verify the checkpoint validity. 619 if server.oracle != nil && server.oracle.isRunning() { 620 cp, height := server.oracle.stableCheckpoint() 621 if cp != nil { 622 send = send.add("checkpoint/value", cp) 623 send = send.add("checkpoint/registerHeight", height) 624 } 625 } 626 } else { 627 // Add some client-specific handshake fields 628 p.announceType = announceTypeSimple 629 if p.trusted { 630 p.announceType = announceTypeSigned 631 } 632 send = send.add("announceType", p.announceType) 633 } 634 635 recvList, err := p.sendReceiveHandshake(send) 636 if err != nil { 637 return err 638 } 639 recv, size := recvList.decode() 640 if p.rejectUpdate(size) { 641 return errResp(ErrRequestRejected, "") 642 } 643 644 var rGenesis, rHash common.Hash 645 var rVersion, rNetwork, rNum uint64 646 var rTd *big.Int 647 648 if err := recv.get("protocolVersion", &rVersion); err != nil { 649 return err 650 } 651 if err := recv.get("networkId", &rNetwork); err != nil { 652 return err 653 } 654 if err := recv.get("headTd", &rTd); err != nil { 655 return err 656 } 657 if err := recv.get("headHash", &rHash); err != nil { 658 return err 659 } 660 if err := recv.get("headNum", &rNum); err != nil { 661 return err 662 } 663 if err := recv.get("genesisHash", &rGenesis); err != nil { 664 return err 665 } 666 667 if rGenesis != genesis { 668 return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", rGenesis[:8], genesis[:8]) 669 } 670 if rNetwork != p.network { 671 return errResp(ErrNetworkIdMismatch, "%d (!= %d)", rNetwork, p.network) 672 } 673 if int(rVersion) != p.version { 674 return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", rVersion, p.version) 675 } 676 677 if server != nil { 678 if recv.get("announceType", &p.announceType) != nil { 679 // set default announceType on server side 680 p.announceType = announceTypeSimple 681 } 682 p.fcClient = flowcontrol.NewClientNode(server.fcManager, server.defParams) 683 } else { 684 if recv.get("serveChainSince", &p.chainSince) != nil { 685 p.onlyAnnounce = true 686 } 687 if recv.get("serveRecentChain", &p.chainRecent) != nil { 688 p.chainRecent = 0 689 } 690 if recv.get("serveStateSince", &p.stateSince) != nil { 691 p.onlyAnnounce = true 692 } 693 if recv.get("serveRecentState", &p.stateRecent) != nil { 694 p.stateRecent = 0 695 } 696 if recv.get("txRelay", nil) != nil { 697 p.onlyAnnounce = true 698 } 699 700 if p.onlyAnnounce && !p.trusted { 701 return errResp(ErrUselessPeer, "peer cannot serve requests") 702 } 703 704 var sParams flowcontrol.ServerParams 705 if err := recv.get("flowControl/BL", &sParams.BufLimit); err != nil { 706 return err 707 } 708 if err := recv.get("flowControl/MRR", &sParams.MinRecharge); err != nil { 709 return err 710 } 711 var MRC RequestCostList 712 if err := recv.get("flowControl/MRC", &MRC); err != nil { 713 return err 714 } 715 p.fcParams = sParams 716 p.fcServer = flowcontrol.NewServerNode(sParams, &mclock.System{}) 717 p.fcCosts = MRC.decode(ProtocolLengths[uint(p.version)]) 718 719 recv.get("checkpoint/value", &p.checkpoint) 720 recv.get("checkpoint/registerHeight", &p.checkpointNumber) 721 722 if !p.onlyAnnounce { 723 for msgCode := range reqAvgTimeCost { 724 if p.fcCosts[msgCode] == nil { 725 return errResp(ErrUselessPeer, "peer does not support message %d", msgCode) 726 } 727 } 728 } 729 } 730 p.headInfo = &announceData{Td: rTd, Hash: rHash, Number: rNum} 731 return nil 732 } 733 734 // updateFlowControl updates the flow control parameters belonging to the server 735 // node if the announced key/value set contains relevant fields 736 func (p *peer) updateFlowControl(update keyValueMap) { 737 if p.fcServer == nil { 738 return 739 } 740 // If any of the flow control params is nil, refuse to update. 741 var params flowcontrol.ServerParams 742 if update.get("flowControl/BL", ¶ms.BufLimit) == nil && update.get("flowControl/MRR", ¶ms.MinRecharge) == nil { 743 // todo can light client set a minimal acceptable flow control params? 744 p.fcParams = params 745 p.fcServer.UpdateParams(params) 746 } 747 var MRC RequestCostList 748 if update.get("flowControl/MRC", &MRC) == nil { 749 costUpdate := MRC.decode(ProtocolLengths[uint(p.version)]) 750 for code, cost := range costUpdate { 751 p.fcCosts[code] = cost 752 } 753 } 754 } 755 756 // String implements fmt.Stringer. 757 func (p *peer) String() string { 758 return fmt.Sprintf("Peer %s [%s]", p.id, 759 fmt.Sprintf("les/%d", p.version), 760 ) 761 } 762 763 // peerSetNotify is a callback interface to notify services about added or 764 // removed peers 765 type peerSetNotify interface { 766 registerPeer(*peer) 767 unregisterPeer(*peer) 768 } 769 770 // peerSet represents the collection of active peers currently participating in 771 // the Light Ethereum sub-protocol. 772 type peerSet struct { 773 peers map[string]*peer 774 lock sync.RWMutex 775 notifyList []peerSetNotify 776 closed bool 777 } 778 779 // newPeerSet creates a new peer set to track the active participants. 780 func newPeerSet() *peerSet { 781 return &peerSet{ 782 peers: make(map[string]*peer), 783 } 784 } 785 786 // notify adds a service to be notified about added or removed peers 787 func (ps *peerSet) notify(n peerSetNotify) { 788 ps.lock.Lock() 789 ps.notifyList = append(ps.notifyList, n) 790 peers := make([]*peer, 0, len(ps.peers)) 791 for _, p := range ps.peers { 792 peers = append(peers, p) 793 } 794 ps.lock.Unlock() 795 796 for _, p := range peers { 797 n.registerPeer(p) 798 } 799 } 800 801 // Register injects a new peer into the working set, or returns an error if the 802 // peer is already known. 803 func (ps *peerSet) Register(p *peer) error { 804 ps.lock.Lock() 805 if ps.closed { 806 ps.lock.Unlock() 807 return errClosed 808 } 809 if _, ok := ps.peers[p.id]; ok { 810 ps.lock.Unlock() 811 return errAlreadyRegistered 812 } 813 ps.peers[p.id] = p 814 p.sendQueue = newExecQueue(100) 815 peers := make([]peerSetNotify, len(ps.notifyList)) 816 copy(peers, ps.notifyList) 817 ps.lock.Unlock() 818 819 for _, n := range peers { 820 n.registerPeer(p) 821 } 822 return nil 823 } 824 825 // Unregister removes a remote peer from the active set, disabling any further 826 // actions to/from that particular entity. It also initiates disconnection at the networking layer. 827 func (ps *peerSet) Unregister(id string) error { 828 ps.lock.Lock() 829 if p, ok := ps.peers[id]; !ok { 830 ps.lock.Unlock() 831 return errNotRegistered 832 } else { 833 delete(ps.peers, id) 834 peers := make([]peerSetNotify, len(ps.notifyList)) 835 copy(peers, ps.notifyList) 836 ps.lock.Unlock() 837 838 for _, n := range peers { 839 n.unregisterPeer(p) 840 } 841 842 p.sendQueue.quit() 843 p.Peer.Disconnect(p2p.DiscUselessPeer) 844 845 return nil 846 } 847 } 848 849 // AllPeerIDs returns a list of all registered peer IDs 850 func (ps *peerSet) AllPeerIDs() []string { 851 ps.lock.RLock() 852 defer ps.lock.RUnlock() 853 854 res := make([]string, len(ps.peers)) 855 idx := 0 856 for id := range ps.peers { 857 res[idx] = id 858 idx++ 859 } 860 return res 861 } 862 863 // Peer retrieves the registered peer with the given id. 864 func (ps *peerSet) Peer(id string) *peer { 865 ps.lock.RLock() 866 defer ps.lock.RUnlock() 867 868 return ps.peers[id] 869 } 870 871 // Len returns if the current number of peers in the set. 872 func (ps *peerSet) Len() int { 873 ps.lock.RLock() 874 defer ps.lock.RUnlock() 875 876 return len(ps.peers) 877 } 878 879 // BestPeer retrieves the known peer with the currently highest total difficulty. 880 func (ps *peerSet) BestPeer() *peer { 881 ps.lock.RLock() 882 defer ps.lock.RUnlock() 883 884 var ( 885 bestPeer *peer 886 bestTd *big.Int 887 ) 888 for _, p := range ps.peers { 889 if td := p.Td(); bestPeer == nil || td.Cmp(bestTd) > 0 { 890 bestPeer, bestTd = p, td 891 } 892 } 893 return bestPeer 894 } 895 896 // AllPeers returns all peers in a list 897 func (ps *peerSet) AllPeers() []*peer { 898 ps.lock.RLock() 899 defer ps.lock.RUnlock() 900 901 list := make([]*peer, len(ps.peers)) 902 i := 0 903 for _, peer := range ps.peers { 904 list[i] = peer 905 i++ 906 } 907 return list 908 } 909 910 // Close disconnects all peers. 911 // No new peers can be registered after Close has returned. 912 func (ps *peerSet) Close() { 913 ps.lock.Lock() 914 defer ps.lock.Unlock() 915 916 for _, p := range ps.peers { 917 p.Disconnect(p2p.DiscQuitting) 918 } 919 ps.closed = true 920 }