github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/les/odr.go (about)

     1  package les
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/quickchainproject/quickchain/core"
     7  	"github.com/quickchainproject/quickchain/qctdb"
     8  	"github.com/quickchainproject/quickchain/light"
     9  	"github.com/quickchainproject/quickchain/log"
    10  )
    11  
    12  // LesOdr implements light.OdrBackend
    13  type LesOdr struct {
    14  	db                                         qctdb.Database
    15  	chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer
    16  	retriever                                  *retrieveManager
    17  	stop                                       chan struct{}
    18  }
    19  
    20  func NewLesOdr(db qctdb.Database, chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer, retriever *retrieveManager) *LesOdr {
    21  	return &LesOdr{
    22  		db:               db,
    23  		chtIndexer:       chtIndexer,
    24  		bloomTrieIndexer: bloomTrieIndexer,
    25  		bloomIndexer:     bloomIndexer,
    26  		retriever:        retriever,
    27  		stop:             make(chan struct{}),
    28  	}
    29  }
    30  
    31  // Stop cancels all pending retrievals
    32  func (odr *LesOdr) Stop() {
    33  	close(odr.stop)
    34  }
    35  
    36  // Database returns the backing database
    37  func (odr *LesOdr) Database() qctdb.Database {
    38  	return odr.db
    39  }
    40  
    41  // ChtIndexer returns the CHT chain indexer
    42  func (odr *LesOdr) ChtIndexer() *core.ChainIndexer {
    43  	return odr.chtIndexer
    44  }
    45  
    46  // BloomTrieIndexer returns the bloom trie chain indexer
    47  func (odr *LesOdr) BloomTrieIndexer() *core.ChainIndexer {
    48  	return odr.bloomTrieIndexer
    49  }
    50  
    51  // BloomIndexer returns the bloombits chain indexer
    52  func (odr *LesOdr) BloomIndexer() *core.ChainIndexer {
    53  	return odr.bloomIndexer
    54  }
    55  
    56  const (
    57  	MsgBlockBodies = iota
    58  	MsgCode
    59  	MsgReceipts
    60  	MsgProofsV1
    61  	MsgProofsV2
    62  	MsgHeaderProofs
    63  	MsgHelperTrieProofs
    64  )
    65  
    66  // Msg encodes a LES message that delivers reply data for a request
    67  type Msg struct {
    68  	MsgType int
    69  	ReqID   uint64
    70  	Obj     interface{}
    71  }
    72  
    73  // Retrieve tries to fetch an object from the LES network.
    74  // If the network retrieval was successful, it stores the object in local db.
    75  func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err error) {
    76  	lreq := LesRequest(req)
    77  
    78  	reqID := genReqID()
    79  	rq := &distReq{
    80  		getCost: func(dp distPeer) uint64 {
    81  			return lreq.GetCost(dp.(*peer))
    82  		},
    83  		canSend: func(dp distPeer) bool {
    84  			p := dp.(*peer)
    85  			return lreq.CanSend(p)
    86  		},
    87  		request: func(dp distPeer) func() {
    88  			p := dp.(*peer)
    89  			cost := lreq.GetCost(p)
    90  			p.fcServer.QueueRequest(reqID, cost)
    91  			return func() { lreq.Request(reqID, p) }
    92  		},
    93  	}
    94  
    95  	if err = odr.retriever.retrieve(ctx, reqID, rq, func(p distPeer, msg *Msg) error { return lreq.Validate(odr.db, msg) }, odr.stop); err == nil {
    96  		// retrieved from network, store in db
    97  		req.StoreResult(odr.db)
    98  	} else {
    99  		log.Debug("Failed to retrieve data from network", "err", err)
   100  	}
   101  	return
   102  }