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