93 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			93 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|   | // Copyright 2021 The go-ethereum Authors | ||
|  | // This file is part of the go-ethereum library. | ||
|  | // | ||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||
|  | // the Free Software Foundation, either version 3 of the License, or | ||
|  | // (at your option) any later version. | ||
|  | // | ||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
|  | // GNU Lesser General Public License for more details. | ||
|  | // | ||
|  | // You should have received a copy of the GNU Lesser General Public License | ||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||
|  | 
 | ||
|  | package core | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"context" | ||
|  | 	"time" | ||
|  | 
 | ||
|  | 	"github.com/ethereum/go-ethereum/common" | ||
|  | 	"github.com/ethereum/go-ethereum/common/bitutil" | ||
|  | 	"github.com/ethereum/go-ethereum/core/bloombits" | ||
|  | 	"github.com/ethereum/go-ethereum/core/rawdb" | ||
|  | 	"github.com/ethereum/go-ethereum/core/types" | ||
|  | 	"github.com/ethereum/go-ethereum/ethdb" | ||
|  | ) | ||
|  | 
 | ||
|  | 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 | ||
|  | ) | ||
|  | 
 | ||
|  | // BloomIndexer implements a core.ChainIndexer, building up a rotated bloom bits index | ||
|  | // for the Ethereum header bloom filters, permitting blazing fast filtering. | ||
|  | type BloomIndexer struct { | ||
|  | 	size    uint64               // section size to generate bloombits for | ||
|  | 	db      ethdb.Database       // database instance to write index data and metadata into | ||
|  | 	gen     *bloombits.Generator // generator to rotate the bloom bits crating the bloom index | ||
|  | 	section uint64               // Section is the section number being processed currently | ||
|  | 	head    common.Hash          // Head is the hash of the last header processed | ||
|  | } | ||
|  | 
 | ||
|  | // NewBloomIndexer returns a chain indexer that generates bloom bits data for the | ||
|  | // canonical chain for fast logs filtering. | ||
|  | func NewBloomIndexer(db ethdb.Database, size, confirms uint64) *ChainIndexer { | ||
|  | 	backend := &BloomIndexer{ | ||
|  | 		db:   db, | ||
|  | 		size: size, | ||
|  | 	} | ||
|  | 	table := rawdb.NewTable(db, string(rawdb.BloomBitsIndexPrefix)) | ||
|  | 
 | ||
|  | 	return NewChainIndexer(db, table, backend, size, confirms, bloomThrottling, "bloombits") | ||
|  | } | ||
|  | 
 | ||
|  | // Reset implements core.ChainIndexerBackend, starting a new bloombits index | ||
|  | // section. | ||
|  | func (b *BloomIndexer) Reset(ctx context.Context, section uint64, lastSectionHead common.Hash) error { | ||
|  | 	gen, err := bloombits.NewGenerator(uint(b.size)) | ||
|  | 	b.gen, b.section, b.head = gen, section, common.Hash{} | ||
|  | 	return err | ||
|  | } | ||
|  | 
 | ||
|  | // Process implements core.ChainIndexerBackend, adding a new header's bloom into | ||
|  | // the index. | ||
|  | func (b *BloomIndexer) Process(ctx context.Context, header *types.Header) error { | ||
|  | 	b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), header.Bloom) | ||
|  | 	b.head = header.Hash() | ||
|  | 	return nil | ||
|  | } | ||
|  | 
 | ||
|  | // Commit implements core.ChainIndexerBackend, finalizing the bloom section and | ||
|  | // writing it out into the database. | ||
|  | func (b *BloomIndexer) Commit() error { | ||
|  | 	batch := b.db.NewBatch() | ||
|  | 	for i := 0; i < types.BloomBitLength; i++ { | ||
|  | 		bits, err := b.gen.Bitset(uint(i)) | ||
|  | 		if err != nil { | ||
|  | 			return err | ||
|  | 		} | ||
|  | 		rawdb.WriteBloomBits(batch, uint(i), b.section, b.head, bitutil.CompressBytes(bits)) | ||
|  | 	} | ||
|  | 	return batch.Write() | ||
|  | } | ||
|  | 
 | ||
|  | // Prune returns an empty error since we don't support pruning here. | ||
|  | func (b *BloomIndexer) Prune(threshold uint64) error { | ||
|  | 	return nil | ||
|  | } |