github.com/luckypickle/go-ethereum-vet@v1.14.2/les/odr.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 "context" 21 22 "github.com/luckypickle/go-ethereum-vet/core" 23 "github.com/luckypickle/go-ethereum-vet/ethdb" 24 "github.com/luckypickle/go-ethereum-vet/light" 25 "github.com/luckypickle/go-ethereum-vet/log" 26 ) 27 28 // LesOdr implements light.OdrBackend 29 type LesOdr struct { 30 db ethdb.Database 31 chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer 32 retriever *retrieveManager 33 stop chan struct{} 34 } 35 36 func NewLesOdr(db ethdb.Database, retriever *retrieveManager) *LesOdr { 37 return &LesOdr{ 38 db: db, 39 retriever: retriever, 40 stop: make(chan struct{}), 41 } 42 } 43 44 // Stop cancels all pending retrievals 45 func (odr *LesOdr) Stop() { 46 close(odr.stop) 47 } 48 49 // Database returns the backing database 50 func (odr *LesOdr) Database() ethdb.Database { 51 return odr.db 52 } 53 54 // SetIndexers adds the necessary chain indexers to the ODR backend 55 func (odr *LesOdr) SetIndexers(chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer) { 56 odr.chtIndexer = chtIndexer 57 odr.bloomTrieIndexer = bloomTrieIndexer 58 odr.bloomIndexer = bloomIndexer 59 } 60 61 // ChtIndexer returns the CHT chain indexer 62 func (odr *LesOdr) ChtIndexer() *core.ChainIndexer { 63 return odr.chtIndexer 64 } 65 66 // BloomTrieIndexer returns the bloom trie chain indexer 67 func (odr *LesOdr) BloomTrieIndexer() *core.ChainIndexer { 68 return odr.bloomTrieIndexer 69 } 70 71 // BloomIndexer returns the bloombits chain indexer 72 func (odr *LesOdr) BloomIndexer() *core.ChainIndexer { 73 return odr.bloomIndexer 74 } 75 76 const ( 77 MsgBlockBodies = iota 78 MsgCode 79 MsgReceipts 80 MsgProofsV1 81 MsgProofsV2 82 MsgHeaderProofs 83 MsgHelperTrieProofs 84 ) 85 86 // Msg encodes a LES message that delivers reply data for a request 87 type Msg struct { 88 MsgType int 89 ReqID uint64 90 Obj interface{} 91 } 92 93 // Retrieve tries to fetch an object from the LES network. 94 // If the network retrieval was successful, it stores the object in local db. 95 func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err error) { 96 lreq := LesRequest(req) 97 98 reqID := genReqID() 99 rq := &distReq{ 100 getCost: func(dp distPeer) uint64 { 101 return lreq.GetCost(dp.(*peer)) 102 }, 103 canSend: func(dp distPeer) bool { 104 p := dp.(*peer) 105 return lreq.CanSend(p) 106 }, 107 request: func(dp distPeer) func() { 108 p := dp.(*peer) 109 cost := lreq.GetCost(p) 110 p.fcServer.QueueRequest(reqID, cost) 111 return func() { lreq.Request(reqID, p) } 112 }, 113 } 114 115 if err = odr.retriever.retrieve(ctx, reqID, rq, func(p distPeer, msg *Msg) error { return lreq.Validate(odr.db, msg) }, odr.stop); err == nil { 116 // retrieved from network, store in db 117 req.StoreResult(odr.db) 118 } else { 119 log.Debug("Failed to retrieve data from network", "err", err) 120 } 121 return 122 }