les, light: pass indexer config to odr

This commit is contained in:
rjl493456442 2018-07-18 15:28:26 +08:00
parent e131a83e30
commit 2bf060a414
11 changed files with 38 additions and 40 deletions

View file

@ -115,7 +115,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
leth.relay = NewLesTxRelay(peers, leth.reqDist) leth.relay = NewLesTxRelay(peers, leth.reqDist)
leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg) leth.serverPool = newServerPool(chainDb, quitSync, &leth.wg)
leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool) leth.retriever = newRetrieveManager(peers, leth.reqDist, leth.serverPool)
leth.odr = NewLesOdr(chainDb, leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer, leth.retriever) leth.odr = NewLesOdr(chainDb, light.DefaultClientIndexerConfig, leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer, leth.retriever)
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, light.DefaultClientIndexerConfig, leth.engine); err != nil { if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, light.DefaultClientIndexerConfig, leth.engine); err != nil {
return nil, err return nil, err
} }

View file

@ -28,14 +28,16 @@ import (
// LesOdr implements light.OdrBackend // LesOdr implements light.OdrBackend
type LesOdr struct { type LesOdr struct {
db ethdb.Database db ethdb.Database
indexerConfig *light.IndexerConfig
chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer
retriever *retrieveManager retriever *retrieveManager
stop chan struct{} stop chan struct{}
} }
func NewLesOdr(db ethdb.Database, chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer, retriever *retrieveManager) *LesOdr { func NewLesOdr(db ethdb.Database, config *light.IndexerConfig, chtIndexer, bloomTrieIndexer, bloomIndexer *core.ChainIndexer, retriever *retrieveManager) *LesOdr {
return &LesOdr{ return &LesOdr{
db: db, db: db,
indexerConfig: config,
chtIndexer: chtIndexer, chtIndexer: chtIndexer,
bloomTrieIndexer: bloomTrieIndexer, bloomTrieIndexer: bloomTrieIndexer,
bloomIndexer: bloomIndexer, bloomIndexer: bloomIndexer,
@ -98,7 +100,7 @@ func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err erro
}, },
canSend: func(dp distPeer) bool { canSend: func(dp distPeer) bool {
p := dp.(*peer) p := dp.(*peer)
return lreq.CanSend(p) return lreq.CanSend(p, odr.indexerConfig)
}, },
request: func(dp distPeer) func() { request: func(dp distPeer) func() {
p := dp.(*peer) p := dp.(*peer)
@ -110,7 +112,7 @@ func (odr *LesOdr) Retrieve(ctx context.Context, req light.OdrRequest) (err erro
if err = odr.retriever.retrieve(ctx, reqID, rq, func(p distPeer, msg *Msg) error { return lreq.Validate(odr.db, msg) }, odr.stop); err == nil { if err = odr.retriever.retrieve(ctx, reqID, rq, func(p distPeer, msg *Msg) error { return lreq.Validate(odr.db, msg) }, odr.stop); err == nil {
// retrieved from network, store in db // retrieved from network, store in db
req.StoreResult(odr.db) req.StoreResult(odr.db, odr.indexerConfig)
} else { } else {
log.Debug("Failed to retrieve data from network", "err", err) log.Debug("Failed to retrieve data from network", "err", err)
} }

View file

@ -49,7 +49,7 @@ var (
type LesOdrRequest interface { type LesOdrRequest interface {
GetCost(*peer) uint64 GetCost(*peer) uint64
CanSend(*peer) bool CanSend(*peer, *light.IndexerConfig) bool
Request(uint64, *peer) error Request(uint64, *peer) error
Validate(ethdb.Database, *Msg) error Validate(ethdb.Database, *Msg) error
} }
@ -83,7 +83,7 @@ func (r *BlockRequest) GetCost(peer *peer) uint64 {
} }
// CanSend tells if a certain peer is suitable for serving the given request // CanSend tells if a certain peer is suitable for serving the given request
func (r *BlockRequest) CanSend(peer *peer) bool { func (r *BlockRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
return peer.HasBlock(r.Hash, r.Number) return peer.HasBlock(r.Hash, r.Number)
} }
@ -139,7 +139,7 @@ func (r *ReceiptsRequest) GetCost(peer *peer) uint64 {
} }
// CanSend tells if a certain peer is suitable for serving the given request // CanSend tells if a certain peer is suitable for serving the given request
func (r *ReceiptsRequest) CanSend(peer *peer) bool { func (r *ReceiptsRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
return peer.HasBlock(r.Hash, r.Number) return peer.HasBlock(r.Hash, r.Number)
} }
@ -201,7 +201,7 @@ func (r *TrieRequest) GetCost(peer *peer) uint64 {
} }
// CanSend tells if a certain peer is suitable for serving the given request // CanSend tells if a certain peer is suitable for serving the given request
func (r *TrieRequest) CanSend(peer *peer) bool { func (r *TrieRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
return peer.HasBlock(r.Id.BlockHash, r.Id.BlockNumber) return peer.HasBlock(r.Id.BlockHash, r.Id.BlockNumber)
} }
@ -271,7 +271,7 @@ func (r *CodeRequest) GetCost(peer *peer) uint64 {
} }
// CanSend tells if a certain peer is suitable for serving the given request // CanSend tells if a certain peer is suitable for serving the given request
func (r *CodeRequest) CanSend(peer *peer) bool { func (r *CodeRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
return peer.HasBlock(r.Id.BlockHash, r.Id.BlockNumber) return peer.HasBlock(r.Id.BlockHash, r.Id.BlockNumber)
} }
@ -361,11 +361,11 @@ func (r *ChtRequest) GetCost(peer *peer) uint64 {
} }
// CanSend tells if a certain peer is suitable for serving the given request // CanSend tells if a certain peer is suitable for serving the given request
func (r *ChtRequest) CanSend(peer *peer) bool { func (r *ChtRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
peer.lock.RLock() peer.lock.RLock()
defer peer.lock.RUnlock() defer peer.lock.RUnlock()
return peer.headInfo.Number >= r.Confirms && r.ChtNum <= (peer.headInfo.Number-r.Confirms)/r.SectionSize return peer.headInfo.Number >= config.ChtConfirm && r.ChtNum <= (peer.headInfo.Number-config.ChtConfirm)/config.ChtSize
} }
// Request sends an ODR request to the LES network (implementation of LesOdrRequest) // Request sends an ODR request to the LES network (implementation of LesOdrRequest)
@ -477,14 +477,14 @@ func (r *BloomRequest) GetCost(peer *peer) uint64 {
} }
// CanSend tells if a certain peer is suitable for serving the given request // CanSend tells if a certain peer is suitable for serving the given request
func (r *BloomRequest) CanSend(peer *peer) bool { func (r *BloomRequest) CanSend(peer *peer, config *light.IndexerConfig) bool {
peer.lock.RLock() peer.lock.RLock()
defer peer.lock.RUnlock() defer peer.lock.RUnlock()
if peer.version < lpv2 { if peer.version < lpv2 {
return false return false
} }
return peer.headInfo.Number >= r.Confirms && r.BloomTrieNum <= (peer.headInfo.Number-r.Confirms)/r.SectionSize return peer.headInfo.Number >= config.BloomTrieConfirm && r.BloomTrieNum <= (peer.headInfo.Number-config.BloomTrieConfirm)/config.BloomTrieSize
} }
// Request sends an ODR request to the LES network (implementation of LesOdrRequest) // Request sends an ODR request to the LES network (implementation of LesOdrRequest)

View file

@ -167,7 +167,7 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) {
rm := newRetrieveManager(peers, dist, nil) rm := newRetrieveManager(peers, dist, nil)
db := ethdb.NewMemDatabase() db := ethdb.NewMemDatabase()
ldb := ethdb.NewMemDatabase() ldb := ethdb.NewMemDatabase()
odr := NewLesOdr(ldb, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations), odr := NewLesOdr(ldb, light.DefaultClientIndexerConfig, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations),
light.NewBloomTrieIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations, params.BloomTrieFrequency, params.HelperTrieConfirmations), light.NewBloomTrieIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations, params.BloomTrieFrequency, params.HelperTrieConfirmations),
eth.NewBloomIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), rm) eth.NewBloomIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), rm)
pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db) pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db)

View file

@ -90,7 +90,7 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) {
rm := newRetrieveManager(peers, dist, nil) rm := newRetrieveManager(peers, dist, nil)
db := ethdb.NewMemDatabase() db := ethdb.NewMemDatabase()
ldb := ethdb.NewMemDatabase() ldb := ethdb.NewMemDatabase()
odr := NewLesOdr(ldb, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations), odr := NewLesOdr(ldb, light.DefaultClientIndexerConfig, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations),
light.NewBloomTrieIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations, params.BloomTrieFrequency, params.HelperTrieConfirmations), light.NewBloomTrieIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations, params.BloomTrieFrequency, params.HelperTrieConfirmations),
eth.NewBloomIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), rm) eth.NewBloomIndexer(db, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), rm)

View file

@ -130,7 +130,7 @@ func (self *LightChain) addTrustedCheckpoint(cp trustedCheckpoint) {
if self.odr.BloomIndexer() != nil { if self.odr.BloomIndexer() != nil {
self.odr.BloomIndexer().AddKnownSectionHead(cp.sectionIdx, cp.sectionHead) self.odr.BloomIndexer().AddKnownSectionHead(cp.sectionIdx, cp.sectionHead)
} }
log.Info("Added trusted checkpoint", "chain", cp.name, "block", (cp.sectionIdx+1)*params.CHTFrequencyClient-1, "hash", cp.sectionHead) log.Info("Added trusted checkpoint", "chain", cp.name, "block", (cp.sectionIdx+1)*self.indexerConfig.ChtSize-1, "hash", cp.sectionHead)
} }
func (self *LightChain) getProcInterrupt() bool { func (self *LightChain) getProcInterrupt() bool {
@ -292,7 +292,7 @@ func (self *LightChain) GetBlockByHash(ctx context.Context, hash common.Hash) (*
// GetBlockByNumber retrieves a block from the database or ODR service by // GetBlockByNumber retrieves a block from the database or ODR service by
// number, caching it (associated with its hash) if found. // number, caching it (associated with its hash) if found.
func (self *LightChain) GetBlockByNumber(ctx context.Context, number uint64) (*types.Block, error) { func (self *LightChain) GetBlockByNumber(ctx context.Context, number uint64) (*types.Block, error) {
hash, err := GetCanonicalHash(ctx, self.odr, number) hash, err := GetCanonicalHash(ctx, self.odr, self.indexerConfig.ChtSize, self.indexerConfig.ChtConfirm, number)
if hash == (common.Hash{}) || err != nil { if hash == (common.Hash{}) || err != nil {
return nil, err return nil, err
} }

View file

@ -44,7 +44,7 @@ type OdrBackend interface {
// OdrRequest is an interface for retrieval requests // OdrRequest is an interface for retrieval requests
type OdrRequest interface { type OdrRequest interface {
StoreResult(db ethdb.Database) StoreResult(db ethdb.Database, indexerConfig *IndexerConfig)
} }
// TrieID identifies a state or account storage trie // TrieID identifies a state or account storage trie
@ -86,7 +86,7 @@ type TrieRequest struct {
} }
// StoreResult stores the retrieved data in local database // StoreResult stores the retrieved data in local database
func (req *TrieRequest) StoreResult(db ethdb.Database) { func (req *TrieRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
req.Proof.Store(db) req.Proof.Store(db)
} }
@ -99,7 +99,7 @@ type CodeRequest struct {
} }
// StoreResult stores the retrieved data in local database // StoreResult stores the retrieved data in local database
func (req *CodeRequest) StoreResult(db ethdb.Database) { func (req *CodeRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
db.Put(req.Hash[:], req.Data) db.Put(req.Hash[:], req.Data)
} }
@ -112,7 +112,7 @@ type BlockRequest struct {
} }
// StoreResult stores the retrieved data in local database // StoreResult stores the retrieved data in local database
func (req *BlockRequest) StoreResult(db ethdb.Database) { func (req *BlockRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
rawdb.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp) rawdb.WriteBodyRLP(db, req.Hash, req.Number, req.Rlp)
} }
@ -125,15 +125,13 @@ type ReceiptsRequest struct {
} }
// StoreResult stores the retrieved data in local database // StoreResult stores the retrieved data in local database
func (req *ReceiptsRequest) StoreResult(db ethdb.Database) { func (req *ReceiptsRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
rawdb.WriteReceipts(db, req.Hash, req.Number, req.Receipts) rawdb.WriteReceipts(db, req.Hash, req.Number, req.Receipts)
} }
// ChtRequest is the ODR request type for state/storage trie entries // ChtRequest is the ODR request type for state/storage trie entries
type ChtRequest struct { type ChtRequest struct {
OdrRequest OdrRequest
SectionSize uint64
Confirms uint64
ChtNum, BlockNum uint64 ChtNum, BlockNum uint64
ChtRoot common.Hash ChtRoot common.Hash
Header *types.Header Header *types.Header
@ -142,7 +140,7 @@ type ChtRequest struct {
} }
// StoreResult stores the retrieved data in local database // StoreResult stores the retrieved data in local database
func (req *ChtRequest) StoreResult(db ethdb.Database) { func (req *ChtRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
hash, num := req.Header.Hash(), req.Header.Number.Uint64() hash, num := req.Header.Hash(), req.Header.Number.Uint64()
rawdb.WriteHeader(db, req.Header) rawdb.WriteHeader(db, req.Header)
@ -153,8 +151,6 @@ func (req *ChtRequest) StoreResult(db ethdb.Database) {
// BloomRequest is the ODR request type for retrieving bloom filters from a CHT structure // BloomRequest is the ODR request type for retrieving bloom filters from a CHT structure
type BloomRequest struct { type BloomRequest struct {
OdrRequest OdrRequest
SectionSize uint64
Confirms uint64
BloomTrieNum uint64 BloomTrieNum uint64
BitIdx uint BitIdx uint
SectionIdxList []uint64 SectionIdxList []uint64
@ -164,9 +160,9 @@ type BloomRequest struct {
} }
// StoreResult stores the retrieved data in local database // StoreResult stores the retrieved data in local database
func (req *BloomRequest) StoreResult(db ethdb.Database) { func (req *BloomRequest) StoreResult(db ethdb.Database, config *IndexerConfig) {
for i, sectionIdx := range req.SectionIdxList { for i, sectionIdx := range req.SectionIdxList {
sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*req.SectionSize-1) sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*config.BloomTrieSize-1)
// if we don't have the canonical hash stored for this section head number, we'll still store it under // if we don't have the canonical hash stored for this section head number, we'll still store it under
// a key with a zero sectionHead. GetBloomBits will look there too if we still don't have the canonical // a key with a zero sectionHead. GetBloomBits will look there too if we still don't have the canonical
// hash. In the unlikely case we've retrieved the section head hash since then, we'll just retrieve the // hash. In the unlikely case we've retrieved the section head hash since then, we'll just retrieve the

View file

@ -55,6 +55,7 @@ var (
type testOdr struct { type testOdr struct {
OdrBackend OdrBackend
indexerConfig *IndexerConfig
sdb, ldb ethdb.Database sdb, ldb ethdb.Database
disable bool disable bool
} }
@ -88,7 +89,7 @@ func (odr *testOdr) Retrieve(ctx context.Context, req OdrRequest) error {
case *CodeRequest: case *CodeRequest:
req.Data, _ = odr.sdb.Get(req.Hash[:]) req.Data, _ = odr.sdb.Get(req.Hash[:])
} }
req.StoreResult(odr.ldb) req.StoreResult(odr.ldb, odr.indexerConfig)
return nil return nil
} }
@ -258,7 +259,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
t.Fatal(err) t.Fatal(err)
} }
odr := &testOdr{sdb: sdb, ldb: ldb} odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: DefaultClientIndexerConfig}
lightchain, err := NewLightChain(odr, params.TestChainConfig, DefaultClientIndexerConfig, ethash.NewFullFaker()) lightchain, err := NewLightChain(odr, params.TestChainConfig, DefaultClientIndexerConfig, ethash.NewFullFaker())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View file

@ -25,7 +25,6 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
) )
@ -63,19 +62,19 @@ func GetHeaderByNumber(ctx context.Context, size uint64, confirms uint64, odr Od
if number >= chtCount*size { if number >= chtCount*size {
return nil, ErrNoTrustedCht return nil, ErrNoTrustedCht
} }
r := &ChtRequest{SectionSize: size, Confirms: confirms, ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: number} r := &ChtRequest{ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: number}
if err := odr.Retrieve(ctx, r); err != nil { if err := odr.Retrieve(ctx, r); err != nil {
return nil, err return nil, err
} }
return r.Header, nil return r.Header, nil
} }
func GetCanonicalHash(ctx context.Context, odr OdrBackend, number uint64) (common.Hash, error) { func GetCanonicalHash(ctx context.Context, odr OdrBackend, size uint64, confirm uint64, number uint64) (common.Hash, error) {
hash := rawdb.ReadCanonicalHash(odr.Database(), number) hash := rawdb.ReadCanonicalHash(odr.Database(), number)
if (hash != common.Hash{}) { if (hash != common.Hash{}) {
return hash, nil return hash, nil
} }
header, err := GetHeaderByNumber(ctx, params.CHTFrequencyClient, params.HelperTrieConfirmations, odr, number) header, err := GetHeaderByNumber(ctx, size, confirm, odr, number)
if header != nil { if header != nil {
return header.Hash(), nil return header.Hash(), nil
} }
@ -221,7 +220,7 @@ func GetBloomBits(ctx context.Context, size uint64, confirms uint64, odr OdrBack
return result, nil return result, nil
} }
r := &BloomRequest{SectionSize: size, Confirms: confirms, BloomTrieRoot: GetBloomTrieRoot(db, bloomTrieCount-1, sectionHead), BloomTrieNum: bloomTrieCount - 1, r := &BloomRequest{BloomTrieRoot: GetBloomTrieRoot(db, bloomTrieCount-1, sectionHead), BloomTrieNum: bloomTrieCount - 1,
BitIdx: bitIdx, SectionIdxList: reqList} BitIdx: bitIdx, SectionIdxList: reqList}
if err := odr.Retrieve(ctx, r); err != nil { if err := odr.Retrieve(ctx, r); err != nil {
return nil, err return nil, err

View file

@ -47,7 +47,7 @@ func TestNodeIterator(t *testing.T) {
} }
ctx := context.Background() ctx := context.Background()
odr := &testOdr{sdb: fulldb, ldb: lightdb} odr := &testOdr{sdb: fulldb, ldb: lightdb, indexerConfig: DefaultClientIndexerConfig}
head := blockchain.CurrentHeader() head := blockchain.CurrentHeader()
lightTrie, _ := NewStateDatabase(ctx, head, odr).OpenTrie(head.Root) lightTrie, _ := NewStateDatabase(ctx, head, odr).OpenTrie(head.Root)
fullTrie, _ := state.NewDatabase(fulldb).OpenTrie(head.Root) fullTrie, _ := state.NewDatabase(fulldb).OpenTrie(head.Root)

View file

@ -94,7 +94,7 @@ func TestTxPool(t *testing.T) {
panic(err) panic(err)
} }
odr := &testOdr{sdb: sdb, ldb: ldb} odr := &testOdr{sdb: sdb, ldb: ldb, indexerConfig: DefaultClientIndexerConfig}
relay := &testTxRelay{ relay := &testTxRelay{
send: make(chan int, 1), send: make(chan int, 1),
discard: make(chan int, 1), discard: make(chan int, 1),