forked from ethereum/go-ethereum
-
Notifications
You must be signed in to change notification settings - Fork 9
feat: allow custom bloom production #261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
6cccdf2
feat: Allow custom bloom production
alarso16 34e0e87
chore: license header
alarso16 5bf0ed3
feat: Add more bloom index interceptors
alarso16 249ad53
chore: license header fix
alarso16 9efd7e6
chore: docs and lint
alarso16 c3d9f41
feat: export some constants
alarso16 2b537d3
style: rename everything
alarso16 dea2e30
feat: Add custom bloom indexer service
alarso16 1169461
test: Ensure bloom override works
alarso16 8b90483
chore: comments
alarso16 b2baaf9
refactor: `NewBloomIndexerService()`
ARR4N 48b01d5
feat: `eth.BloomHandlers` with cleanup
ARR4N 2e22758
refactor!: remove `filters.BloomIndexerService` to place in SAE inste…
ARR4N 187c128
test: Ensure bloom overrider is called
alarso16 a64a286
chore: remove barely unnecessary change
alarso16 4c97664
chore: oops
alarso16 6d2eb68
chore: reduce diff
alarso16 e380f22
test: non-intrusive testing of Bloom overriding
ARR4N 2600174
refactor: revert `ethereum` aliasing
ARR4N File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // Copyright 2026 the libevm authors. | ||
| // | ||
| // The libevm additions to go-ethereum are free software: you can redistribute | ||
| // them and/or modify them 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 libevm additions are distributed in the hope that they 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 ( | ||
| "github.com/ava-labs/libevm/core/types" | ||
| "github.com/ava-labs/libevm/ethdb" | ||
| ) | ||
|
|
||
| // BloomThrottling is the time to wait between processing two consecutive index sections. | ||
| const BloomThrottling = bloomThrottling | ||
|
|
||
| // NewBloomIndexerBackend creates a [BloomIndexer] instance for the given database and section size, | ||
| // allowing users to provide custom functionality to the bloom indexer. | ||
| func NewBloomIndexerBackend(db ethdb.Database, size uint64) *BloomIndexer { | ||
alarso16 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return &BloomIndexer{ | ||
| db: db, | ||
| size: size, | ||
| } | ||
| } | ||
|
|
||
| // ProcessWithBloomOverride is the same as [BloomIndexer.Process], but takes the header and bloom separately. | ||
| // This must obey the same invariates as [BloomIndexer.Process], including calling [BloomIndexer.Reset] | ||
| // to start a new section prior to this call, otherwise this function will panic. | ||
| func (b *BloomIndexer) ProcessWithBloomOverride(header *types.Header, bloom types.Bloom) error { | ||
alarso16 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| index := uint(header.Number.Uint64() - b.section*b.size) | ||
| if err := b.gen.AddBloom(index, bloom); err != nil { | ||
alarso16 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return err | ||
| } | ||
| b.head = header.Hash() | ||
| return nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| // Copyright 2026 the libevm authors. | ||
| // | ||
| // The libevm additions to go-ethereum are free software: you can redistribute | ||
| // them and/or modify them 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 libevm additions are distributed in the hope that they 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 eth | ||
|
|
||
| import ( | ||
| "github.com/ava-labs/libevm/core/bloombits" | ||
| "github.com/ava-labs/libevm/ethdb" | ||
| ) | ||
|
|
||
| const ( | ||
| // BloomFilterThreads is the number of goroutines used locally per filter to | ||
| // multiplex requests onto the global servicing goroutines. | ||
| BloomFilterThreads = bloomFilterThreads | ||
|
|
||
| // BloomRetrievalBatch is the maximum number of bloom bit retrievals to | ||
| // service in a single batch. | ||
| BloomRetrievalBatch = bloomRetrievalBatch | ||
|
|
||
| // BloomRetrievalWait is the maximum time to wait for enough bloom bit | ||
| // requests to accumulate request an entire batch (avoiding hysteresis). | ||
| BloomRetrievalWait = bloomRetrievalWait | ||
| ) | ||
|
|
||
| // StartBloomHandlers starts a batch of goroutines to serve data for | ||
| // [bloombits.Retrieval] requests from any number of filters. This is identical | ||
| // to [Ethereum.startBloomHandlers], but exposed for independent use. | ||
| func StartBloomHandlers(db ethdb.Database, sectionSize uint64) *BloomHandlers { | ||
| bh := &BloomHandlers{ | ||
| Requests: make(chan chan *bloombits.Retrieval), | ||
| quit: make(chan struct{}), | ||
| } | ||
| eth := &Ethereum{ | ||
| bloomRequests: bh.Requests, | ||
| closeBloomHandler: bh.quit, | ||
| chainDb: db, | ||
| } | ||
| eth.startBloomHandlers(sectionSize) | ||
| return bh | ||
| } | ||
|
|
||
| // BloomHandlers serve data for [bloombits.Retrieval] requests from any number | ||
| // of filters. [BloomHandlers.Close] MUST be called to release goroutines, after | ||
| // which a send on the requests channel will block indefinitely. | ||
| type BloomHandlers struct { | ||
| Requests chan chan *bloombits.Retrieval | ||
| quit chan struct{} | ||
| } | ||
|
|
||
| // Close releases resources in use by the [BloomHandlers]; repeated calls will | ||
| // panic. | ||
| func (bh *BloomHandlers) Close() { | ||
| close(bh.quit) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // Copyright 2026 the libevm authors. | ||
| // | ||
| // The libevm additions to go-ethereum are free software: you can redistribute | ||
| // them and/or modify them 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 libevm additions are distributed in the hope that they 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 eth | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "go.uber.org/goleak" | ||
|
|
||
| "github.com/ava-labs/libevm/core/rawdb" | ||
| ) | ||
|
|
||
| func TestStartBloomHandlersNoLeaks(t *testing.T) { | ||
| defer goleak.VerifyNone(t, goleak.IgnoreCurrent()) | ||
alarso16 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| StartBloomHandlers(rawdb.NewMemoryDatabase(), 42).Close() | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // Copyright 2026 the libevm authors. | ||
| // | ||
| // The libevm additions to go-ethereum are free software: you can redistribute | ||
| // them and/or modify them 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 libevm additions are distributed in the hope that they 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 filters | ||
|
|
||
| import ( | ||
| "github.com/ava-labs/libevm/core/types" | ||
| ) | ||
|
|
||
| // BloomOverrider is an optional extension to [Backend], allowing arbitrary | ||
| // bloom filters to be returned for a header. If not implemented, | ||
| // [types.Header.Bloom] is used instead. | ||
| type BloomOverrider interface { | ||
| OverrideHeaderBloom(*types.Header) types.Bloom | ||
| } | ||
|
|
||
| func maybeOverrideBloom(header *types.Header, backend Backend) types.Bloom { | ||
| if bo, ok := backend.(BloomOverrider); ok { | ||
| return bo.OverrideHeaderBloom(header) | ||
| } | ||
| return header.Bloom | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| // Copyright 2026 the libevm authors. | ||
| // | ||
| // The libevm additions to go-ethereum are free software: you can redistribute | ||
| // them and/or modify them 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 libevm additions are distributed in the hope that they 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 filters | ||
|
|
||
| import ( | ||
| "math/big" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/require" | ||
|
|
||
| "github.com/ava-labs/libevm/core" | ||
| "github.com/ava-labs/libevm/core/rawdb" | ||
| "github.com/ava-labs/libevm/core/types" | ||
| "github.com/ava-labs/libevm/rpc" | ||
| ) | ||
|
|
||
| type bloomOverriderBackend struct { | ||
| *testBackend | ||
| overridden chan struct{} | ||
| } | ||
|
|
||
| var _ BloomOverrider = (*bloomOverriderBackend)(nil) | ||
|
|
||
| func (b *bloomOverriderBackend) OverrideHeaderBloom(header *types.Header) types.Bloom { | ||
| b.overridden <- struct{}{} | ||
| return header.Bloom | ||
| } | ||
|
|
||
| func TestBloomOverride(t *testing.T) { | ||
| db := rawdb.NewMemoryDatabase() | ||
| backend, sys := newTestFilterSystem(t, db, Config{}) | ||
| sut := &bloomOverriderBackend{ | ||
| testBackend: backend, | ||
| overridden: make(chan struct{}), | ||
| } | ||
| sys.backend = sut | ||
|
|
||
| t.Run("lightFilterLogs", func(t *testing.T) { | ||
| api := NewFilterAPI(sys, true /*lightMode*/) | ||
| defer CloseAPI(api) | ||
|
|
||
| id, err := api.NewFilter(FilterCriteria{}) | ||
| require.NoErrorf(t, err, "%T.NewFilter()", api) | ||
| defer api.UninstallFilter(id) | ||
|
|
||
| // If there is no historical header then the filter system returns early. | ||
| for i := range int64(2) { | ||
| sut.chainFeed.Send(core.ChainEvent{ | ||
| Block: types.NewBlockWithHeader(&types.Header{ | ||
| Number: big.NewInt(i), | ||
| }), | ||
| }) | ||
| } | ||
| <-sut.overridden | ||
| }) | ||
|
|
||
| t.Run("blockLogs", func(t *testing.T) { | ||
| hdr := &types.Header{Number: big.NewInt(0)} | ||
| h := hdr.Hash() | ||
| rawdb.WriteHeader(db, hdr) | ||
| rawdb.WriteCanonicalHash(db, h, 0) | ||
| rawdb.WriteHeaderNumber(db, h, 0) | ||
|
|
||
| go sys.NewBlockFilter(h, nil, nil).Logs(t.Context()) //nolint:errcheck // Known but irrelevant error | ||
| <-sut.overridden | ||
| }) | ||
|
|
||
| t.Run("pendingLogs", func(t *testing.T) { | ||
| hdr := &types.Header{Number: big.NewInt(1)} | ||
| sut.pendingBlock = types.NewBlockWithHeader(hdr) | ||
| sut.pendingReceipts = types.Receipts{} | ||
|
|
||
| n := rpc.PendingBlockNumber.Int64() | ||
| go sys.NewRangeFilter(n, n, nil, nil).Logs(t.Context()) //nolint:errcheck // Known but irrelevant error | ||
| <-sut.overridden | ||
| }) | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.