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