github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/les/handler.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:38</date>
    10  //</624450093986091008>
    11  
    12  
    13  //包les实现轻以太坊子协议。
    14  package les
    15  
    16  import (
    17  	"encoding/binary"
    18  	"encoding/json"
    19  	"fmt"
    20  	"math/big"
    21  	"net"
    22  	"sync"
    23  	"time"
    24  
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/common/mclock"
    27  	"github.com/ethereum/go-ethereum/consensus"
    28  	"github.com/ethereum/go-ethereum/core"
    29  	"github.com/ethereum/go-ethereum/core/rawdb"
    30  	"github.com/ethereum/go-ethereum/core/state"
    31  	"github.com/ethereum/go-ethereum/core/types"
    32  	"github.com/ethereum/go-ethereum/eth/downloader"
    33  	"github.com/ethereum/go-ethereum/ethdb"
    34  	"github.com/ethereum/go-ethereum/event"
    35  	"github.com/ethereum/go-ethereum/light"
    36  	"github.com/ethereum/go-ethereum/log"
    37  	"github.com/ethereum/go-ethereum/p2p"
    38  	"github.com/ethereum/go-ethereum/p2p/discv5"
    39  	"github.com/ethereum/go-ethereum/params"
    40  	"github.com/ethereum/go-ethereum/rlp"
    41  	"github.com/ethereum/go-ethereum/trie"
    42  )
    43  
    44  const (
    45  softResponseLimit = 2 * 1024 * 1024 //返回的块、头或节点数据的目标最大大小。
    46  estHeaderRlpSize  = 500             //RLP编码块头的近似大小
    47  
    48  ethVersion = 63 //下载器的等效ETH版本
    49  
    50  MaxHeaderFetch           = 192 //每个检索请求要获取的块头的数量
    51  MaxBodyFetch             = 32  //每个检索请求要获取的块体数量
    52  MaxReceiptFetch          = 128 //允许每个请求提取的事务处理收据的数量
    53  MaxCodeFetch             = 64  //允许按请求提取的合同代码量
    54  MaxProofsFetch           = 64  //每个检索请求要获取的Merkle证明的数量
    55  MaxHelperTrieProofsFetch = 64  //每个检索请求要获取的Merkle证明的数量
    56  MaxTxSend                = 64  //每个请求发送的事务量
    57  MaxTxStatus              = 256 //每个请求要查询的事务量
    58  
    59  	disableClientRemovePeer = false
    60  )
    61  
    62  func errResp(code errCode, format string, v ...interface{}) error {
    63  	return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...))
    64  }
    65  
    66  type BlockChain interface {
    67  	Config() *params.ChainConfig
    68  	HasHeader(hash common.Hash, number uint64) bool
    69  	GetHeader(hash common.Hash, number uint64) *types.Header
    70  	GetHeaderByHash(hash common.Hash) *types.Header
    71  	CurrentHeader() *types.Header
    72  	GetTd(hash common.Hash, number uint64) *big.Int
    73  	State() (*state.StateDB, error)
    74  	InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error)
    75  	Rollback(chain []common.Hash)
    76  	GetHeaderByNumber(number uint64) *types.Header
    77  	GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64)
    78  	Genesis() *types.Block
    79  	SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
    80  }
    81  
    82  type txPool interface {
    83  	AddRemotes(txs []*types.Transaction) []error
    84  	Status(hashes []common.Hash) []core.TxStatus
    85  }
    86  
    87  type ProtocolManager struct {
    88  	lightSync   bool
    89  	txpool      txPool
    90  	txrelay     *LesTxRelay
    91  	networkId   uint64
    92  	chainConfig *params.ChainConfig
    93  	iConfig     *light.IndexerConfig
    94  	blockchain  BlockChain
    95  	chainDb     ethdb.Database
    96  	odr         *LesOdr
    97  	server      *LesServer
    98  	serverPool  *serverPool
    99  	clientPool  *freeClientPool
   100  	lesTopic    discv5.Topic
   101  	reqDist     *requestDistributor
   102  	retriever   *retrieveManager
   103  
   104  	downloader *downloader.Downloader
   105  	fetcher    *lightFetcher
   106  	peers      *peerSet
   107  	maxPeers   int
   108  
   109  	eventMux *event.TypeMux
   110  
   111  //获取器、同步器、TxSyncLoop的通道
   112  	newPeerCh   chan *peer
   113  	quitSync    chan struct{}
   114  	noMorePeers chan struct{}
   115  
   116  //等待组用于在下载过程中正常关闭
   117  //加工
   118  	wg *sync.WaitGroup
   119  }
   120  
   121  //NewProtocolManager返回新的以太坊子协议管理器。以太坊子协议管理对等端
   122  //使用以太坊网络。
   123  func NewProtocolManager(chainConfig *params.ChainConfig, indexerConfig *light.IndexerConfig, lightSync bool, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, serverPool *serverPool, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) {
   124  //使用基本字段创建协议管理器
   125  	manager := &ProtocolManager{
   126  		lightSync:   lightSync,
   127  		eventMux:    mux,
   128  		blockchain:  blockchain,
   129  		chainConfig: chainConfig,
   130  		iConfig:     indexerConfig,
   131  		chainDb:     chainDb,
   132  		odr:         odr,
   133  		networkId:   networkId,
   134  		txpool:      txpool,
   135  		txrelay:     txrelay,
   136  		serverPool:  serverPool,
   137  		peers:       peers,
   138  		newPeerCh:   make(chan *peer),
   139  		quitSync:    quitSync,
   140  		wg:          wg,
   141  		noMorePeers: make(chan struct{}),
   142  	}
   143  	if odr != nil {
   144  		manager.retriever = odr.retriever
   145  		manager.reqDist = odr.retriever.dist
   146  	}
   147  
   148  	removePeer := manager.removePeer
   149  	if disableClientRemovePeer {
   150  		removePeer = func(id string) {}
   151  	}
   152  
   153  	if lightSync {
   154  		manager.downloader = downloader.New(downloader.LightSync, chainDb, manager.eventMux, nil, blockchain, removePeer)
   155  		manager.peers.notify((*downloaderPeerNotify)(manager))
   156  		manager.fetcher = newLightFetcher(manager)
   157  	}
   158  
   159  	return manager, nil
   160  }
   161  
   162  //removepeer通过从对等端集删除对等端来启动与对等端的断开连接。
   163  func (pm *ProtocolManager) removePeer(id string) {
   164  	pm.peers.Unregister(id)
   165  }
   166  
   167  func (pm *ProtocolManager) Start(maxPeers int) {
   168  	pm.maxPeers = maxPeers
   169  
   170  	if pm.lightSync {
   171  		go pm.syncer()
   172  	} else {
   173  		pm.clientPool = newFreeClientPool(pm.chainDb, maxPeers, 10000, mclock.System{})
   174  		go func() {
   175  			for range pm.newPeerCh {
   176  			}
   177  		}()
   178  	}
   179  }
   180  
   181  func (pm *ProtocolManager) Stop() {
   182  //显示日志消息。在下载/处理过程中,实际上
   183  //需要5到10秒,因此需要反馈。
   184  	log.Info("Stopping light Ethereum protocol")
   185  
   186  //退出同步循环。
   187  //完成此发送后,将不接受任何新对等方。
   188  	pm.noMorePeers <- struct{}{}
   189  
   190  close(pm.quitSync) //退出同步器,获取器
   191  	if pm.clientPool != nil {
   192  		pm.clientPool.stop()
   193  	}
   194  
   195  //断开现有会话。
   196  //这也会关闭对等集上任何新注册的入口。
   197  //已建立但尚未添加到pm.peers的会话
   198  //当他们尝试注册时将退出。
   199  	pm.peers.Close()
   200  
   201  //等待任何进程操作
   202  	pm.wg.Wait()
   203  
   204  	log.Info("Light Ethereum protocol stopped")
   205  }
   206  
   207  //runpeer是给定版本的p2p协议运行函数。
   208  func (pm *ProtocolManager) runPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) error {
   209  	var entry *poolEntry
   210  	peer := pm.newPeer(int(version), pm.networkId, p, rw)
   211  	if pm.serverPool != nil {
   212  		entry = pm.serverPool.connect(peer, peer.Node())
   213  	}
   214  	peer.poolEntry = entry
   215  	select {
   216  	case pm.newPeerCh <- peer:
   217  		pm.wg.Add(1)
   218  		defer pm.wg.Done()
   219  		err := pm.handle(peer)
   220  		if entry != nil {
   221  			pm.serverPool.disconnect(entry)
   222  		}
   223  		return err
   224  	case <-pm.quitSync:
   225  		if entry != nil {
   226  			pm.serverPool.disconnect(entry)
   227  		}
   228  		return p2p.DiscQuitting
   229  	}
   230  }
   231  
   232  func (pm *ProtocolManager) newPeer(pv int, nv uint64, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
   233  	return newPeer(pv, nv, p, newMeteredMsgWriter(rw))
   234  }
   235  
   236  //handle是为管理LES对等机的生命周期而调用的回调。什么时候?
   237  //此函数终止,对等端断开连接。
   238  func (pm *ProtocolManager) handle(p *peer) error {
   239  //如果这是受信任的对等,则忽略MaxPeers
   240  //在服务器模式下,我们尝试在握手后签入客户端池
   241  	if pm.lightSync && pm.peers.Len() >= pm.maxPeers && !p.Peer.Info().Network.Trusted {
   242  		return p2p.DiscTooManyPeers
   243  	}
   244  
   245  	p.Log().Debug("Light Ethereum peer connected", "name", p.Name())
   246  
   247  //执行LES握手
   248  	var (
   249  		genesis = pm.blockchain.Genesis()
   250  		head    = pm.blockchain.CurrentHeader()
   251  		hash    = head.Hash()
   252  		number  = head.Number.Uint64()
   253  		td      = pm.blockchain.GetTd(hash, number)
   254  	)
   255  	if err := p.Handshake(td, hash, number, genesis.Hash(), pm.server); err != nil {
   256  		p.Log().Debug("Light Ethereum handshake failed", "err", err)
   257  		return err
   258  	}
   259  
   260  	if !pm.lightSync && !p.Peer.Info().Network.Trusted {
   261  		addr, ok := p.RemoteAddr().(*net.TCPAddr)
   262  //测试对等地址不是TCP地址,如果无法进行类型转换,则不使用客户端池
   263  		if ok {
   264  			id := addr.IP.String()
   265  			if !pm.clientPool.connect(id, func() { go pm.removePeer(p.id) }) {
   266  				return p2p.DiscTooManyPeers
   267  			}
   268  			defer pm.clientPool.disconnect(id)
   269  		}
   270  	}
   271  
   272  	if rw, ok := p.rw.(*meteredMsgReadWriter); ok {
   273  		rw.Init(p.version)
   274  	}
   275  //在本地注册对等机
   276  	if err := pm.peers.Register(p); err != nil {
   277  		p.Log().Error("Light Ethereum peer registration failed", "err", err)
   278  		return err
   279  	}
   280  	defer func() {
   281  		if pm.server != nil && pm.server.fcManager != nil && p.fcClient != nil {
   282  			p.fcClient.Remove(pm.server.fcManager)
   283  		}
   284  		pm.removePeer(p.id)
   285  	}()
   286  //在下载程序中注册对等点。如果下载者认为它是被禁止的,我们会断开
   287  	if pm.lightSync {
   288  		p.lock.Lock()
   289  		head := p.headInfo
   290  		p.lock.Unlock()
   291  		if pm.fetcher != nil {
   292  			pm.fetcher.announce(p, head)
   293  		}
   294  
   295  		if p.poolEntry != nil {
   296  			pm.serverPool.registered(p.poolEntry)
   297  		}
   298  	}
   299  
   300  	stop := make(chan struct{})
   301  	defer close(stop)
   302  	go func() {
   303  //新块通知循环
   304  		for {
   305  			select {
   306  			case announce := <-p.announceChn:
   307  				p.SendAnnounce(announce)
   308  			case <-stop:
   309  				return
   310  			}
   311  		}
   312  	}()
   313  
   314  //主回路。处理传入消息。
   315  	for {
   316  		if err := pm.handleMsg(p); err != nil {
   317  			p.Log().Debug("Light Ethereum message handling failed", "err", err)
   318  			return err
   319  		}
   320  	}
   321  }
   322  
   323  var reqList = []uint64{GetBlockHeadersMsg, GetBlockBodiesMsg, GetCodeMsg, GetReceiptsMsg, GetProofsV1Msg, SendTxMsg, SendTxV2Msg, GetTxStatusMsg, GetHeaderProofsMsg, GetProofsV2Msg, GetHelperTrieProofsMsg}
   324  
   325  //每当从远程服务器接收到入站消息时,将调用handlemsg。
   326  //同龄人。返回任何错误时,远程连接被断开。
   327  func (pm *ProtocolManager) handleMsg(p *peer) error {
   328  //从远程对等端读取下一条消息,并确保它被完全消耗掉。
   329  	msg, err := p.rw.ReadMsg()
   330  	if err != nil {
   331  		return err
   332  	}
   333  	p.Log().Trace("Light Ethereum message arrived", "code", msg.Code, "bytes", msg.Size)
   334  
   335  	costs := p.fcCosts[msg.Code]
   336  	reject := func(reqCnt, maxCnt uint64) bool {
   337  		if p.fcClient == nil || reqCnt > maxCnt {
   338  			return true
   339  		}
   340  		bufValue, _ := p.fcClient.AcceptRequest()
   341  		cost := costs.baseCost + reqCnt*costs.reqCost
   342  		if cost > pm.server.defParams.BufLimit {
   343  			cost = pm.server.defParams.BufLimit
   344  		}
   345  		if cost > bufValue {
   346  			recharge := time.Duration((cost - bufValue) * 1000000 / pm.server.defParams.MinRecharge)
   347  			p.Log().Error("Request came too early", "recharge", common.PrettyDuration(recharge))
   348  			return true
   349  		}
   350  		return false
   351  	}
   352  
   353  	if msg.Size > ProtocolMaxMsgSize {
   354  		return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
   355  	}
   356  	defer msg.Discard()
   357  
   358  	var deliverMsg *Msg
   359  
   360  //根据消息的内容处理消息
   361  	switch msg.Code {
   362  	case StatusMsg:
   363  		p.Log().Trace("Received status message")
   364  //状态消息不应在握手后到达
   365  		return errResp(ErrExtraStatusMsg, "uncontrolled status message")
   366  
   367  //阻止头查询,收集请求的头并答复
   368  	case AnnounceMsg:
   369  		p.Log().Trace("Received announce message")
   370  		if p.requestAnnounceType == announceTypeNone {
   371  			return errResp(ErrUnexpectedResponse, "")
   372  		}
   373  
   374  		var req announceData
   375  		if err := msg.Decode(&req); err != nil {
   376  			return errResp(ErrDecode, "%v: %v", msg, err)
   377  		}
   378  
   379  		if p.requestAnnounceType == announceTypeSigned {
   380  			if err := req.checkSignature(p.ID()); err != nil {
   381  				p.Log().Trace("Invalid announcement signature", "err", err)
   382  				return err
   383  			}
   384  			p.Log().Trace("Valid announcement signature")
   385  		}
   386  
   387  		p.Log().Trace("Announce message content", "number", req.Number, "hash", req.Hash, "td", req.Td, "reorg", req.ReorgDepth)
   388  		if pm.fetcher != nil {
   389  			pm.fetcher.announce(p, &req)
   390  		}
   391  
   392  	case GetBlockHeadersMsg:
   393  		p.Log().Trace("Received block header request")
   394  //解码复杂的头查询
   395  		var req struct {
   396  			ReqID uint64
   397  			Query getBlockHeadersData
   398  		}
   399  		if err := msg.Decode(&req); err != nil {
   400  			return errResp(ErrDecode, "%v: %v", msg, err)
   401  		}
   402  
   403  		query := req.Query
   404  		if reject(query.Amount, MaxHeaderFetch) {
   405  			return errResp(ErrRequestRejected, "")
   406  		}
   407  
   408  		hashMode := query.Origin.Hash != (common.Hash{})
   409  		first := true
   410  		maxNonCanonical := uint64(100)
   411  
   412  //收集邮件头,直到达到提取或网络限制
   413  		var (
   414  			bytes   common.StorageSize
   415  			headers []*types.Header
   416  			unknown bool
   417  		)
   418  		for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit {
   419  //检索满足查询的下一个标题
   420  			var origin *types.Header
   421  			if hashMode {
   422  				if first {
   423  					first = false
   424  					origin = pm.blockchain.GetHeaderByHash(query.Origin.Hash)
   425  					if origin != nil {
   426  						query.Origin.Number = origin.Number.Uint64()
   427  					}
   428  				} else {
   429  					origin = pm.blockchain.GetHeader(query.Origin.Hash, query.Origin.Number)
   430  				}
   431  			} else {
   432  				origin = pm.blockchain.GetHeaderByNumber(query.Origin.Number)
   433  			}
   434  			if origin == nil {
   435  				break
   436  			}
   437  			headers = append(headers, origin)
   438  			bytes += estHeaderRlpSize
   439  
   440  //前进到查询的下一个标题
   441  			switch {
   442  			case hashMode && query.Reverse:
   443  //向Genesis块的基于哈希的遍历
   444  				ancestor := query.Skip + 1
   445  				if ancestor == 0 {
   446  					unknown = true
   447  				} else {
   448  					query.Origin.Hash, query.Origin.Number = pm.blockchain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical)
   449  					unknown = (query.Origin.Hash == common.Hash{})
   450  				}
   451  			case hashMode && !query.Reverse:
   452  //基于哈希的叶块遍历
   453  				var (
   454  					current = origin.Number.Uint64()
   455  					next    = current + query.Skip + 1
   456  				)
   457  				if next <= current {
   458  					infos, _ := json.MarshalIndent(p.Peer.Info(), "", "  ")
   459  					p.Log().Warn("GetBlockHeaders skip overflow attack", "current", current, "skip", query.Skip, "next", next, "attacker", infos)
   460  					unknown = true
   461  				} else {
   462  					if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
   463  						nextHash := header.Hash()
   464  						expOldHash, _ := pm.blockchain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical)
   465  						if expOldHash == query.Origin.Hash {
   466  							query.Origin.Hash, query.Origin.Number = nextHash, next
   467  						} else {
   468  							unknown = true
   469  						}
   470  					} else {
   471  						unknown = true
   472  					}
   473  				}
   474  			case query.Reverse:
   475  //朝向Genesis区块的基于数字的遍历
   476  				if query.Origin.Number >= query.Skip+1 {
   477  					query.Origin.Number -= query.Skip + 1
   478  				} else {
   479  					unknown = true
   480  				}
   481  
   482  			case !query.Reverse:
   483  //面向叶块的基于数字的遍历
   484  				query.Origin.Number += query.Skip + 1
   485  			}
   486  		}
   487  
   488  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + query.Amount*costs.reqCost)
   489  		pm.server.fcCostStats.update(msg.Code, query.Amount, rcost)
   490  		return p.SendBlockHeaders(req.ReqID, bv, headers)
   491  
   492  	case BlockHeadersMsg:
   493  		if pm.downloader == nil {
   494  			return errResp(ErrUnexpectedResponse, "")
   495  		}
   496  
   497  		p.Log().Trace("Received block header response message")
   498  //我们以前的一个请求收到了一批头文件
   499  		var resp struct {
   500  			ReqID, BV uint64
   501  			Headers   []*types.Header
   502  		}
   503  		if err := msg.Decode(&resp); err != nil {
   504  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   505  		}
   506  		p.fcServer.GotReply(resp.ReqID, resp.BV)
   507  		if pm.fetcher != nil && pm.fetcher.requestedID(resp.ReqID) {
   508  			pm.fetcher.deliverHeaders(p, resp.ReqID, resp.Headers)
   509  		} else {
   510  			err := pm.downloader.DeliverHeaders(p.id, resp.Headers)
   511  			if err != nil {
   512  				log.Debug(fmt.Sprint(err))
   513  			}
   514  		}
   515  
   516  	case GetBlockBodiesMsg:
   517  		p.Log().Trace("Received block bodies request")
   518  //解码检索消息
   519  		var req struct {
   520  			ReqID  uint64
   521  			Hashes []common.Hash
   522  		}
   523  		if err := msg.Decode(&req); err != nil {
   524  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   525  		}
   526  //收集块,直到达到获取或网络限制
   527  		var (
   528  			bytes  int
   529  			bodies []rlp.RawValue
   530  		)
   531  		reqCnt := len(req.Hashes)
   532  		if reject(uint64(reqCnt), MaxBodyFetch) {
   533  			return errResp(ErrRequestRejected, "")
   534  		}
   535  		for _, hash := range req.Hashes {
   536  			if bytes >= softResponseLimit {
   537  				break
   538  			}
   539  //检索请求的块体,如果找到足够的块体,则停止
   540  			if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != nil {
   541  				if data := rawdb.ReadBodyRLP(pm.chainDb, hash, *number); len(data) != 0 {
   542  					bodies = append(bodies, data)
   543  					bytes += len(data)
   544  				}
   545  			}
   546  		}
   547  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
   548  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
   549  		return p.SendBlockBodiesRLP(req.ReqID, bv, bodies)
   550  
   551  	case BlockBodiesMsg:
   552  		if pm.odr == nil {
   553  			return errResp(ErrUnexpectedResponse, "")
   554  		}
   555  
   556  		p.Log().Trace("Received block bodies response")
   557  //我们以前的一个要求得到了一批尸体。
   558  		var resp struct {
   559  			ReqID, BV uint64
   560  			Data      []*types.Body
   561  		}
   562  		if err := msg.Decode(&resp); err != nil {
   563  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   564  		}
   565  		p.fcServer.GotReply(resp.ReqID, resp.BV)
   566  		deliverMsg = &Msg{
   567  			MsgType: MsgBlockBodies,
   568  			ReqID:   resp.ReqID,
   569  			Obj:     resp.Data,
   570  		}
   571  
   572  	case GetCodeMsg:
   573  		p.Log().Trace("Received code request")
   574  //解码检索消息
   575  		var req struct {
   576  			ReqID uint64
   577  			Reqs  []CodeReq
   578  		}
   579  		if err := msg.Decode(&req); err != nil {
   580  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   581  		}
   582  //收集状态数据,直到达到提取或网络限制
   583  		var (
   584  			bytes int
   585  			data  [][]byte
   586  		)
   587  		reqCnt := len(req.Reqs)
   588  		if reject(uint64(reqCnt), MaxCodeFetch) {
   589  			return errResp(ErrRequestRejected, "")
   590  		}
   591  		for _, req := range req.Reqs {
   592  //检索请求的状态项,如果找到足够的,则停止
   593  			if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
   594  				if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
   595  					statedb, err := pm.blockchain.State()
   596  					if err != nil {
   597  						continue
   598  					}
   599  					account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
   600  					if err != nil {
   601  						continue
   602  					}
   603  					code, _ := statedb.Database().TrieDB().Node(common.BytesToHash(account.CodeHash))
   604  
   605  					data = append(data, code)
   606  					if bytes += len(code); bytes >= softResponseLimit {
   607  						break
   608  					}
   609  				}
   610  			}
   611  		}
   612  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
   613  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
   614  		return p.SendCode(req.ReqID, bv, data)
   615  
   616  	case CodeMsg:
   617  		if pm.odr == nil {
   618  			return errResp(ErrUnexpectedResponse, "")
   619  		}
   620  
   621  		p.Log().Trace("Received code response")
   622  //一批节点状态数据到达了我们以前的一个请求
   623  		var resp struct {
   624  			ReqID, BV uint64
   625  			Data      [][]byte
   626  		}
   627  		if err := msg.Decode(&resp); err != nil {
   628  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   629  		}
   630  		p.fcServer.GotReply(resp.ReqID, resp.BV)
   631  		deliverMsg = &Msg{
   632  			MsgType: MsgCode,
   633  			ReqID:   resp.ReqID,
   634  			Obj:     resp.Data,
   635  		}
   636  
   637  	case GetReceiptsMsg:
   638  		p.Log().Trace("Received receipts request")
   639  //解码检索消息
   640  		var req struct {
   641  			ReqID  uint64
   642  			Hashes []common.Hash
   643  		}
   644  		if err := msg.Decode(&req); err != nil {
   645  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   646  		}
   647  //收集状态数据,直到达到提取或网络限制
   648  		var (
   649  			bytes    int
   650  			receipts []rlp.RawValue
   651  		)
   652  		reqCnt := len(req.Hashes)
   653  		if reject(uint64(reqCnt), MaxReceiptFetch) {
   654  			return errResp(ErrRequestRejected, "")
   655  		}
   656  		for _, hash := range req.Hashes {
   657  			if bytes >= softResponseLimit {
   658  				break
   659  			}
   660  //检索请求块的收据,如果我们不知道,则跳过
   661  			var results types.Receipts
   662  			if number := rawdb.ReadHeaderNumber(pm.chainDb, hash); number != nil {
   663  				results = rawdb.ReadReceipts(pm.chainDb, hash, *number)
   664  			}
   665  			if results == nil {
   666  				if header := pm.blockchain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
   667  					continue
   668  				}
   669  			}
   670  //如果已知,则对响应数据包进行编码和排队
   671  			if encoded, err := rlp.EncodeToBytes(results); err != nil {
   672  				log.Error("Failed to encode receipt", "err", err)
   673  			} else {
   674  				receipts = append(receipts, encoded)
   675  				bytes += len(encoded)
   676  			}
   677  		}
   678  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
   679  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
   680  		return p.SendReceiptsRLP(req.ReqID, bv, receipts)
   681  
   682  	case ReceiptsMsg:
   683  		if pm.odr == nil {
   684  			return errResp(ErrUnexpectedResponse, "")
   685  		}
   686  
   687  		p.Log().Trace("Received receipts response")
   688  //我们以前的一个请求收到了一批收据
   689  		var resp struct {
   690  			ReqID, BV uint64
   691  			Receipts  []types.Receipts
   692  		}
   693  		if err := msg.Decode(&resp); err != nil {
   694  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   695  		}
   696  		p.fcServer.GotReply(resp.ReqID, resp.BV)
   697  		deliverMsg = &Msg{
   698  			MsgType: MsgReceipts,
   699  			ReqID:   resp.ReqID,
   700  			Obj:     resp.Receipts,
   701  		}
   702  
   703  	case GetProofsV1Msg:
   704  		p.Log().Trace("Received proofs request")
   705  //解码检索消息
   706  		var req struct {
   707  			ReqID uint64
   708  			Reqs  []ProofReq
   709  		}
   710  		if err := msg.Decode(&req); err != nil {
   711  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   712  		}
   713  //收集状态数据,直到达到提取或网络限制
   714  		var (
   715  			bytes  int
   716  			proofs proofsData
   717  		)
   718  		reqCnt := len(req.Reqs)
   719  		if reject(uint64(reqCnt), MaxProofsFetch) {
   720  			return errResp(ErrRequestRejected, "")
   721  		}
   722  		for _, req := range req.Reqs {
   723  //检索请求的状态项,如果找到足够的,则停止
   724  			if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
   725  				if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
   726  					statedb, err := pm.blockchain.State()
   727  					if err != nil {
   728  						continue
   729  					}
   730  					var trie state.Trie
   731  					if len(req.AccKey) > 0 {
   732  						account, err := pm.getAccount(statedb, header.Root, common.BytesToHash(req.AccKey))
   733  						if err != nil {
   734  							continue
   735  						}
   736  						trie, _ = statedb.Database().OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
   737  					} else {
   738  						trie, _ = statedb.Database().OpenTrie(header.Root)
   739  					}
   740  					if trie != nil {
   741  						var proof light.NodeList
   742  						trie.Prove(req.Key, 0, &proof)
   743  
   744  						proofs = append(proofs, proof)
   745  						if bytes += proof.DataSize(); bytes >= softResponseLimit {
   746  							break
   747  						}
   748  					}
   749  				}
   750  			}
   751  		}
   752  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
   753  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
   754  		return p.SendProofs(req.ReqID, bv, proofs)
   755  
   756  	case GetProofsV2Msg:
   757  		p.Log().Trace("Received les/2 proofs request")
   758  //解码检索消息
   759  		var req struct {
   760  			ReqID uint64
   761  			Reqs  []ProofReq
   762  		}
   763  		if err := msg.Decode(&req); err != nil {
   764  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   765  		}
   766  //收集状态数据,直到达到提取或网络限制
   767  		var (
   768  			lastBHash common.Hash
   769  			statedb   *state.StateDB
   770  			root      common.Hash
   771  		)
   772  		reqCnt := len(req.Reqs)
   773  		if reject(uint64(reqCnt), MaxProofsFetch) {
   774  			return errResp(ErrRequestRejected, "")
   775  		}
   776  
   777  		nodes := light.NewNodeSet()
   778  
   779  		for _, req := range req.Reqs {
   780  //查找属于请求的状态
   781  			if statedb == nil || req.BHash != lastBHash {
   782  				statedb, root, lastBHash = nil, common.Hash{}, req.BHash
   783  
   784  				if number := rawdb.ReadHeaderNumber(pm.chainDb, req.BHash); number != nil {
   785  					if header := rawdb.ReadHeader(pm.chainDb, req.BHash, *number); header != nil {
   786  						statedb, _ = pm.blockchain.State()
   787  						root = header.Root
   788  					}
   789  				}
   790  			}
   791  			if statedb == nil {
   792  				continue
   793  			}
   794  //提取请求的帐户或存储检索
   795  			var trie state.Trie
   796  			if len(req.AccKey) > 0 {
   797  				account, err := pm.getAccount(statedb, root, common.BytesToHash(req.AccKey))
   798  				if err != nil {
   799  					continue
   800  				}
   801  				trie, _ = statedb.Database().OpenStorageTrie(common.BytesToHash(req.AccKey), account.Root)
   802  			} else {
   803  				trie, _ = statedb.Database().OpenTrie(root)
   804  			}
   805  			if trie == nil {
   806  				continue
   807  			}
   808  //从帐户或stroage trie证明用户的请求
   809  			trie.Prove(req.Key, req.FromLevel, nodes)
   810  			if nodes.DataSize() >= softResponseLimit {
   811  				break
   812  			}
   813  		}
   814  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
   815  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
   816  		return p.SendProofsV2(req.ReqID, bv, nodes.NodeList())
   817  
   818  	case ProofsV1Msg:
   819  		if pm.odr == nil {
   820  			return errResp(ErrUnexpectedResponse, "")
   821  		}
   822  
   823  		p.Log().Trace("Received proofs response")
   824  //我们以前的一个要求得到了一批Merkle证明
   825  		var resp struct {
   826  			ReqID, BV uint64
   827  			Data      []light.NodeList
   828  		}
   829  		if err := msg.Decode(&resp); err != nil {
   830  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   831  		}
   832  		p.fcServer.GotReply(resp.ReqID, resp.BV)
   833  		deliverMsg = &Msg{
   834  			MsgType: MsgProofsV1,
   835  			ReqID:   resp.ReqID,
   836  			Obj:     resp.Data,
   837  		}
   838  
   839  	case ProofsV2Msg:
   840  		if pm.odr == nil {
   841  			return errResp(ErrUnexpectedResponse, "")
   842  		}
   843  
   844  		p.Log().Trace("Received les/2 proofs response")
   845  //我们以前的一个要求得到了一批Merkle证明
   846  		var resp struct {
   847  			ReqID, BV uint64
   848  			Data      light.NodeList
   849  		}
   850  		if err := msg.Decode(&resp); err != nil {
   851  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   852  		}
   853  		p.fcServer.GotReply(resp.ReqID, resp.BV)
   854  		deliverMsg = &Msg{
   855  			MsgType: MsgProofsV2,
   856  			ReqID:   resp.ReqID,
   857  			Obj:     resp.Data,
   858  		}
   859  
   860  	case GetHeaderProofsMsg:
   861  		p.Log().Trace("Received headers proof request")
   862  //解码检索消息
   863  		var req struct {
   864  			ReqID uint64
   865  			Reqs  []ChtReq
   866  		}
   867  		if err := msg.Decode(&req); err != nil {
   868  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   869  		}
   870  //收集状态数据,直到达到提取或网络限制
   871  		var (
   872  			bytes  int
   873  			proofs []ChtResp
   874  		)
   875  		reqCnt := len(req.Reqs)
   876  		if reject(uint64(reqCnt), MaxHelperTrieProofsFetch) {
   877  			return errResp(ErrRequestRejected, "")
   878  		}
   879  		trieDb := trie.NewDatabase(ethdb.NewTable(pm.chainDb, light.ChtTablePrefix))
   880  		for _, req := range req.Reqs {
   881  			if header := pm.blockchain.GetHeaderByNumber(req.BlockNum); header != nil {
   882  				sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, req.ChtNum*pm.iConfig.ChtSize-1)
   883  				if root := light.GetChtRoot(pm.chainDb, req.ChtNum-1, sectionHead); root != (common.Hash{}) {
   884  					trie, err := trie.New(root, trieDb)
   885  					if err != nil {
   886  						continue
   887  					}
   888  					var encNumber [8]byte
   889  					binary.BigEndian.PutUint64(encNumber[:], req.BlockNum)
   890  
   891  					var proof light.NodeList
   892  					trie.Prove(encNumber[:], 0, &proof)
   893  
   894  					proofs = append(proofs, ChtResp{Header: header, Proof: proof})
   895  					if bytes += proof.DataSize() + estHeaderRlpSize; bytes >= softResponseLimit {
   896  						break
   897  					}
   898  				}
   899  			}
   900  		}
   901  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
   902  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
   903  		return p.SendHeaderProofs(req.ReqID, bv, proofs)
   904  
   905  	case GetHelperTrieProofsMsg:
   906  		p.Log().Trace("Received helper trie proof request")
   907  //解码检索消息
   908  		var req struct {
   909  			ReqID uint64
   910  			Reqs  []HelperTrieReq
   911  		}
   912  		if err := msg.Decode(&req); err != nil {
   913  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   914  		}
   915  //收集状态数据,直到达到提取或网络限制
   916  		var (
   917  			auxBytes int
   918  			auxData  [][]byte
   919  		)
   920  		reqCnt := len(req.Reqs)
   921  		if reject(uint64(reqCnt), MaxHelperTrieProofsFetch) {
   922  			return errResp(ErrRequestRejected, "")
   923  		}
   924  
   925  		var (
   926  			lastIdx  uint64
   927  			lastType uint
   928  			root     common.Hash
   929  			auxTrie  *trie.Trie
   930  		)
   931  		nodes := light.NewNodeSet()
   932  		for _, req := range req.Reqs {
   933  			if auxTrie == nil || req.Type != lastType || req.TrieIdx != lastIdx {
   934  				auxTrie, lastType, lastIdx = nil, req.Type, req.TrieIdx
   935  
   936  				var prefix string
   937  				if root, prefix = pm.getHelperTrie(req.Type, req.TrieIdx); root != (common.Hash{}) {
   938  					auxTrie, _ = trie.New(root, trie.NewDatabase(ethdb.NewTable(pm.chainDb, prefix)))
   939  				}
   940  			}
   941  			if req.AuxReq == auxRoot {
   942  				var data []byte
   943  				if root != (common.Hash{}) {
   944  					data = root[:]
   945  				}
   946  				auxData = append(auxData, data)
   947  				auxBytes += len(data)
   948  			} else {
   949  				if auxTrie != nil {
   950  					auxTrie.Prove(req.Key, req.FromLevel, nodes)
   951  				}
   952  				if req.AuxReq != 0 {
   953  					data := pm.getHelperTrieAuxData(req)
   954  					auxData = append(auxData, data)
   955  					auxBytes += len(data)
   956  				}
   957  			}
   958  			if nodes.DataSize()+auxBytes >= softResponseLimit {
   959  				break
   960  			}
   961  		}
   962  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
   963  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
   964  		return p.SendHelperTrieProofs(req.ReqID, bv, HelperTrieResps{Proofs: nodes.NodeList(), AuxData: auxData})
   965  
   966  	case HeaderProofsMsg:
   967  		if pm.odr == nil {
   968  			return errResp(ErrUnexpectedResponse, "")
   969  		}
   970  
   971  		p.Log().Trace("Received headers proof response")
   972  		var resp struct {
   973  			ReqID, BV uint64
   974  			Data      []ChtResp
   975  		}
   976  		if err := msg.Decode(&resp); err != nil {
   977  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   978  		}
   979  		p.fcServer.GotReply(resp.ReqID, resp.BV)
   980  		deliverMsg = &Msg{
   981  			MsgType: MsgHeaderProofs,
   982  			ReqID:   resp.ReqID,
   983  			Obj:     resp.Data,
   984  		}
   985  
   986  	case HelperTrieProofsMsg:
   987  		if pm.odr == nil {
   988  			return errResp(ErrUnexpectedResponse, "")
   989  		}
   990  
   991  		p.Log().Trace("Received helper trie proof response")
   992  		var resp struct {
   993  			ReqID, BV uint64
   994  			Data      HelperTrieResps
   995  		}
   996  		if err := msg.Decode(&resp); err != nil {
   997  			return errResp(ErrDecode, "msg %v: %v", msg, err)
   998  		}
   999  
  1000  		p.fcServer.GotReply(resp.ReqID, resp.BV)
  1001  		deliverMsg = &Msg{
  1002  			MsgType: MsgHelperTrieProofs,
  1003  			ReqID:   resp.ReqID,
  1004  			Obj:     resp.Data,
  1005  		}
  1006  
  1007  	case SendTxMsg:
  1008  		if pm.txpool == nil {
  1009  			return errResp(ErrRequestRejected, "")
  1010  		}
  1011  //事务到达,分析所有事务并传递到池
  1012  		var txs []*types.Transaction
  1013  		if err := msg.Decode(&txs); err != nil {
  1014  			return errResp(ErrDecode, "msg %v: %v", msg, err)
  1015  		}
  1016  		reqCnt := len(txs)
  1017  		if reject(uint64(reqCnt), MaxTxSend) {
  1018  			return errResp(ErrRequestRejected, "")
  1019  		}
  1020  		pm.txpool.AddRemotes(txs)
  1021  
  1022  		_, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
  1023  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
  1024  
  1025  	case SendTxV2Msg:
  1026  		if pm.txpool == nil {
  1027  			return errResp(ErrRequestRejected, "")
  1028  		}
  1029  //事务到达,分析所有事务并传递到池
  1030  		var req struct {
  1031  			ReqID uint64
  1032  			Txs   []*types.Transaction
  1033  		}
  1034  		if err := msg.Decode(&req); err != nil {
  1035  			return errResp(ErrDecode, "msg %v: %v", msg, err)
  1036  		}
  1037  		reqCnt := len(req.Txs)
  1038  		if reject(uint64(reqCnt), MaxTxSend) {
  1039  			return errResp(ErrRequestRejected, "")
  1040  		}
  1041  
  1042  		hashes := make([]common.Hash, len(req.Txs))
  1043  		for i, tx := range req.Txs {
  1044  			hashes[i] = tx.Hash()
  1045  		}
  1046  		stats := pm.txStatus(hashes)
  1047  		for i, stat := range stats {
  1048  			if stat.Status == core.TxStatusUnknown {
  1049  				if errs := pm.txpool.AddRemotes([]*types.Transaction{req.Txs[i]}); errs[0] != nil {
  1050  					stats[i].Error = errs[0].Error()
  1051  					continue
  1052  				}
  1053  				stats[i] = pm.txStatus([]common.Hash{hashes[i]})[0]
  1054  			}
  1055  		}
  1056  
  1057  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
  1058  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
  1059  
  1060  		return p.SendTxStatus(req.ReqID, bv, stats)
  1061  
  1062  	case GetTxStatusMsg:
  1063  		if pm.txpool == nil {
  1064  			return errResp(ErrUnexpectedResponse, "")
  1065  		}
  1066  //事务到达,分析所有事务并传递到池
  1067  		var req struct {
  1068  			ReqID  uint64
  1069  			Hashes []common.Hash
  1070  		}
  1071  		if err := msg.Decode(&req); err != nil {
  1072  			return errResp(ErrDecode, "msg %v: %v", msg, err)
  1073  		}
  1074  		reqCnt := len(req.Hashes)
  1075  		if reject(uint64(reqCnt), MaxTxStatus) {
  1076  			return errResp(ErrRequestRejected, "")
  1077  		}
  1078  		bv, rcost := p.fcClient.RequestProcessed(costs.baseCost + uint64(reqCnt)*costs.reqCost)
  1079  		pm.server.fcCostStats.update(msg.Code, uint64(reqCnt), rcost)
  1080  
  1081  		return p.SendTxStatus(req.ReqID, bv, pm.txStatus(req.Hashes))
  1082  
  1083  	case TxStatusMsg:
  1084  		if pm.odr == nil {
  1085  			return errResp(ErrUnexpectedResponse, "")
  1086  		}
  1087  
  1088  		p.Log().Trace("Received tx status response")
  1089  		var resp struct {
  1090  			ReqID, BV uint64
  1091  			Status    []txStatus
  1092  		}
  1093  		if err := msg.Decode(&resp); err != nil {
  1094  			return errResp(ErrDecode, "msg %v: %v", msg, err)
  1095  		}
  1096  
  1097  		p.fcServer.GotReply(resp.ReqID, resp.BV)
  1098  
  1099  	default:
  1100  		p.Log().Trace("Received unknown message", "code", msg.Code)
  1101  		return errResp(ErrInvalidMsgCode, "%v", msg.Code)
  1102  	}
  1103  
  1104  	if deliverMsg != nil {
  1105  		err := pm.retriever.deliver(p, deliverMsg)
  1106  		if err != nil {
  1107  			p.responseErrors++
  1108  			if p.responseErrors > maxResponseErrors {
  1109  				return err
  1110  			}
  1111  		}
  1112  	}
  1113  	return nil
  1114  }
  1115  
  1116  //GetAccount从根目录下的状态检索帐户。
  1117  func (pm *ProtocolManager) getAccount(statedb *state.StateDB, root, hash common.Hash) (state.Account, error) {
  1118  	trie, err := trie.New(root, statedb.Database().TrieDB())
  1119  	if err != nil {
  1120  		return state.Account{}, err
  1121  	}
  1122  	blob, err := trie.TryGet(hash[:])
  1123  	if err != nil {
  1124  		return state.Account{}, err
  1125  	}
  1126  	var account state.Account
  1127  	if err = rlp.DecodeBytes(blob, &account); err != nil {
  1128  		return state.Account{}, err
  1129  	}
  1130  	return account, nil
  1131  }
  1132  
  1133  //gethelpertrie返回给定trie id和节索引的后处理trie根。
  1134  func (pm *ProtocolManager) getHelperTrie(id uint, idx uint64) (common.Hash, string) {
  1135  	switch id {
  1136  	case htCanonical:
  1137  		idxV1 := (idx+1)*(pm.iConfig.PairChtSize/pm.iConfig.ChtSize) - 1
  1138  		sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idxV1+1)*pm.iConfig.ChtSize-1)
  1139  		return light.GetChtRoot(pm.chainDb, idxV1, sectionHead), light.ChtTablePrefix
  1140  	case htBloomBits:
  1141  		sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.iConfig.BloomTrieSize-1)
  1142  		return light.GetBloomTrieRoot(pm.chainDb, idx, sectionHead), light.BloomTrieTablePrefix
  1143  	}
  1144  	return common.Hash{}, ""
  1145  }
  1146  
  1147  //gethelpertrieauxdata返回给定helpertrie请求的请求辅助数据
  1148  func (pm *ProtocolManager) getHelperTrieAuxData(req HelperTrieReq) []byte {
  1149  	if req.Type == htCanonical && req.AuxReq == auxHeader && len(req.Key) == 8 {
  1150  		blockNum := binary.BigEndian.Uint64(req.Key)
  1151  		hash := rawdb.ReadCanonicalHash(pm.chainDb, blockNum)
  1152  		return rawdb.ReadHeaderRLP(pm.chainDb, hash, blockNum)
  1153  	}
  1154  	return nil
  1155  }
  1156  
  1157  func (pm *ProtocolManager) txStatus(hashes []common.Hash) []txStatus {
  1158  	stats := make([]txStatus, len(hashes))
  1159  	for i, stat := range pm.txpool.Status(hashes) {
  1160  //保存事务池中的状态
  1161  		stats[i].Status = stat
  1162  
  1163  //如果池未知事务,请尝试在本地查找它
  1164  		if stat == core.TxStatusUnknown {
  1165  			if block, number, index := rawdb.ReadTxLookupEntry(pm.chainDb, hashes[i]); block != (common.Hash{}) {
  1166  				stats[i].Status = core.TxStatusIncluded
  1167  				stats[i].Lookup = &rawdb.TxLookupEntry{BlockHash: block, BlockIndex: number, Index: index}
  1168  			}
  1169  		}
  1170  	}
  1171  	return stats
  1172  }
  1173  
  1174  //DownloaderPeerNotify实现PeerSetNotify
  1175  type downloaderPeerNotify ProtocolManager
  1176  
  1177  type peerConnection struct {
  1178  	manager *ProtocolManager
  1179  	peer    *peer
  1180  }
  1181  
  1182  func (pc *peerConnection) Head() (common.Hash, *big.Int) {
  1183  	return pc.peer.HeadAndTd()
  1184  }
  1185  
  1186  func (pc *peerConnection) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error {
  1187  	reqID := genReqID()
  1188  	rq := &distReq{
  1189  		getCost: func(dp distPeer) uint64 {
  1190  			peer := dp.(*peer)
  1191  			return peer.GetRequestCost(GetBlockHeadersMsg, amount)
  1192  		},
  1193  		canSend: func(dp distPeer) bool {
  1194  			return dp.(*peer) == pc.peer
  1195  		},
  1196  		request: func(dp distPeer) func() {
  1197  			peer := dp.(*peer)
  1198  			cost := peer.GetRequestCost(GetBlockHeadersMsg, amount)
  1199  			peer.fcServer.QueueRequest(reqID, cost)
  1200  			return func() { peer.RequestHeadersByHash(reqID, cost, origin, amount, skip, reverse) }
  1201  		},
  1202  	}
  1203  	_, ok := <-pc.manager.reqDist.queue(rq)
  1204  	if !ok {
  1205  		return light.ErrNoPeers
  1206  	}
  1207  	return nil
  1208  }
  1209  
  1210  func (pc *peerConnection) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error {
  1211  	reqID := genReqID()
  1212  	rq := &distReq{
  1213  		getCost: func(dp distPeer) uint64 {
  1214  			peer := dp.(*peer)
  1215  			return peer.GetRequestCost(GetBlockHeadersMsg, amount)
  1216  		},
  1217  		canSend: func(dp distPeer) bool {
  1218  			return dp.(*peer) == pc.peer
  1219  		},
  1220  		request: func(dp distPeer) func() {
  1221  			peer := dp.(*peer)
  1222  			cost := peer.GetRequestCost(GetBlockHeadersMsg, amount)
  1223  			peer.fcServer.QueueRequest(reqID, cost)
  1224  			return func() { peer.RequestHeadersByNumber(reqID, cost, origin, amount, skip, reverse) }
  1225  		},
  1226  	}
  1227  	_, ok := <-pc.manager.reqDist.queue(rq)
  1228  	if !ok {
  1229  		return light.ErrNoPeers
  1230  	}
  1231  	return nil
  1232  }
  1233  
  1234  func (d *downloaderPeerNotify) registerPeer(p *peer) {
  1235  	pm := (*ProtocolManager)(d)
  1236  	pc := &peerConnection{
  1237  		manager: pm,
  1238  		peer:    p,
  1239  	}
  1240  	pm.downloader.RegisterLightPeer(p.id, ethVersion, pc)
  1241  }
  1242  
  1243  func (d *downloaderPeerNotify) unregisterPeer(p *peer) {
  1244  	pm := (*ProtocolManager)(d)
  1245  	pm.downloader.UnregisterPeer(p.id)
  1246  }
  1247