les, light, params: polish a bit

This commit is contained in:
rjl493456442 2018-07-20 13:03:16 +08:00
parent b790f4aab8
commit 3ededf0edd
10 changed files with 53 additions and 29 deletions

View file

@ -223,8 +223,8 @@ func (s *LightEthereum) Protocols() []p2p.Protocol {
// Start implements node.Service, starting all internal goroutines needed by the // Start implements node.Service, starting all internal goroutines needed by the
// Ethereum protocol implementation. // Ethereum protocol implementation.
func (s *LightEthereum) Start(srvr *p2p.Server) error { func (s *LightEthereum) Start(srvr *p2p.Server) error {
s.startBloomHandlers(params.BloomBitsBlocksClient, params.HelperTrieConfirmations)
log.Warn("Light client mode is an experimental feature") log.Warn("Light client mode is an experimental feature")
s.startBloomHandlers(params.BloomBitsBlocksClient)
s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.networkId) s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.networkId)
// clients are searching for the first advertised protocol in the list // clients are searching for the first advertised protocol in the list
protocolVersion := AdvertiseProtocolVersions[0] protocolVersion := AdvertiseProtocolVersions[0]

View file

@ -43,7 +43,7 @@ const (
// startBloomHandlers starts a batch of goroutines to accept bloom bit database // startBloomHandlers starts a batch of goroutines to accept bloom bit database
// retrievals from possibly a range of filters and serving the data to satisfy. // retrievals from possibly a range of filters and serving the data to satisfy.
func (eth *LightEthereum) startBloomHandlers(sectionSize, confirms uint64) { func (eth *LightEthereum) startBloomHandlers(sectionSize uint64) {
for i := 0; i < bloomServiceThreads; i++ { for i := 0; i < bloomServiceThreads; i++ {
go func() { go func() {
for { for {
@ -54,7 +54,7 @@ func (eth *LightEthereum) startBloomHandlers(sectionSize, confirms uint64) {
case request := <-eth.bloomRequests: case request := <-eth.bloomRequests:
task := <-request task := <-request
task.Bitsets = make([][]byte, len(task.Sections)) task.Bitsets = make([][]byte, len(task.Sections))
compVectors, err := light.GetBloomBits(task.Context, sectionSize, confirms, eth.odr, task.Bit, task.Sections) compVectors, err := light.GetBloomBits(task.Context, eth.odr, task.Bit, task.Sections)
if err == nil { if err == nil {
for i := range task.Sections { for i := range task.Sections {
if blob, err := bitutil.DecompressBytes(compVectors[i], int(sectionSize/8)); err == nil { if blob, err := bitutil.DecompressBytes(compVectors[i], int(sectionSize/8)); err == nil {

View file

@ -1149,8 +1149,8 @@ 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)*(pm.indexerConfig.ChtClientSize/pm.indexerConfig.ChtSize) - 1 idxV2 := (idx+1)*(pm.indexerConfig.PairChtSize/pm.indexerConfig.ChtSize) - 1
sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.indexerConfig.ChtClientSize-1) sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.indexerConfig.PairChtSize-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)*pm.indexerConfig.BloomTrieSize-1) sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*pm.indexerConfig.BloomTrieSize-1)

View file

@ -71,6 +71,11 @@ func (odr *LesOdr) BloomIndexer() *core.ChainIndexer {
return odr.bloomIndexer return odr.bloomIndexer
} }
// IndexerConfig returns the indexer config.
func (odr *LesOdr) IndexerConfig() *light.IndexerConfig {
return odr.indexerConfig
}
const ( const (
MsgBlockBodies = iota MsgBlockBodies = iota
MsgCode MsgCode

View file

@ -387,7 +387,7 @@ func (r *ChtRequest) Request(reqID uint64, peer *peer, config *light.IndexerConf
} }
blockNum := binary.BigEndian.Uint64(req.Key) blockNum := binary.BigEndian.Uint64(req.Key)
// convert HelperTrie request to old CHT request // convert HelperTrie request to old CHT request
reqsV1 = ChtReq{ChtNum: (req.TrieIdx+1)*(config.ChtSize/config.ChtClientSize) - 1, BlockNum: blockNum, FromLevel: req.FromLevel} reqsV1 = ChtReq{ChtNum: (req.TrieIdx+1)*(config.ChtSize/config.PairChtSize) - 1, BlockNum: blockNum, FromLevel: req.FromLevel}
return peer.RequestHelperTrieProofs(reqID, r.GetCost(peer), []interface{}{reqsV1}) return peer.RequestHelperTrieProofs(reqID, r.GetCost(peer), []interface{}{reqsV1})
case lpv2: case lpv2:
return peer.RequestHelperTrieProofs(reqID, r.GetCost(peer), []interface{}{req}) return peer.RequestHelperTrieProofs(reqID, r.GetCost(peer), []interface{}{req})

View file

@ -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, self.indexerConfig.ChtSize, self.indexerConfig.ChtConfirm, number) hash, err := GetCanonicalHash(ctx, self.odr, number)
if hash == (common.Hash{}) || err != nil { if hash == (common.Hash{}) || err != nil {
return nil, err return nil, err
} }
@ -459,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, self.indexerConfig.ChtSize, self.indexerConfig.ChtConfirm, self.odr, number) return GetHeaderByNumber(ctx, self.odr, number)
} }
// Config retrieves the header chain's chain configuration. // Config retrieves the header chain's chain configuration.
@ -473,7 +473,7 @@ func (self *LightChain) SyncCht(ctx context.Context) bool {
chtCount, _, _ := self.odr.ChtIndexer().Sections() chtCount, _, _ := self.odr.ChtIndexer().Sections()
if headNum+1 < chtCount*self.indexerConfig.ChtSize { if headNum+1 < chtCount*self.indexerConfig.ChtSize {
num := chtCount*self.indexerConfig.ChtSize - 1 num := chtCount*self.indexerConfig.ChtSize - 1
header, err := GetHeaderByNumber(ctx, self.indexerConfig.ChtSize, self.indexerConfig.ChtConfirm, self.odr, num) header, err := GetHeaderByNumber(ctx, 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

@ -40,6 +40,7 @@ type OdrBackend interface {
BloomTrieIndexer() *core.ChainIndexer BloomTrieIndexer() *core.ChainIndexer
BloomIndexer() *core.ChainIndexer BloomIndexer() *core.ChainIndexer
Retrieve(ctx context.Context, req OdrRequest) error Retrieve(ctx context.Context, req OdrRequest) error
IndexerConfig() *IndexerConfig
} }
// OdrRequest is an interface for retrieval requests // OdrRequest is an interface for retrieval requests

View file

@ -30,7 +30,7 @@ import (
var sha3_nil = crypto.Keccak256Hash(nil) var sha3_nil = crypto.Keccak256Hash(nil)
func GetHeaderByNumber(ctx context.Context, size uint64, confirms uint64, odr OdrBackend, number uint64) (*types.Header, error) { func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*types.Header, error) {
db := odr.Database() db := odr.Database()
hash := rawdb.ReadCanonicalHash(db, number) hash := rawdb.ReadCanonicalHash(db, number)
if (hash != common.Hash{}) { if (hash != common.Hash{}) {
@ -53,13 +53,13 @@ func GetHeaderByNumber(ctx context.Context, size uint64, confirms uint64, odr Od
for chtCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) { for chtCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) {
chtCount-- chtCount--
if chtCount > 0 { if chtCount > 0 {
sectionHeadNum = chtCount*size - 1 sectionHeadNum = chtCount*odr.IndexerConfig().ChtSize - 1
sectionHead = odr.ChtIndexer().SectionHead(chtCount - 1) sectionHead = odr.ChtIndexer().SectionHead(chtCount - 1)
canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum) canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum)
} }
} }
} }
if number >= chtCount*size { if number >= chtCount*odr.IndexerConfig().ChtSize {
return nil, ErrNoTrustedCht return nil, ErrNoTrustedCht
} }
r := &ChtRequest{ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: number} r := &ChtRequest{ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: number}
@ -69,12 +69,12 @@ func GetHeaderByNumber(ctx context.Context, size uint64, confirms uint64, odr Od
return r.Header, nil return r.Header, nil
} }
func GetCanonicalHash(ctx context.Context, odr OdrBackend, size uint64, confirm uint64, number uint64) (common.Hash, error) { func GetCanonicalHash(ctx context.Context, odr OdrBackend, 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, size, confirm, odr, number) header, err := GetHeaderByNumber(ctx, odr, number)
if header != nil { if header != nil {
return header.Hash(), nil return header.Hash(), nil
} }
@ -174,10 +174,10 @@ func GetBlockLogs(ctx context.Context, odr OdrBackend, hash common.Hash, number
} }
// GetBloomBits retrieves a batch of compressed bloomBits vectors belonging to the given bit index and section indexes // GetBloomBits retrieves a batch of compressed bloomBits vectors belonging to the given bit index and section indexes
func GetBloomBits(ctx context.Context, size uint64, confirms uint64, odr OdrBackend, bitIdx uint, sectionIdxList []uint64) ([][]byte, error) { func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxList []uint64) ([][]byte, error) {
db := odr.Database()
result := make([][]byte, len(sectionIdxList))
var ( var (
db = odr.Database()
result = make([][]byte, len(sectionIdxList))
reqList []uint64 reqList []uint64
reqIdx []int reqIdx []int
) )
@ -193,7 +193,7 @@ func GetBloomBits(ctx context.Context, size uint64, confirms uint64, odr OdrBack
for bloomTrieCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) { for bloomTrieCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) {
bloomTrieCount-- bloomTrieCount--
if bloomTrieCount > 0 { if bloomTrieCount > 0 {
sectionHeadNum = bloomTrieCount*size - 1 sectionHeadNum = bloomTrieCount*odr.IndexerConfig().BloomTrieSize - 1
sectionHead = odr.BloomTrieIndexer().SectionHead(bloomTrieCount - 1) sectionHead = odr.BloomTrieIndexer().SectionHead(bloomTrieCount - 1)
canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum) canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum)
} }
@ -201,7 +201,7 @@ func GetBloomBits(ctx context.Context, size uint64, confirms uint64, odr OdrBack
} }
for i, sectionIdx := range sectionIdxList { for i, sectionIdx := range sectionIdxList {
sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*size-1) sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*odr.IndexerConfig().BloomSize-1)
// if we don't have the canonical hash stored for this section head number, we'll still look for // if we don't have the canonical hash stored for this section head number, we'll still look for
// an entry with a zero sectionHead (we store it with zero section head too if we don't know it // an entry with a zero sectionHead (we store it with zero section head too if we don't know it
// at the time of the retrieval) // at the time of the retrieval)
@ -209,6 +209,7 @@ func GetBloomBits(ctx context.Context, size uint64, confirms uint64, odr OdrBack
if err == nil { if err == nil {
result[i] = bloomBits result[i] = bloomBits
} else { } else {
// TODO(rjl493456442) Convert sectionIndex to BloomTrie relative index
if sectionIdx >= bloomTrieCount { if sectionIdx >= bloomTrieCount {
return nil, ErrNoTrustedBloomTrie return nil, ErrNoTrustedBloomTrie
} }

View file

@ -34,20 +34,35 @@ import (
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
) )
// IndexerConfig specifies a set of configs for chain indexers. // IndexerConfig includes a set of configs for chain indexers.
type IndexerConfig struct { type IndexerConfig struct {
ChtSize uint64 // The block frequency for creating CHTs.
ChtClientSize uint64 ChtSize uint64
ChtConfirm uint64
BloomSize uint64 // A special auxiliary field represents client's chtsize for server config, otherwise represents server's chtsize.
BloomConfirm uint64 PairChtSize uint64
BloomTrieSize uint64
// The number of confirmations needed to generate/accept a canonical hash help trie.
ChtConfirm uint64
// The block frequency for creating new bloom bits.
BloomSize uint64
// The number of confirmation needed before a bloom section is considered probably final and its rotated bits
// are calculated.
BloomConfirm uint64
// The block frequency for creating BloomTrie.
BloomTrieSize uint64
// The number of confirmations needed to generate/accept a bloom trie.
BloomTrieConfirm uint64 BloomTrieConfirm uint64
} }
// DefaultServerIndexerConfig wraps a set of configs as a default indexer config for server side.
var DefaultServerIndexerConfig = &IndexerConfig{ var DefaultServerIndexerConfig = &IndexerConfig{
ChtSize: params.CHTFrequencyServer, ChtSize: params.CHTFrequencyServer,
ChtClientSize: params.CHTFrequencyClient, PairChtSize: params.CHTFrequencyClient,
ChtConfirm: params.HelperTrieProcessConfirmations, ChtConfirm: params.HelperTrieProcessConfirmations,
BloomSize: params.BloomBitsBlocks, BloomSize: params.BloomBitsBlocks,
BloomConfirm: params.BloomConfirms, BloomConfirm: params.BloomConfirms,
@ -55,8 +70,10 @@ var DefaultServerIndexerConfig = &IndexerConfig{
BloomTrieConfirm: params.HelperTrieProcessConfirmations, BloomTrieConfirm: params.HelperTrieProcessConfirmations,
} }
// DefaultClientIndexerConfig wraps a set of configs as a default indexer config for client side.
var DefaultClientIndexerConfig = &IndexerConfig{ var DefaultClientIndexerConfig = &IndexerConfig{
ChtSize: params.CHTFrequencyClient, ChtSize: params.CHTFrequencyClient,
PairChtSize: params.CHTFrequencyServer,
ChtConfirm: params.HelperTrieConfirmations, ChtConfirm: params.HelperTrieConfirmations,
BloomSize: params.BloomBitsBlocksClient, BloomSize: params.BloomBitsBlocksClient,
BloomConfirm: params.HelperTrieConfirmations, BloomConfirm: params.HelperTrieConfirmations,

View file

@ -21,7 +21,7 @@ package params
const ( const (
// BloomBitsBlocks is the number of blocks a single bloom bit section vector // BloomBitsBlocks is the number of blocks a single bloom bit section vector
// contains. // contains on the server side.
BloomBitsBlocks uint64 = 4096 BloomBitsBlocks uint64 = 4096
// BloomBitsBlocksClient is the number of blocks a single bloom bit section vector // BloomBitsBlocksClient is the number of blocks a single bloom bit section vector
@ -44,7 +44,7 @@ const (
// server/client sides. // server/client sides.
BloomTrieFrequency = 32768 BloomTrieFrequency = 32768
// HelperTrieConfirmations is the number of confirmations before a server is expected // HelperTrieConfirmations is the number of confirmations before a client is expected
// to have the given HelperTrie available. // to have the given HelperTrie available.
HelperTrieConfirmations = 2048 HelperTrieConfirmations = 2048