github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/neatptc/bloombits.go (about) 1 package neatptc 2 3 import ( 4 "time" 5 6 "github.com/neatlab/neatio/chain/core" 7 "github.com/neatlab/neatio/chain/core/bloombits" 8 "github.com/neatlab/neatio/chain/core/rawdb" 9 "github.com/neatlab/neatio/chain/core/types" 10 "github.com/neatlab/neatio/neatdb" 11 "github.com/neatlab/neatio/params" 12 "github.com/neatlab/neatio/utilities/common" 13 "github.com/neatlab/neatio/utilities/common/bitutil" 14 ) 15 16 const ( 17 bloomServiceThreads = 16 18 19 bloomFilterThreads = 3 20 21 bloomRetrievalBatch = 16 22 23 bloomRetrievalWait = time.Duration(0) 24 ) 25 26 func (neatChain *NeatIO) startBloomHandlers() { 27 for i := 0; i < bloomServiceThreads; i++ { 28 go func() { 29 for { 30 select { 31 case <-neatChain.shutdownChan: 32 return 33 34 case request := <-neatChain.bloomRequests: 35 task := <-request 36 task.Bitsets = make([][]byte, len(task.Sections)) 37 for i, section := range task.Sections { 38 head := rawdb.ReadCanonicalHash(neatChain.chainDb, (section+1)*params.BloomBitsBlocks-1) 39 if compVector, err := rawdb.ReadBloomBits(neatChain.chainDb, task.Bit, section, head); err == nil { 40 if blob, err := bitutil.DecompressBytes(compVector, int(params.BloomBitsBlocks)/8); err == nil { 41 task.Bitsets[i] = blob 42 } else { 43 task.Error = err 44 } 45 } else { 46 task.Error = err 47 } 48 } 49 request <- task 50 } 51 } 52 }() 53 } 54 } 55 56 const ( 57 bloomConfirms = 256 58 59 bloomThrottling = 100 * time.Millisecond 60 ) 61 62 type BloomIndexer struct { 63 size uint64 64 65 db neatdb.Database 66 gen *bloombits.Generator 67 68 section uint64 69 head common.Hash 70 } 71 72 func NewBloomIndexer(db neatdb.Database, size uint64) *core.ChainIndexer { 73 backend := &BloomIndexer{ 74 db: db, 75 size: size, 76 } 77 table := rawdb.NewTable(db, string(rawdb.BloomBitsIndexPrefix)) 78 79 return core.NewChainIndexer(db, table, backend, size, bloomConfirms, bloomThrottling, "bloombits") 80 } 81 82 func (b *BloomIndexer) Reset(section uint64, lastSectionHead common.Hash) error { 83 gen, err := bloombits.NewGenerator(uint(b.size)) 84 b.gen, b.section, b.head = gen, section, common.Hash{} 85 return err 86 } 87 88 func (b *BloomIndexer) Process(header *types.Header) { 89 b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), header.Bloom) 90 b.head = header.Hash() 91 } 92 93 func (b *BloomIndexer) Commit() error { 94 batch := b.db.NewBatch() 95 for i := 0; i < types.BloomBitLength; i++ { 96 bits, err := b.gen.Bitset(uint(i)) 97 if err != nil { 98 return err 99 } 100 rawdb.WriteBloomBits(batch, uint(i), b.section, b.head, bitutil.CompressBytes(bits)) 101 } 102 return batch.Write() 103 }