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