github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/eth/bloombits.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package eth 26 27 import ( 28 "context" 29 "time" 30 31 "github.com/ethereum/go-ethereum/common" 32 "github.com/ethereum/go-ethereum/common/bitutil" 33 "github.com/ethereum/go-ethereum/core" 34 "github.com/ethereum/go-ethereum/core/bloombits" 35 "github.com/ethereum/go-ethereum/core/rawdb" 36 "github.com/ethereum/go-ethereum/core/types" 37 "github.com/ethereum/go-ethereum/ethdb" 38 "github.com/ethereum/go-ethereum/params" 39 ) 40 41 const ( 42 //BloomServiceThreads是以太坊全局使用的Goroutine数。 43 //实例到服务BloomBits查找所有正在运行的筛选器。 44 bloomServiceThreads = 16 45 46 //BloomFilterThreads是每个筛选器本地使用的goroutine数,用于 47 //将请求多路传输到全局服务goroutine。 48 bloomFilterThreads = 3 49 50 //BloomRetrievalBatch是要服务的最大Bloom位检索数。 51 //一批。 52 bloomRetrievalBatch = 16 53 54 //BloomRetrievalWait是等待足够的Bloom位请求的最长时间。 55 //累积请求整个批(避免滞后)。 56 bloomRetrievalWait = time.Duration(0) 57 ) 58 59 //StartBloomHandlers启动一批Goroutine以接受BloomBit数据库 60 //从可能的一系列过滤器中检索并为数据提供满足条件的服务。 61 func (eth *Ethereum) startBloomHandlers() { 62 for i := 0; i < bloomServiceThreads; i++ { 63 go func() { 64 for { 65 select { 66 case <-eth.shutdownChan: 67 return 68 69 case request := <-eth.bloomRequests: 70 task := <-request 71 task.Bitsets = make([][]byte, len(task.Sections)) 72 for i, section := range task.Sections { 73 head := rawdb.ReadCanonicalHash(eth.chainDb, (section+1)*params.BloomBitsBlocks-1) 74 if compVector, err := rawdb.ReadBloomBits(eth.chainDb, task.Bit, section, head); err == nil { 75 if blob, err := bitutil.DecompressBytes(compVector, int(params.BloomBitsBlocks)/8); err == nil { 76 task.Bitsets[i] = blob 77 } else { 78 task.Error = err 79 } 80 } else { 81 task.Error = err 82 } 83 } 84 request <- task 85 } 86 } 87 }() 88 } 89 } 90 91 const ( 92 //BloomConfirms是在Bloom部分 93 //considered probably final and its rotated bits are calculated. 94 bloomConfirms = 256 95 96 //BloomThrottling是处理两个连续索引之间的等待时间。 97 //部分。它在链升级期间很有用,可以防止磁盘过载。 98 bloomThrottling = 100 * time.Millisecond 99 ) 100 101 //BloomIndexer实现core.chainIndexer,建立旋转的BloomBits索引 102 //对于以太坊头段Bloom过滤器,允许快速过滤。 103 type BloomIndexer struct { 104 size uint64 //要为其生成bloombits的节大小 105 db ethdb.Database //要将索引数据和元数据写入的数据库实例 106 gen *bloombits.Generator //发电机旋转盛开钻头,装入盛开指数 107 section uint64 //节是当前正在处理的节号 108 head common.Hash //head是最后处理的头的哈希值 109 } 110 111 //newbloomindexer返回一个链索引器,它为 112 //用于快速日志筛选的规范链。 113 func NewBloomIndexer(db ethdb.Database, size, confReq uint64) *core.ChainIndexer { 114 backend := &BloomIndexer{ 115 db: db, 116 size: size, 117 } 118 table := ethdb.NewTable(db, string(rawdb.BloomBitsIndexPrefix)) 119 120 return core.NewChainIndexer(db, table, backend, size, confReq, bloomThrottling, "bloombits") 121 } 122 123 //reset实现core.chainindexerbackend,启动新的bloombits索引 124 //部分。 125 func (b *BloomIndexer) Reset(ctx context.Context, section uint64, lastSectionHead common.Hash) error { 126 gen, err := bloombits.NewGenerator(uint(b.size)) 127 b.gen, b.section, b.head = gen, section, common.Hash{} 128 return err 129 } 130 131 //进程实现了core.chainindexerbackend,将新头的bloom添加到 132 //索引。 133 func (b *BloomIndexer) Process(ctx context.Context, header *types.Header) error { 134 b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), header.Bloom) 135 b.head = header.Hash() 136 return nil 137 } 138 139 //commit实现core.chainindexerbackend,完成bloom部分和 140 //把它写进数据库。 141 func (b *BloomIndexer) Commit() error { 142 batch := b.db.NewBatch() 143 for i := 0; i < types.BloomBitLength; i++ { 144 bits, err := b.gen.Bitset(uint(i)) 145 if err != nil { 146 return err 147 } 148 rawdb.WriteBloomBits(batch, uint(i), b.section, b.head, bitutil.CompressBytes(bits)) 149 } 150 return batch.Write() 151 }