light, les: indexer config

This commit is contained in:
rjl493456442 2018-07-18 14:12:42 +08:00
parent 98abaf09b7
commit e131a83e30
9 changed files with 96 additions and 56 deletions

View file

@ -116,7 +116,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
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, leth.chtIndexer, leth.bloomTrieIndexer, leth.bloomIndexer, leth.retriever)
if leth.blockchain, err = light.NewLightChain(leth.odr, leth.chainConfig, 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
} }
leth.bloomIndexer.Start(leth.blockchain) leth.bloomIndexer.Start(leth.blockchain)
@ -128,7 +128,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
} }
leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay) leth.txPool = light.NewTxPool(leth.chainConfig, leth.blockchain, leth.relay)
if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, true, ClientProtocolVersions, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, leth.serverPool, quitSync, &leth.wg); err != nil { if leth.protocolManager, err = NewProtocolManager(leth.chainConfig, light.DefaultClientIndexerConfig, true, ClientProtocolVersions, config.NetworkId, leth.eventMux, leth.engine, leth.peers, leth.blockchain, nil, chainDb, leth.odr, leth.relay, leth.serverPool, quitSync, &leth.wg); err != nil {
return nil, err return nil, err
} }
leth.ApiBackend = &LesApiBackend{leth, nil} leth.ApiBackend = &LesApiBackend{leth, nil}

View file

@ -94,19 +94,20 @@ type txPool interface {
} }
type ProtocolManager struct { type ProtocolManager struct {
lightSync bool lightSync bool
txpool txPool txpool txPool
txrelay *LesTxRelay txrelay *LesTxRelay
networkId uint64 networkId uint64
chainConfig *params.ChainConfig chainConfig *params.ChainConfig
blockchain BlockChain indexerConfig *light.IndexerConfig
chainDb ethdb.Database blockchain BlockChain
odr *LesOdr chainDb ethdb.Database
server *LesServer odr *LesOdr
serverPool *serverPool server *LesServer
lesTopic discv5.Topic serverPool *serverPool
reqDist *requestDistributor lesTopic discv5.Topic
retriever *retrieveManager reqDist *requestDistributor
retriever *retrieveManager
downloader *downloader.Downloader downloader *downloader.Downloader
fetcher *lightFetcher fetcher *lightFetcher
@ -129,24 +130,25 @@ type ProtocolManager struct {
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable // NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
// with the ethereum network. // with the ethereum network.
func NewProtocolManager(chainConfig *params.ChainConfig, lightSync bool, protocolVersions []uint, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, serverPool *serverPool, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) { func NewProtocolManager(chainConfig *params.ChainConfig, indexerConfig *light.IndexerConfig, lightSync bool, protocolVersions []uint, networkId uint64, mux *event.TypeMux, engine consensus.Engine, peers *peerSet, blockchain BlockChain, txpool txPool, chainDb ethdb.Database, odr *LesOdr, txrelay *LesTxRelay, serverPool *serverPool, quitSync chan struct{}, wg *sync.WaitGroup) (*ProtocolManager, error) {
// Create the protocol manager with the base fields // Create the protocol manager with the base fields
manager := &ProtocolManager{ manager := &ProtocolManager{
lightSync: lightSync, lightSync: lightSync,
eventMux: mux, eventMux: mux,
blockchain: blockchain, blockchain: blockchain,
chainConfig: chainConfig, chainConfig: chainConfig,
chainDb: chainDb, indexerConfig: indexerConfig,
odr: odr, chainDb: chainDb,
networkId: networkId, odr: odr,
txpool: txpool, networkId: networkId,
txrelay: txrelay, txpool: txpool,
serverPool: serverPool, txrelay: txrelay,
peers: peers, serverPool: serverPool,
newPeerCh: make(chan *peer), peers: peers,
quitSync: quitSync, newPeerCh: make(chan *peer),
wg: wg, quitSync: quitSync,
noMorePeers: make(chan struct{}), wg: wg,
noMorePeers: make(chan struct{}),
} }
if odr != nil { if odr != nil {
manager.retriever = odr.retriever manager.retriever = odr.retriever
@ -892,7 +894,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
trieDb := trie.NewDatabase(ethdb.NewTable(pm.chainDb, light.ChtTablePrefix)) trieDb := trie.NewDatabase(ethdb.NewTable(pm.chainDb, light.ChtTablePrefix))
for _, req := range req.Reqs { for _, req := range req.Reqs {
if header := pm.blockchain.GetHeaderByNumber(req.BlockNum); header != nil { if header := pm.blockchain.GetHeaderByNumber(req.BlockNum); header != nil {
sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, req.ChtNum*params.CHTFrequencyServer-1) sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, req.ChtNum*pm.indexerConfig.ChtSize-1)
if root := light.GetChtRoot(pm.chainDb, req.ChtNum-1, sectionHead); root != (common.Hash{}) { if root := light.GetChtRoot(pm.chainDb, req.ChtNum-1, sectionHead); root != (common.Hash{}) {
trie, err := trie.New(root, trieDb) trie, err := trie.New(root, trieDb)
if err != nil { if err != nil {
@ -1147,11 +1149,11 @@ func (pm *ProtocolManager) getAccount(statedb *state.StateDB, root, hash common.
func (pm *ProtocolManager) getHelperTrie(id uint, idx uint64) (common.Hash, string) { func (pm *ProtocolManager) getHelperTrie(id uint, idx uint64) (common.Hash, string) {
switch id { switch id {
case htCanonical: case htCanonical:
idxV2 := (idx+1)*(params.CHTFrequencyClient/params.CHTFrequencyServer) - 1 idxV2 := (idx+1)*(pm.indexerConfig.ChtClientSize/pm.indexerConfig.ChtSize) - 1
sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*params.CHTFrequencyClient-1) sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.indexerConfig.ChtClientSize-1)
return light.GetChtRoot(pm.chainDb, idxV2, sectionHead), light.ChtTablePrefix return light.GetChtRoot(pm.chainDb, idxV2, sectionHead), light.ChtTablePrefix
case htBloomBits: case htBloomBits:
sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*params.BloomTrieFrequency-1) sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.indexerConfig.BloomTrieSize-1)
return light.GetBloomTrieRoot(pm.chainDb, idx, sectionHead), light.BloomTrieTablePrefix return light.GetBloomTrieRoot(pm.chainDb, idx, sectionHead), light.BloomTrieTablePrefix
} }
return common.Hash{}, "" return common.Hash{}, ""

View file

@ -152,7 +152,7 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
} }
if lightSync { if lightSync {
chain, _ = light.NewLightChain(odr, gspec.Config, engine) chain, _ = light.NewLightChain(odr, gspec.Config, light.DefaultClientIndexerConfig, engine)
} else { } else {
blockchain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}) blockchain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{})
@ -173,13 +173,19 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor
chain = blockchain chain = blockchain
} }
var protocolVersions []uint var (
protocolVersions []uint
indexConfig *light.IndexerConfig
)
if lightSync { if lightSync {
protocolVersions = ClientProtocolVersions protocolVersions = ClientProtocolVersions
indexConfig = light.DefaultClientIndexerConfig
} else { } else {
protocolVersions = ServerProtocolVersions protocolVersions = ServerProtocolVersions
indexConfig = light.DefaultServerIndexerConfig
} }
pm, err := NewProtocolManager(gspec.Config, lightSync, protocolVersions, NetworkId, evmux, engine, peers, chain, nil, db, odr, nil, nil, make(chan struct{}), new(sync.WaitGroup)) pm, err := NewProtocolManager(gspec.Config, indexConfig, lightSync, protocolVersions, NetworkId, evmux, engine, peers, chain, nil, db, odr, nil, nil, make(chan struct{}), new(sync.WaitGroup))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -53,7 +53,7 @@ type LesServer struct {
func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) { func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
quitSync := make(chan struct{}) quitSync := make(chan struct{})
pm, err := NewProtocolManager(eth.BlockChain().Config(), false, ServerProtocolVersions, config.NetworkId, eth.EventMux(), eth.Engine(), newPeerSet(), eth.BlockChain(), eth.TxPool(), eth.ChainDb(), nil, nil, nil, quitSync, new(sync.WaitGroup)) pm, err := NewProtocolManager(eth.BlockChain().Config(), light.DefaultServerIndexerConfig, false, ServerProtocolVersions, config.NetworkId, eth.EventMux(), eth.Engine(), newPeerSet(), eth.BlockChain(), eth.TxPool(), eth.ChainDb(), nil, nil, nil, quitSync, new(sync.WaitGroup))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -48,6 +48,7 @@ var (
// interface. It only does header validation during chain insertion. // interface. It only does header validation during chain insertion.
type LightChain struct { type LightChain struct {
hc *core.HeaderChain hc *core.HeaderChain
indexerConfig *IndexerConfig
chainDb ethdb.Database chainDb ethdb.Database
odr OdrBackend odr OdrBackend
chainFeed event.Feed chainFeed event.Feed
@ -75,19 +76,20 @@ type LightChain struct {
// NewLightChain returns a fully initialised light chain using information // NewLightChain returns a fully initialised light chain using information
// available in the database. It initialises the default Ethereum header // available in the database. It initialises the default Ethereum header
// validator. // validator.
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine) (*LightChain, error) { func NewLightChain(odr OdrBackend, config *params.ChainConfig, indexerConfig *IndexerConfig, engine consensus.Engine) (*LightChain, error) {
bodyCache, _ := lru.New(bodyCacheLimit) bodyCache, _ := lru.New(bodyCacheLimit)
bodyRLPCache, _ := lru.New(bodyCacheLimit) bodyRLPCache, _ := lru.New(bodyCacheLimit)
blockCache, _ := lru.New(blockCacheLimit) blockCache, _ := lru.New(blockCacheLimit)
bc := &LightChain{ bc := &LightChain{
chainDb: odr.Database(), chainDb: odr.Database(),
odr: odr, indexerConfig: indexerConfig,
quit: make(chan struct{}), odr: odr,
bodyCache: bodyCache, quit: make(chan struct{}),
bodyRLPCache: bodyRLPCache, bodyCache: bodyCache,
blockCache: blockCache, bodyRLPCache: bodyRLPCache,
engine: engine, blockCache: blockCache,
engine: engine,
} }
var err error var err error
bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt) bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt)
@ -457,7 +459,7 @@ func (self *LightChain) GetHeaderByNumberOdr(ctx context.Context, number uint64)
if header := self.hc.GetHeaderByNumber(number); header != nil { if header := self.hc.GetHeaderByNumber(number); header != nil {
return header, nil return header, nil
} }
return GetHeaderByNumber(ctx, params.CHTFrequencyClient, params.HelperTrieConfirmations, self.odr, number) return GetHeaderByNumber(ctx, self.indexerConfig.ChtSize, self.indexerConfig.ChtConfirm, self.odr, number)
} }
// Config retrieves the header chain's chain configuration. // Config retrieves the header chain's chain configuration.
@ -469,9 +471,9 @@ func (self *LightChain) SyncCht(ctx context.Context) bool {
} }
headNum := self.CurrentHeader().Number.Uint64() headNum := self.CurrentHeader().Number.Uint64()
chtCount, _, _ := self.odr.ChtIndexer().Sections() chtCount, _, _ := self.odr.ChtIndexer().Sections()
if headNum+1 < chtCount*params.CHTFrequencyClient { if headNum+1 < chtCount*self.indexerConfig.ChtSize {
num := chtCount*params.CHTFrequencyClient - 1 num := chtCount*self.indexerConfig.ChtSize - 1
header, err := GetHeaderByNumber(ctx, params.CHTFrequencyClient, params.HelperTrieConfirmations, self.odr, num) header, err := GetHeaderByNumber(ctx, self.indexerConfig.ChtSize, self.indexerConfig.ChtConfirm, self.odr, num)
if header != nil && err == nil { if header != nil && err == nil {
self.mu.Lock() self.mu.Lock()
if self.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() { if self.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() {

View file

@ -55,7 +55,7 @@ func newCanonical(n int) (ethdb.Database, *LightChain, error) {
db := ethdb.NewMemDatabase() db := ethdb.NewMemDatabase()
gspec := core.Genesis{Config: params.TestChainConfig} gspec := core.Genesis{Config: params.TestChainConfig}
genesis := gspec.MustCommit(db) genesis := gspec.MustCommit(db)
blockchain, _ := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFaker()) blockchain, _ := NewLightChain(&dummyOdr{db: db}, gspec.Config, DefaultClientIndexerConfig, ethash.NewFaker())
// Create and inject the requested chain // Create and inject the requested chain
if n == 0 { if n == 0 {
@ -75,7 +75,7 @@ func newTestLightChain() *LightChain {
Config: params.TestChainConfig, Config: params.TestChainConfig,
} }
gspec.MustCommit(db) gspec.MustCommit(db)
lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, ethash.NewFullFaker()) lc, err := NewLightChain(&dummyOdr{db: db}, gspec.Config, DefaultClientIndexerConfig, ethash.NewFullFaker())
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -339,7 +339,7 @@ func TestReorgBadHeaderHashes(t *testing.T) {
defer func() { delete(core.BadHashes, headers[3].Hash()) }() defer func() { delete(core.BadHashes, headers[3].Hash()) }()
// Create a new LightChain and check that it rolled back the state. // Create a new LightChain and check that it rolled back the state.
ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, params.TestChainConfig, ethash.NewFaker()) ncm, err := NewLightChain(&dummyOdr{db: bc.chainDb}, params.TestChainConfig, DefaultClientIndexerConfig, ethash.NewFaker())
if err != nil { if err != nil {
t.Fatalf("failed to create new chain manager: %v", err) t.Fatalf("failed to create new chain manager: %v", err)
} }

View file

@ -259,7 +259,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
} }
odr := &testOdr{sdb: sdb, ldb: ldb} odr := &testOdr{sdb: sdb, ldb: ldb}
lightchain, err := NewLightChain(odr, params.TestChainConfig, 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

@ -34,6 +34,36 @@ import (
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
) )
// IndexerConfig specifies a set of configs for chain indexers.
type IndexerConfig struct {
ChtSize uint64
ChtClientSize uint64
ChtConfirm uint64
BloomSize uint64
BloomConfirm uint64
BloomTrieSize uint64
BloomTrieConfirm uint64
}
var DefaultServerIndexerConfig = &IndexerConfig{
ChtSize: params.CHTFrequencyServer,
ChtClientSize: params.CHTFrequencyClient,
ChtConfirm: params.HelperTrieProcessConfirmations,
BloomSize: params.BloomBitsBlocks,
BloomConfirm: params.BloomConfirms,
BloomTrieSize: params.BloomTrieFrequency,
BloomTrieConfirm: params.HelperTrieProcessConfirmations,
}
var DefaultClientIndexerConfig = &IndexerConfig{
ChtSize: params.CHTFrequencyClient,
ChtConfirm: params.HelperTrieConfirmations,
BloomSize: params.BloomBitsBlocksClient,
BloomConfirm: params.HelperTrieConfirmations,
BloomTrieSize: params.BloomTrieFrequency,
BloomTrieConfirm: params.HelperTrieConfirmations,
}
// trustedCheckpoint represents a set of post-processed trie roots (CHT and BloomTrie) associated with // trustedCheckpoint represents a set of post-processed trie roots (CHT and BloomTrie) associated with
// the appropriate section index and head hash. It is used to start light syncing from this checkpoint // the appropriate section index and head hash. It is used to start light syncing from this checkpoint
// and avoid downloading the entire header chain while still being able to securely access old headers/logs. // and avoid downloading the entire header chain while still being able to securely access old headers/logs.

View file

@ -100,7 +100,7 @@ func TestTxPool(t *testing.T) {
discard: make(chan int, 1), discard: make(chan int, 1),
mined: make(chan int, 1), mined: make(chan int, 1),
} }
lightchain, _ := NewLightChain(odr, params.TestChainConfig, ethash.NewFullFaker()) lightchain, _ := NewLightChain(odr, params.TestChainConfig, DefaultClientIndexerConfig, ethash.NewFullFaker())
txPermanent = 50 txPermanent = 50
pool := NewTxPool(params.TestChainConfig, lightchain, relay) pool := NewTxPool(params.TestChainConfig, lightchain, relay)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)