github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/les/odr.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:39</date>
    10  //</624450095571537920>
    11  
    12  
    13  package les
    14  
    15  import (
    16  	"context"
    17  
    18  	"github.com/ethereum/go-ethereum/core"
    19  	"github.com/ethereum/go-ethereum/ethdb"
    20  	"github.com/ethereum/go-ethereum/light"
    21  	"github.com/ethereum/go-ethereum/log"
    22  )
    23  
    24  //lesodr实现light.odrbackend
    25  type LesOdr struct {
    26  	db                                         ethdb.Database
    27  	indexerConfig                              *light.IndexerConfig
    28  	chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer
    29  	retriever                                  *retrieveManager
    30  	stop                                       chan struct{}
    31  }
    32  
    33  func NewLesOdr(db ethdb.Database, config *light.IndexerConfig, retriever *retrieveManager) *LesOdr {
    34  	return &LesOdr{
    35  		db:            db,
    36  		indexerConfig: config,
    37  		retriever:     retriever,
    38  		stop:          make(chan struct{}),
    39  	}
    40  }
    41  
    42  //停止取消所有挂起的检索
    43  func (odr *LesOdr) Stop() {
    44  	close(odr.stop)
    45  }
    46  
    47  //数据库返回后备数据库
    48  func (odr *LesOdr) Database() ethdb.Database {
    49  	return odr.db
    50  }
    51  
    52  //setindexers将必要的链索引器添加到ODR后端
    53  func (odr *LesOdr) SetIndexers(chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer) {
    54  	odr.chtIndexer = chtIndexer
    55  	odr.bloomTrieIndexer = bloomTrieIndexer
    56  	odr.bloomIndexer = bloomIndexer
    57  }
    58  
    59  //返回CHT链索引器
    60  func (odr *LesOdr) ChtIndexer() *core.ChainIndexer {
    61  	return odr.chtIndexer
    62  }
    63  
    64  //BloomTrieIndexer返回BloomTrie链索引器
    65  func (odr *LesOdr) BloomTrieIndexer() *core.ChainIndexer {
    66  	return odr.bloomTrieIndexer
    67  }
    68  
    69  //BloomIndexer返回BloomBits链索引器
    70  func (odr *LesOdr) BloomIndexer() *core.ChainIndexer {
    71  	return odr.bloomIndexer
    72  }
    73  
    74  //indexer config返回索引器配置。
    75  func (odr *LesOdr) IndexerConfig() *light.IndexerConfig {
    76  	return odr.indexerConfig
    77  }
    78  
    79  const (
    80  	MsgBlockBodies = iota
    81  	MsgCode
    82  	MsgReceipts
    83  	MsgProofsV1
    84  	MsgProofsV2
    85  	MsgHeaderProofs
    86  	MsgHelperTrieProofs
    87  )
    88  
    89  //msg对为请求传递答复数据的les消息进行编码
    90  type Msg struct {
    91  	MsgType int
    92  	ReqID   uint64
    93  	Obj     interface{}
    94  }
    95  
    96  //retrieve尝试从les网络获取对象。
    97  //如果网络检索成功,它将对象存储在本地数据库中。
    98  func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err error) {
    99  	lreq := LesRequest(req)
   100  
   101  	reqID := genReqID()
   102  	rq := &distReq{
   103  		getCost: func(dp distPeer) uint64 {
   104  			return lreq.GetCost(dp.(*peer))
   105  		},
   106  		canSend: func(dp distPeer) bool {
   107  			p := dp.(*peer)
   108  			return lreq.CanSend(p)
   109  		},
   110  		request: func(dp distPeer) func() {
   111  			p := dp.(*peer)
   112  			cost := lreq.GetCost(p)
   113  			p.fcServer.QueueRequest(reqID, cost)
   114  			return func() { lreq.Request(reqID, p) }
   115  		},
   116  	}
   117  
   118  	if err = odr.retriever.retrieve(ctx, reqID, rq, func(p distPeer, msg *Msg) error { return lreq.Validate(odr.db, msg) }, odr.stop); err == nil {
   119  //retrieved from network, store in db
   120  		req.StoreResult(odr.db)
   121  	} else {
   122  		log.Debug("Failed to retrieve data from network", "err", err)
   123  	}
   124  	return
   125  }
   126