diff --git a/eth/bloombits.go b/eth/bloombits.go index 147be85dfe..45f472b883 100644 --- a/eth/bloombits.go +++ b/eth/bloombits.go @@ -79,7 +79,6 @@ func (eth *Ethereum) startBloomHandlers(sectionSize uint64) { } const ( - // bloomThrottling is the time to wait between processing two consecutive index // sections. It's useful during chain upgrades to prevent disk overload. bloomThrottling = 100 * time.Millisecond diff --git a/les/api_backend.go b/les/api_backend.go index dea33c4702..037a798056 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -189,7 +189,7 @@ func (b *LesApiBackend) BloomStatus() (uint64, uint64) { return 0, 0 } sections, _, _ := b.eth.bloomIndexer.Sections() - return light.BloomTrieFrequency, sections + return params.BloomTrieFrequency, sections } func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { diff --git a/les/backend.go b/les/backend.go index 0bea84c6d2..9772953966 100644 --- a/les/backend.go +++ b/les/backend.go @@ -106,10 +106,10 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { shutdownChan: make(chan bool), networkId: config.NetworkId, bloomRequests: make(chan chan *bloombits.Retrieval), - bloomIndexer: eth.NewBloomIndexer(chainDb, light.BloomTrieFrequency, params.BloomConfirms), - chtIndexer: light.NewChtIndexer(chainDb, light.CHTFrequencyClient, light.HelperTrieConfirmations), - bloomTrieIndexer: light.NewBloomTrieIndexer(chainDb, light.BloomTrieFrequency, params.BloomConfirms, - light.BloomTrieFrequency, light.HelperTrieConfirmations), + bloomIndexer: eth.NewBloomIndexer(chainDb, params.BloomTrieFrequency, params.BloomConfirms), + chtIndexer: light.NewChtIndexer(chainDb, params.CHTFrequencyClient, params.HelperTrieConfirmations), + bloomTrieIndexer: light.NewBloomTrieIndexer(chainDb, params.BloomTrieFrequency, params.BloomConfirms, + params.BloomTrieFrequency, params.HelperTrieConfirmations), } leth.relay = NewLesTxRelay(peers, leth.reqDist) @@ -223,7 +223,7 @@ func (s *LightEthereum) Protocols() []p2p.Protocol { // Start implements node.Service, starting all internal goroutines needed by the // Ethereum protocol implementation. func (s *LightEthereum) Start(srvr *p2p.Server) error { - s.startBloomHandlers(light.BloomTrieFrequency) + s.startBloomHandlers(params.BloomTrieFrequency, params.HelperTrieConfirmations) log.Warn("Light client mode is an experimental feature") s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.networkId) // clients are searching for the first advertised protocol in the list diff --git a/les/bloombits.go b/les/bloombits.go index aea0fcd5f4..4e6fecbe20 100644 --- a/les/bloombits.go +++ b/les/bloombits.go @@ -43,7 +43,7 @@ const ( // startBloomHandlers starts a batch of goroutines to accept bloom bit database // retrievals from possibly a range of filters and serving the data to satisfy. -func (eth *LightEthereum) startBloomHandlers(sectionSize uint64) { +func (eth *LightEthereum) startBloomHandlers(sectionSize, confirms uint64) { for i := 0; i < bloomServiceThreads; i++ { go func() { for { @@ -54,7 +54,7 @@ func (eth *LightEthereum) startBloomHandlers(sectionSize uint64) { case request := <-eth.bloomRequests: task := <-request task.Bitsets = make([][]byte, len(task.Sections)) - compVectors, err := light.GetBloomBits(task.Context, eth.odr, task.Bit, task.Sections) + compVectors, err := light.GetBloomBits(task.Context, sectionSize, confirms, eth.odr, task.Bit, task.Sections) if err == nil { for i := range task.Sections { if blob, err := bitutil.DecompressBytes(compVectors[i], int(sectionSize/8)); err == nil { diff --git a/les/handler.go b/les/handler.go index f0aa8aeafe..1e4670f354 100644 --- a/les/handler.go +++ b/les/handler.go @@ -892,7 +892,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { trieDb := trie.NewDatabase(ethdb.NewTable(pm.chainDb, light.ChtTablePrefix)) for _, req := range req.Reqs { if header := pm.blockchain.GetHeaderByNumber(req.BlockNum); header != nil { - sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, req.ChtNum*light.CHTFrequencyServer-1) + sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, req.ChtNum*params.CHTFrequencyServer-1) if root := light.GetChtRoot(pm.chainDb, req.ChtNum-1, sectionHead); root != (common.Hash{}) { trie, err := trie.New(root, trieDb) if err != nil { @@ -1147,11 +1147,11 @@ func (pm *ProtocolManager) getAccount(statedb *state.StateDB, root, hash common. func (pm *ProtocolManager) getHelperTrie(id uint, idx uint64) (common.Hash, string) { switch id { case htCanonical: - idxV2 := (idx+1)*(light.CHTFrequencyClient/light.CHTFrequencyServer) - 1 - sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*light.CHTFrequencyClient-1) + idxV2 := (idx+1)*(params.CHTFrequencyClient/params.CHTFrequencyServer) - 1 + sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*params.CHTFrequencyClient-1) return light.GetChtRoot(pm.chainDb, idxV2, sectionHead), light.ChtTablePrefix case htBloomBits: - sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*light.BloomTrieFrequency-1) + sectionHead := rawdb.ReadCanonicalHash(pm.chainDb, (idx+1)*params.BloomTrieFrequency-1) return light.GetBloomTrieRoot(pm.chainDb, idx, sectionHead), light.BloomTrieTablePrefix } return common.Hash{}, "" diff --git a/les/handler_test.go b/les/handler_test.go index 774e0dcb77..8e424865b6 100644 --- a/les/handler_test.go +++ b/les/handler_test.go @@ -376,20 +376,20 @@ func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) } func testGetCHTProofs(t *testing.T, protocol int) { // Figure out the client's CHT frequency - frequency := uint64(light.CHTFrequencyClient) + frequency := uint64(params.CHTFrequencyClient) if protocol == 1 { - frequency = uint64(light.CHTFrequencyServer) + frequency = uint64(params.CHTFrequencyServer) } // Assemble the test environment db := ethdb.NewMemDatabase() - pm := newTestProtocolManagerMust(t, false, int(frequency)+light.HelperTrieProcessConfirmations, testChainGen, nil, nil, db) + pm := newTestProtocolManagerMust(t, false, int(frequency)+params.HelperTrieProcessConfirmations, testChainGen, nil, nil, db) bc := pm.blockchain.(*core.BlockChain) peer, _ := newTestPeer(t, "peer", protocol, pm, true) defer peer.close() // Wait a while for the CHT indexer to process the new headers - time.Sleep(100 * time.Millisecond * time.Duration(frequency/light.CHTFrequencyServer)) // Chain indexer throttling - time.Sleep(250 * time.Millisecond) // CI tester slack + time.Sleep(100 * time.Millisecond * time.Duration(frequency/params.CHTFrequencyServer)) // Chain indexer throttling + time.Sleep(250 * time.Millisecond) // CI tester slack // Assemble the proofs from the different protocols header := bc.GetHeaderByNumber(frequency) @@ -414,7 +414,7 @@ func testGetCHTProofs(t *testing.T, protocol int) { proofsV1[0].Proof = proof case 2: - root := light.GetChtRoot(db, (light.CHTFrequencyClient/light.CHTFrequencyServer)-1, bc.GetHeaderByNumber(frequency-1).Hash()) + root := light.GetChtRoot(db, (params.CHTFrequencyClient/params.CHTFrequencyServer)-1, bc.GetHeaderByNumber(frequency-1).Hash()) trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(db, light.ChtTablePrefix))) trie.Prove(key, 0, &proofsV2.Proofs) } @@ -450,14 +450,14 @@ func testGetCHTProofs(t *testing.T, protocol int) { func TestGetBloombitsProofs(t *testing.T) { // Assemble the test environment db := ethdb.NewMemDatabase() - pm := newTestProtocolManagerMust(t, false, light.BloomTrieFrequency+256, testChainGen, nil, nil, db) + pm := newTestProtocolManagerMust(t, false, params.BloomTrieFrequency+256, testChainGen, nil, nil, db) bc := pm.blockchain.(*core.BlockChain) peer, _ := newTestPeer(t, "peer", 2, pm, true) defer peer.close() // Wait a while for the bloombits indexer to process the new headers - time.Sleep(100 * time.Millisecond * time.Duration(light.BloomTrieFrequency/4096)) // Chain indexer throttling - time.Sleep(250 * time.Millisecond) // CI tester slack + time.Sleep(100 * time.Millisecond * time.Duration(params.BloomTrieFrequency/4096)) // Chain indexer throttling + time.Sleep(250 * time.Millisecond) // CI tester slack // Request and verify each bit of the bloom bits proofs for bit := 0; bit < 2048; bit++ { @@ -465,7 +465,7 @@ func TestGetBloombitsProofs(t *testing.T) { key := make([]byte, 10) binary.BigEndian.PutUint16(key[:2], uint16(bit)) - binary.BigEndian.PutUint64(key[2:], uint64(light.BloomTrieFrequency)) + binary.BigEndian.PutUint64(key[2:], uint64(params.BloomTrieFrequency)) requests := []HelperTrieReq{{ Type: htBloomBits, @@ -474,7 +474,7 @@ func TestGetBloombitsProofs(t *testing.T) { }} var proofs HelperTrieResps - root := light.GetBloomTrieRoot(db, 0, bc.GetHeaderByNumber(light.BloomTrieFrequency-1).Hash()) + root := light.GetBloomTrieRoot(db, 0, bc.GetHeaderByNumber(params.BloomTrieFrequency-1).Hash()) trie, _ := trie.New(root, trie.NewDatabase(ethdb.NewTable(db, light.BloomTrieTablePrefix))) trie.Prove(key, 0, &proofs.Proofs) diff --git a/les/helper_test.go b/les/helper_test.go index 440cfbef49..04ff0d786b 100644 --- a/les/helper_test.go +++ b/les/helper_test.go @@ -156,11 +156,11 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor } else { blockchain, _ := core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}) - chtIndexer := light.NewChtIndexer(db, light.CHTFrequencyServer, light.HelperTrieProcessConfirmations) + chtIndexer := light.NewChtIndexer(db, params.CHTFrequencyServer, params.HelperTrieProcessConfirmations) chtIndexer.Start(blockchain) bbtIndexer := light.NewBloomTrieIndexer(db, params.BloomBitsBlocks, params.BloomConfirms, - light.BloomTrieFrequency, light.HelperTrieProcessConfirmations) + params.BloomTrieFrequency, params.HelperTrieProcessConfirmations) bloomIndexer := eth.NewBloomIndexer(db, params.BloomBitsBlocks, params.BloomConfirms) bloomIndexer.AddChildIndexer(bbtIndexer) diff --git a/les/odr_requests.go b/les/odr_requests.go index 075fcd92ca..70b57399ca 100644 --- a/les/odr_requests.go +++ b/les/odr_requests.go @@ -365,7 +365,7 @@ func (r *ChtRequest) CanSend(peer *peer) bool { peer.lock.RLock() defer peer.lock.RUnlock() - return peer.headInfo.Number >= light.HelperTrieConfirmations && r.ChtNum <= (peer.headInfo.Number-light.HelperTrieConfirmations)/light.CHTFrequencyClient + return peer.headInfo.Number >= r.Confirms && r.ChtNum <= (peer.headInfo.Number-r.Confirms)/r.SectionSize } // Request sends an ODR request to the LES network (implementation of LesOdrRequest) @@ -484,7 +484,7 @@ func (r *BloomRequest) CanSend(peer *peer) bool { if peer.version < lpv2 { return false } - return peer.headInfo.Number >= light.HelperTrieConfirmations && r.BloomTrieNum <= (peer.headInfo.Number-light.HelperTrieConfirmations)/light.BloomTrieFrequency + return peer.headInfo.Number >= r.Confirms && r.BloomTrieNum <= (peer.headInfo.Number-r.Confirms)/r.SectionSize } // Request sends an ODR request to the LES network (implementation of LesOdrRequest) diff --git a/les/odr_test.go b/les/odr_test.go index 2e99fb711d..ef0b8ae43f 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -167,9 +167,9 @@ func testOdr(t *testing.T, protocol int, expFail uint64, fn odrTestFn) { rm := newRetrieveManager(peers, dist, nil) db := ethdb.NewMemDatabase() ldb := ethdb.NewMemDatabase() - odr := NewLesOdr(ldb, light.NewChtIndexer(db, light.CHTFrequencyClient, light.HelperTrieConfirmations), - light.NewBloomTrieIndexer(db, light.BloomTrieFrequency, params.BloomConfirms, light.BloomTrieFrequency, light.HelperTrieConfirmations), - eth.NewBloomIndexer(db, light.BloomTrieFrequency, params.BloomConfirms), rm) + odr := NewLesOdr(ldb, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations), + light.NewBloomTrieIndexer(db, params.BloomTrieFrequency, params.BloomConfirms, params.BloomTrieFrequency, params.HelperTrieConfirmations), + eth.NewBloomIndexer(db, params.BloomTrieFrequency, params.BloomConfirms), rm) pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db) lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb) _, err1, lpeer, err2 := newTestPeerPair("peer", protocol, pm, lpm) diff --git a/les/peer.go b/les/peer.go index eb7452e276..76afa25a45 100644 --- a/les/peer.go +++ b/les/peer.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/les/flowcontrol" "github.com/ethereum/go-ethereum/light" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" ) @@ -295,7 +296,8 @@ func (p *peer) RequestHelperTrieProofs(reqID, cost uint64, reqs []HelperTrieReq) } blockNum := binary.BigEndian.Uint64(req.Key) // convert HelperTrie request to old CHT request - reqsV1[i] = ChtReq{ChtNum: (req.TrieIdx + 1) * (light.CHTFrequencyClient / light.CHTFrequencyServer), BlockNum: blockNum, FromLevel: req.FromLevel} + reqsV1[i] = ChtReq{ChtNum: (req.TrieIdx + 1) * (params.CHTFrequencyClient / params.CHTFrequencyServer), BlockNum: blockNum, FromLevel: req.FromLevel} + } return sendRequest(p.rw, GetHeaderProofsMsg, reqID, cost, reqsV1) case lpv2: diff --git a/les/request_test.go b/les/request_test.go index b2295b14cf..59645a8302 100644 --- a/les/request_test.go +++ b/les/request_test.go @@ -90,9 +90,9 @@ func testAccess(t *testing.T, protocol int, fn accessTestFn) { rm := newRetrieveManager(peers, dist, nil) db := ethdb.NewMemDatabase() ldb := ethdb.NewMemDatabase() - odr := NewLesOdr(ldb, light.NewChtIndexer(db, light.CHTFrequencyClient, light.HelperTrieConfirmations), - light.NewBloomTrieIndexer(db, light.BloomTrieFrequency, params.BloomConfirms, light.BloomTrieFrequency, light.HelperTrieConfirmations), - eth.NewBloomIndexer(db, light.BloomTrieFrequency, params.BloomConfirms), rm) + odr := NewLesOdr(ldb, light.NewChtIndexer(db, params.CHTFrequencyClient, params.HelperTrieConfirmations), + light.NewBloomTrieIndexer(db, params.BloomTrieFrequency, params.BloomConfirms, params.BloomTrieFrequency, params.HelperTrieConfirmations), + eth.NewBloomIndexer(db, params.BloomTrieFrequency, params.BloomConfirms), rm) pm := newTestProtocolManagerMust(t, false, 4, testChainGen, nil, nil, db) lpm := newTestProtocolManagerMust(t, true, 0, nil, peers, odr, ldb) diff --git a/les/server.go b/les/server.go index 529d6da4a8..7e3ebc9d24 100644 --- a/les/server.go +++ b/les/server.go @@ -68,19 +68,19 @@ func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) { protocolManager: pm, quitSync: quitSync, lesTopics: lesTopics, - chtIndexer: light.NewChtIndexer(eth.ChainDb(), light.CHTFrequencyServer, light.HelperTrieProcessConfirmations), + chtIndexer: light.NewChtIndexer(eth.ChainDb(), params.CHTFrequencyServer, params.HelperTrieProcessConfirmations), bloomTrieIndexer: light.NewBloomTrieIndexer(eth.ChainDb(), params.BloomBitsBlocks, params.BloomConfirms, - light.BloomTrieFrequency, light.HelperTrieProcessConfirmations), + params.BloomTrieFrequency, params.HelperTrieProcessConfirmations), } logger := log.New() chtV1SectionCount, _, _ := srv.chtIndexer.Sections() // indexer still uses LES/1 4k section size for backwards server compatibility - chtV2SectionCount := chtV1SectionCount / (light.CHTFrequencyClient / light.CHTFrequencyServer) + chtV2SectionCount := chtV1SectionCount / (params.CHTFrequencyClient / params.CHTFrequencyServer) if chtV2SectionCount != 0 { // convert to LES/2 section chtLastSection := chtV2SectionCount - 1 // convert last LES/2 section index back to LES/1 index for chtIndexer.SectionHead - chtLastSectionV1 := (chtLastSection+1)*(light.CHTFrequencyClient/light.CHTFrequencyServer) - 1 + chtLastSectionV1 := (chtLastSection+1)*(params.CHTFrequencyClient/params.CHTFrequencyServer) - 1 chtSectionHead := srv.chtIndexer.SectionHead(chtLastSectionV1) chtRoot := light.GetChtRoot(pm.chainDb, chtLastSectionV1, chtSectionHead) logger.Info("Loaded CHT", "section", chtLastSection, "head", chtSectionHead, "root", chtRoot) diff --git a/light/lightchain.go b/light/lightchain.go index 30b9bd89a6..5a4ee62cb6 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -128,7 +128,7 @@ func (self *LightChain) addTrustedCheckpoint(cp trustedCheckpoint) { if self.odr.BloomIndexer() != nil { self.odr.BloomIndexer().AddKnownSectionHead(cp.sectionIdx, cp.sectionHead) } - log.Info("Added trusted checkpoint", "chain", cp.name, "block", (cp.sectionIdx+1)*CHTFrequencyClient-1, "hash", cp.sectionHead) + log.Info("Added trusted checkpoint", "chain", cp.name, "block", (cp.sectionIdx+1)*params.CHTFrequencyClient-1, "hash", cp.sectionHead) } func (self *LightChain) getProcInterrupt() bool { @@ -457,7 +457,7 @@ func (self *LightChain) GetHeaderByNumberOdr(ctx context.Context, number uint64) if header := self.hc.GetHeaderByNumber(number); header != nil { return header, nil } - return GetHeaderByNumber(ctx, self.odr, number) + return GetHeaderByNumber(ctx, params.CHTFrequencyClient, params.HelperTrieConfirmations, self.odr, number) } // Config retrieves the header chain's chain configuration. @@ -469,9 +469,9 @@ func (self *LightChain) SyncCht(ctx context.Context) bool { } headNum := self.CurrentHeader().Number.Uint64() chtCount, _, _ := self.odr.ChtIndexer().Sections() - if headNum+1 < chtCount*CHTFrequencyClient { - num := chtCount*CHTFrequencyClient - 1 - header, err := GetHeaderByNumber(ctx, self.odr, num) + if headNum+1 < chtCount*params.CHTFrequencyClient { + num := chtCount*params.CHTFrequencyClient - 1 + header, err := GetHeaderByNumber(ctx, params.CHTFrequencyClient, params.HelperTrieConfirmations, self.odr, num) if header != nil && err == nil { self.mu.Lock() if self.hc.CurrentHeader().Number.Uint64() < header.Number.Uint64() { diff --git a/light/odr.go b/light/odr.go index 8f1e50b817..164f4e29d3 100644 --- a/light/odr.go +++ b/light/odr.go @@ -132,6 +132,8 @@ func (req *ReceiptsRequest) StoreResult(db ethdb.Database) { // ChtRequest is the ODR request type for state/storage trie entries type ChtRequest struct { OdrRequest + SectionSize uint64 + Confirms uint64 ChtNum, BlockNum uint64 ChtRoot common.Hash Header *types.Header @@ -151,6 +153,8 @@ func (req *ChtRequest) StoreResult(db ethdb.Database) { // BloomRequest is the ODR request type for retrieving bloom filters from a CHT structure type BloomRequest struct { OdrRequest + SectionSize uint64 + Confirms uint64 BloomTrieNum uint64 BitIdx uint SectionIdxList []uint64 @@ -162,7 +166,7 @@ type BloomRequest struct { // StoreResult stores the retrieved data in local database func (req *BloomRequest) StoreResult(db ethdb.Database) { for i, sectionIdx := range req.SectionIdxList { - sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*BloomTrieFrequency-1) + sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*req.SectionSize-1) // 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 // hash. In the unlikely case we've retrieved the section head hash since then, we'll just retrieve the diff --git a/light/odr_util.go b/light/odr_util.go index 620af63835..9f87e217cb 100644 --- a/light/odr_util.go +++ b/light/odr_util.go @@ -25,12 +25,13 @@ import ( "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" ) var sha3_nil = crypto.Keccak256Hash(nil) -func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*types.Header, error) { +func GetHeaderByNumber(ctx context.Context, size uint64, confirms uint64, odr OdrBackend, number uint64) (*types.Header, error) { db := odr.Database() hash := rawdb.ReadCanonicalHash(db, number) if (hash != common.Hash{}) { @@ -53,16 +54,16 @@ func GetHeaderByNumber(ctx context.Context, odr OdrBackend, number uint64) (*typ for chtCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) { chtCount-- if chtCount > 0 { - sectionHeadNum = chtCount*CHTFrequencyClient - 1 + sectionHeadNum = chtCount*size - 1 sectionHead = odr.ChtIndexer().SectionHead(chtCount - 1) canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum) } } } - if number >= chtCount*CHTFrequencyClient { + if number >= chtCount*size { return nil, ErrNoTrustedCht } - r := &ChtRequest{ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: number} + r := &ChtRequest{SectionSize: size, Confirms: confirms, ChtRoot: GetChtRoot(db, chtCount-1, sectionHead), ChtNum: chtCount - 1, BlockNum: number} if err := odr.Retrieve(ctx, r); err != nil { return nil, err } @@ -74,7 +75,7 @@ func GetCanonicalHash(ctx context.Context, odr OdrBackend, number uint64) (commo if (hash != common.Hash{}) { return hash, nil } - header, err := GetHeaderByNumber(ctx, odr, number) + header, err := GetHeaderByNumber(ctx, params.CHTFrequencyClient, params.HelperTrieConfirmations, odr, number) if header != nil { return header.Hash(), nil } @@ -174,7 +175,7 @@ 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 -func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxList []uint64) ([][]byte, error) { +func GetBloomBits(ctx context.Context, size uint64, confirms uint64, odr OdrBackend, bitIdx uint, sectionIdxList []uint64) ([][]byte, error) { db := odr.Database() result := make([][]byte, len(sectionIdxList)) var ( @@ -193,7 +194,7 @@ func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxLi for bloomTrieCount > 0 && canonicalHash != sectionHead && canonicalHash != (common.Hash{}) { bloomTrieCount-- if bloomTrieCount > 0 { - sectionHeadNum = bloomTrieCount*BloomTrieFrequency - 1 + sectionHeadNum = bloomTrieCount*size - 1 sectionHead = odr.BloomTrieIndexer().SectionHead(bloomTrieCount - 1) canonicalHash = rawdb.ReadCanonicalHash(db, sectionHeadNum) } @@ -201,7 +202,7 @@ func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxLi } for i, sectionIdx := range sectionIdxList { - sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*BloomTrieFrequency-1) + sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*size-1) // 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 // at the time of the retrieval) @@ -220,7 +221,8 @@ func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxLi return result, nil } - r := &BloomRequest{BloomTrieRoot: GetBloomTrieRoot(db, bloomTrieCount-1, sectionHead), BloomTrieNum: bloomTrieCount - 1, BitIdx: bitIdx, SectionIdxList: reqList} + r := &BloomRequest{SectionSize: size, Confirms: confirms, BloomTrieRoot: GetBloomTrieRoot(db, bloomTrieCount-1, sectionHead), BloomTrieNum: bloomTrieCount - 1, + BitIdx: bitIdx, SectionIdxList: reqList} if err := odr.Retrieve(ctx, r); err != nil { return nil, err } else { diff --git a/light/postprocess.go b/light/postprocess.go index 9717571d6f..06546b6201 100644 --- a/light/postprocess.go +++ b/light/postprocess.go @@ -34,19 +34,6 @@ import ( "github.com/ethereum/go-ethereum/trie" ) -const ( - // CHTFrequencyClient is the block frequency for creating CHTs on the client side. - CHTFrequencyClient = 32768 - - // CHTFrequencyServer is the block frequency for creating CHTs on the server side. - // Eventually this can be merged back with the client version, but that requires a - // full database upgrade, so that should be left for a suitable moment. - CHTFrequencyServer = 4096 - - HelperTrieConfirmations = 2048 // number of confirmations before a server is expected to have the given HelperTrie available - HelperTrieProcessConfirmations = 256 // number of confirmations before a HelperTrie is generated -) - // 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 // and avoid downloading the entire header chain while still being able to securely access old headers/logs. @@ -95,7 +82,7 @@ type ChtNode struct { } // GetChtRoot reads the CHT root associated to the given section from the database -// Note that sectionIdx is specified according to LES/1 CHT section size +// Note that sectionIdx is specified according to LES/1 CHT section size. func GetChtRoot(db ethdb.Database, sectionIdx uint64, sectionHead common.Hash) common.Hash { var encNumber [8]byte binary.BigEndian.PutUint64(encNumber[:], sectionIdx) @@ -104,23 +91,24 @@ func GetChtRoot(db ethdb.Database, sectionIdx uint64, sectionHead common.Hash) c } // StoreChtRoot writes the CHT root associated to the given section into the database -// Note that sectionIdx is specified according to LES/1 CHT section size +// Note that sectionIdx is specified according to LES/1 CHT section size. func StoreChtRoot(db ethdb.Database, sectionIdx uint64, sectionHead, root common.Hash) { var encNumber [8]byte binary.BigEndian.PutUint64(encNumber[:], sectionIdx) db.Put(append(append(chtPrefix, encNumber[:]...), sectionHead.Bytes()...), root.Bytes()) } -// ChtIndexerBackend implements core.ChainIndexerBackend +// ChtIndexerBackend implements core.ChainIndexerBackend. type ChtIndexerBackend struct { - diskdb ethdb.Database - triedb *trie.Database - section, sectionSize uint64 - lastHash common.Hash - trie *trie.Trie + diskdb ethdb.Database + triedb *trie.Database + section uint64 + sectionSize uint64 + lastHash common.Hash + trie *trie.Trie } -// NewChtIndexer creates a Cht chain indexer +// NewChtIndexer creates a Cht chain indexer. func NewChtIndexer(db ethdb.Database, size, confirms uint64) *core.ChainIndexer { idb := ethdb.NewTable(db, "chtIndex-") backend := &ChtIndexerBackend{ @@ -131,7 +119,7 @@ func NewChtIndexer(db ethdb.Database, size, confirms uint64) *core.ChainIndexer return core.NewChainIndexer(db, idb, backend, size, confirms, time.Millisecond*100, "cht") } -// Reset implements core.ChainIndexerBackend +// Reset implements core.ChainIndexerBackend. func (c *ChtIndexerBackend) Reset(section uint64, lastSectionHead common.Hash) error { var root common.Hash if section > 0 { @@ -166,19 +154,13 @@ func (c *ChtIndexerBackend) Commit() error { } c.triedb.Commit(root, false) - if ((c.section+1)*c.sectionSize)%CHTFrequencyClient == 0 { - log.Info("Storing CHT", "section", c.section*c.sectionSize/CHTFrequencyClient, "head", c.lastHash, "root", root) + if ((c.section+1)*c.sectionSize)%params.CHTFrequencyClient == 0 { + log.Info("Storing CHT", "section", c.section*c.sectionSize/params.CHTFrequencyClient, "head", c.lastHash, "root", root) } StoreChtRoot(c.diskdb, c.section, c.lastHash, root) return nil } -const ( - BloomTrieFrequency = 32768 - ethBloomBitsSection = 4096 - ethBloomBitsConfirmations = 256 -) - var ( bloomTriePrefix = []byte("bltRoot-") // bloomTriePrefix + bloomTrieNum (uint64 big endian) -> trie root hash BloomTrieTablePrefix = "blt-" diff --git a/params/network_params.go b/params/network_params.go index f784cb3769..b74084600b 100644 --- a/params/network_params.go +++ b/params/network_params.go @@ -17,7 +17,7 @@ package params // These are network parameters that need to be constant between clients, but -// aren't necesarilly consensus related. +// aren't necessary consensus related. const ( // BloomBitsBlocks is the number of blocks a single bloom bit section vector @@ -27,4 +27,24 @@ const ( // BloomConfirms is the number of confirmation blocks before a bloom section is // considered probably final and its rotated bits are calculated. BloomConfirms = 256 + + // CHTFrequencyClient is the block frequency for creating CHTs on the client side. + CHTFrequencyClient = 32768 + + // CHTFrequencyServer is the block frequency for creating CHTs on the server side. + // Eventually this can be merged back with the client version, but that requires a + // full database upgrade, so that should be left for a suitable moment. + CHTFrequencyServer = 4096 + + // BloomTrieFrequency is the block frequency for creating BloomTrie on both + // server/client sides. + BloomTrieFrequency = 32768 + + // HelperTrieConfirmations is the number of confirmations before a server is expected + // to have the given HelperTrie available. + HelperTrieConfirmations = 2048 + + // HelperTrieProcessConfirmations is the number of confirmations before a HelperTrie + // is generated + HelperTrieProcessConfirmations = 256 )