diff --git a/core/bloom_indexer.go b/core/bloom_indexer.go
index 8a3687e720..d68cbebf0b 100644
--- a/core/bloom_indexer.go
+++ b/core/bloom_indexer.go
@@ -33,10 +33,10 @@ import (
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/common/bitutil"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/rawdb"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/ethdb"
- "github.com/ava-labs/subnet-evm/core/bloombits"
)
const (
diff --git a/core/bloombits/doc.go b/core/bloombits/doc.go
deleted file mode 100644
index b6d66e1fa0..0000000000
--- a/core/bloombits/doc.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-//
-// This file is a derived work, based on the go-ethereum library whose original
-// notices appear below.
-//
-// It is distributed under a license compatible with the licensing terms of the
-// original code from which it is derived.
-//
-// Much love to the original authors for their work.
-// **********
-// Copyright 2017 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 .
-
-// Package bloombits implements bloom filtering on batches of data.
-package bloombits
diff --git a/core/bloombits/generator.go b/core/bloombits/generator.go
deleted file mode 100644
index ea17e949b9..0000000000
--- a/core/bloombits/generator.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-//
-// This file is a derived work, based on the go-ethereum library whose original
-// notices appear below.
-//
-// It is distributed under a license compatible with the licensing terms of the
-// original code from which it is derived.
-//
-// Much love to the original authors for their work.
-// **********
-// Copyright 2017 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 .
-
-package bloombits
-
-import (
- "errors"
-
- "github.com/ava-labs/libevm/core/types"
-)
-
-var (
- // errSectionOutOfBounds is returned if the user tried to add more bloom filters
- // to the batch than available space, or if tries to retrieve above the capacity.
- errSectionOutOfBounds = errors.New("section out of bounds")
-
- // errBloomBitOutOfBounds is returned if the user tried to retrieve specified
- // bit bloom above the capacity.
- errBloomBitOutOfBounds = errors.New("bloom bit out of bounds")
-)
-
-// Generator takes a number of bloom filters and generates the rotated bloom bits
-// to be used for batched filtering.
-type Generator struct {
- blooms [types.BloomBitLength][]byte // Rotated blooms for per-bit matching
- sections uint // Number of sections to batch together
- nextSec uint // Next section to set when adding a bloom
-}
-
-// NewGenerator creates a rotated bloom generator that can iteratively fill a
-// batched bloom filter's bits.
-func NewGenerator(sections uint) (*Generator, error) {
- if sections%8 != 0 {
- return nil, errors.New("section count not multiple of 8")
- }
- b := &Generator{sections: sections}
- for i := 0; i < types.BloomBitLength; i++ {
- b.blooms[i] = make([]byte, sections/8)
- }
- return b, nil
-}
-
-// AddBloom takes a single bloom filter and sets the corresponding bit column
-// in memory accordingly.
-func (b *Generator) AddBloom(index uint, bloom types.Bloom) error {
- // Make sure we're not adding more bloom filters than our capacity
- if b.nextSec >= b.sections {
- return errSectionOutOfBounds
- }
- if b.nextSec != index {
- return errors.New("bloom filter with unexpected index")
- }
- // Rotate the bloom and insert into our collection
- byteIndex := b.nextSec / 8
- bitIndex := byte(7 - b.nextSec%8)
- for byt := 0; byt < types.BloomByteLength; byt++ {
- bloomByte := bloom[types.BloomByteLength-1-byt]
- if bloomByte == 0 {
- continue
- }
- base := 8 * byt
- b.blooms[base+7][byteIndex] |= ((bloomByte >> 7) & 1) << bitIndex
- b.blooms[base+6][byteIndex] |= ((bloomByte >> 6) & 1) << bitIndex
- b.blooms[base+5][byteIndex] |= ((bloomByte >> 5) & 1) << bitIndex
- b.blooms[base+4][byteIndex] |= ((bloomByte >> 4) & 1) << bitIndex
- b.blooms[base+3][byteIndex] |= ((bloomByte >> 3) & 1) << bitIndex
- b.blooms[base+2][byteIndex] |= ((bloomByte >> 2) & 1) << bitIndex
- b.blooms[base+1][byteIndex] |= ((bloomByte >> 1) & 1) << bitIndex
- b.blooms[base][byteIndex] |= (bloomByte & 1) << bitIndex
- }
- b.nextSec++
- return nil
-}
-
-// Bitset returns the bit vector belonging to the given bit index after all
-// blooms have been added.
-func (b *Generator) Bitset(idx uint) ([]byte, error) {
- if b.nextSec != b.sections {
- return nil, errors.New("bloom not fully generated yet")
- }
- if idx >= types.BloomBitLength {
- return nil, errBloomBitOutOfBounds
- }
- return b.blooms[idx], nil
-}
diff --git a/core/bloombits/generator_test.go b/core/bloombits/generator_test.go
deleted file mode 100644
index ae40567b95..0000000000
--- a/core/bloombits/generator_test.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-//
-// This file is a derived work, based on the go-ethereum library whose original
-// notices appear below.
-//
-// It is distributed under a license compatible with the licensing terms of the
-// original code from which it is derived.
-//
-// Much love to the original authors for their work.
-// **********
-// Copyright 2017 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 .
-
-package bloombits
-
-import (
- "bytes"
- crand "crypto/rand"
- "math/rand"
- "testing"
-
- "github.com/ava-labs/libevm/core/types"
-)
-
-// Tests that batched bloom bits are correctly rotated from the input bloom
-// filters.
-func TestGenerator(t *testing.T) {
- // Generate the input and the rotated output
- var input, output [types.BloomBitLength][types.BloomByteLength]byte
-
- for i := 0; i < types.BloomBitLength; i++ {
- for j := 0; j < types.BloomBitLength; j++ {
- bit := byte(rand.Int() % 2)
-
- input[i][j/8] |= bit << byte(7-j%8)
- output[types.BloomBitLength-1-j][i/8] |= bit << byte(7-i%8)
- }
- }
- // Crunch the input through the generator and verify the result
- gen, err := NewGenerator(types.BloomBitLength)
- if err != nil {
- t.Fatalf("failed to create bloombit generator: %v", err)
- }
- for i, bloom := range input {
- if err := gen.AddBloom(uint(i), bloom); err != nil {
- t.Fatalf("bloom %d: failed to add: %v", i, err)
- }
- }
- for i, want := range output {
- have, err := gen.Bitset(uint(i))
- if err != nil {
- t.Fatalf("output %d: failed to retrieve bits: %v", i, err)
- }
- if !bytes.Equal(have, want[:]) {
- t.Errorf("output %d: bit vector mismatch have %x, want %x", i, have, want)
- }
- }
-}
-
-func BenchmarkGenerator(b *testing.B) {
- var input [types.BloomBitLength][types.BloomByteLength]byte
- b.Run("empty", func(b *testing.B) {
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- // Crunch the input through the generator and verify the result
- gen, err := NewGenerator(types.BloomBitLength)
- if err != nil {
- b.Fatalf("failed to create bloombit generator: %v", err)
- }
- for j, bloom := range &input {
- if err := gen.AddBloom(uint(j), bloom); err != nil {
- b.Fatalf("bloom %d: failed to add: %v", i, err)
- }
- }
- }
- })
- for i := 0; i < types.BloomBitLength; i++ {
- crand.Read(input[i][:])
- }
- b.Run("random", func(b *testing.B) {
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- // Crunch the input through the generator and verify the result
- gen, err := NewGenerator(types.BloomBitLength)
- if err != nil {
- b.Fatalf("failed to create bloombit generator: %v", err)
- }
- for j, bloom := range &input {
- if err := gen.AddBloom(uint(j), bloom); err != nil {
- b.Fatalf("bloom %d: failed to add: %v", i, err)
- }
- }
- }
- })
-}
diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go
deleted file mode 100644
index 7b7d1299bd..0000000000
--- a/core/bloombits/matcher.go
+++ /dev/null
@@ -1,656 +0,0 @@
-// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-//
-// This file is a derived work, based on the go-ethereum library whose original
-// notices appear below.
-//
-// It is distributed under a license compatible with the licensing terms of the
-// original code from which it is derived.
-//
-// Much love to the original authors for their work.
-// **********
-// Copyright 2017 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 .
-
-package bloombits
-
-import (
- "bytes"
- "context"
- "errors"
- "math"
- "sort"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/ava-labs/libevm/common/bitutil"
- "github.com/ava-labs/libevm/crypto"
-)
-
-// bloomIndexes represents the bit indexes inside the bloom filter that belong
-// to some key.
-type bloomIndexes [3]uint
-
-// calcBloomIndexes returns the bloom filter bit indexes belonging to the given key.
-func calcBloomIndexes(b []byte) bloomIndexes {
- b = crypto.Keccak256(b)
-
- var idxs bloomIndexes
- for i := 0; i < len(idxs); i++ {
- idxs[i] = (uint(b[2*i])<<8)&2047 + uint(b[2*i+1])
- }
- return idxs
-}
-
-// partialMatches with a non-nil vector represents a section in which some sub-
-// matchers have already found potential matches. Subsequent sub-matchers will
-// binary AND their matches with this vector. If vector is nil, it represents a
-// section to be processed by the first sub-matcher.
-type partialMatches struct {
- section uint64
- bitset []byte
-}
-
-// Retrieval represents a request for retrieval task assignments for a given
-// bit with the given number of fetch elements, or a response for such a request.
-// It can also have the actual results set to be used as a delivery data struct.
-//
-// The context and error fields are used by the light client to terminate matching
-// early if an error is encountered on some path of the pipeline.
-type Retrieval struct {
- Bit uint
- Sections []uint64
- Bitsets [][]byte
-
- Context context.Context
- Error error
-}
-
-// Matcher is a pipelined system of schedulers and logic matchers which perform
-// binary AND/OR operations on the bit-streams, creating a stream of potential
-// blocks to inspect for data content.
-type Matcher struct {
- sectionSize uint64 // Size of the data batches to filter on
-
- filters [][]bloomIndexes // Filter the system is matching for
- schedulers map[uint]*scheduler // Retrieval schedulers for loading bloom bits
-
- retrievers chan chan uint // Retriever processes waiting for bit allocations
- counters chan chan uint // Retriever processes waiting for task count reports
- retrievals chan chan *Retrieval // Retriever processes waiting for task allocations
- deliveries chan *Retrieval // Retriever processes waiting for task response deliveries
-
- running atomic.Bool // Atomic flag whether a session is live or not
-}
-
-// NewMatcher creates a new pipeline for retrieving bloom bit streams and doing
-// address and topic filtering on them. Setting a filter component to `nil` is
-// allowed and will result in that filter rule being skipped (OR 0x11...1).
-func NewMatcher(sectionSize uint64, filters [][][]byte) *Matcher {
- // Create the matcher instance
- m := &Matcher{
- sectionSize: sectionSize,
- schedulers: make(map[uint]*scheduler),
- retrievers: make(chan chan uint),
- counters: make(chan chan uint),
- retrievals: make(chan chan *Retrieval),
- deliveries: make(chan *Retrieval),
- }
- // Calculate the bloom bit indexes for the groups we're interested in
- m.filters = nil
-
- for _, filter := range filters {
- // Gather the bit indexes of the filter rule, special casing the nil filter
- if len(filter) == 0 {
- continue
- }
- bloomBits := make([]bloomIndexes, len(filter))
- for i, clause := range filter {
- if clause == nil {
- bloomBits = nil
- break
- }
- bloomBits[i] = calcBloomIndexes(clause)
- }
- // Accumulate the filter rules if no nil rule was within
- if bloomBits != nil {
- m.filters = append(m.filters, bloomBits)
- }
- }
- // For every bit, create a scheduler to load/download the bit vectors
- for _, bloomIndexLists := range m.filters {
- for _, bloomIndexList := range bloomIndexLists {
- for _, bloomIndex := range bloomIndexList {
- m.addScheduler(bloomIndex)
- }
- }
- }
- return m
-}
-
-// addScheduler adds a bit stream retrieval scheduler for the given bit index if
-// it has not existed before. If the bit is already selected for filtering, the
-// existing scheduler can be used.
-func (m *Matcher) addScheduler(idx uint) {
- if _, ok := m.schedulers[idx]; ok {
- return
- }
- m.schedulers[idx] = newScheduler(idx)
-}
-
-// Start starts the matching process and returns a stream of bloom matches in
-// a given range of blocks. If there are no more matches in the range, the result
-// channel is closed.
-func (m *Matcher) Start(ctx context.Context, begin, end uint64, results chan uint64) (*MatcherSession, error) {
- // Make sure we're not creating concurrent sessions
- if m.running.Swap(true) {
- return nil, errors.New("matcher already running")
- }
- defer m.running.Store(false)
-
- // Initiate a new matching round
- session := &MatcherSession{
- matcher: m,
- quit: make(chan struct{}),
- ctx: ctx,
- }
- for _, scheduler := range m.schedulers {
- scheduler.reset()
- }
- sink := m.run(begin, end, cap(results), session)
-
- // Read the output from the result sink and deliver to the user
- session.pend.Add(1)
- go func() {
- defer session.pend.Done()
- defer close(results)
-
- for {
- select {
- case <-session.quit:
- return
-
- case res, ok := <-sink:
- // New match result found
- if !ok {
- return
- }
- // Calculate the first and last blocks of the section
- sectionStart := res.section * m.sectionSize
-
- first := sectionStart
- if begin > first {
- first = begin
- }
- last := sectionStart + m.sectionSize - 1
- if end < last {
- last = end
- }
- // Iterate over all the blocks in the section and return the matching ones
- for i := first; i <= last; i++ {
- // Skip the entire byte if no matches are found inside (and we're processing an entire byte!)
- next := res.bitset[(i-sectionStart)/8]
- if next == 0 {
- if i%8 == 0 {
- i += 7
- }
- continue
- }
- // Some bit it set, do the actual submatching
- if bit := 7 - i%8; next&(1<= req.section })
- requests[req.bit] = append(queue[:index], append([]uint64{req.section}, queue[index:]...)...)
-
- // If it's a new bit and we have waiting fetchers, allocate to them
- if len(queue) == 0 {
- assign(req.bit)
- }
-
- case fetcher := <-retrievers:
- // New retriever arrived, find the lowest section-ed bit to assign
- bit, best := uint(0), uint64(math.MaxUint64)
- for idx := range unallocs {
- if requests[idx][0] < best {
- bit, best = idx, requests[idx][0]
- }
- }
- // Stop tracking this bit (and alloc notifications if no more work is available)
- delete(unallocs, bit)
- if len(unallocs) == 0 {
- retrievers = nil
- }
- allocs++
- fetcher <- bit
-
- case fetcher := <-m.counters:
- // New task count request arrives, return number of items
- fetcher <- uint(len(requests[<-fetcher]))
-
- case fetcher := <-m.retrievals:
- // New fetcher waiting for tasks to retrieve, assign
- task := <-fetcher
- if want := len(task.Sections); want >= len(requests[task.Bit]) {
- task.Sections = requests[task.Bit]
- delete(requests, task.Bit)
- } else {
- task.Sections = append(task.Sections[:0], requests[task.Bit][:want]...)
- requests[task.Bit] = append(requests[task.Bit][:0], requests[task.Bit][want:]...)
- }
- fetcher <- task
-
- // If anything was left unallocated, try to assign to someone else
- if len(requests[task.Bit]) > 0 {
- assign(task.Bit)
- }
-
- case result := <-m.deliveries:
- // New retrieval task response from fetcher, split out missing sections and
- // deliver complete ones
- var (
- sections = make([]uint64, 0, len(result.Sections))
- bitsets = make([][]byte, 0, len(result.Bitsets))
- missing = make([]uint64, 0, len(result.Sections))
- )
- for i, bitset := range result.Bitsets {
- if len(bitset) == 0 {
- missing = append(missing, result.Sections[i])
- continue
- }
- sections = append(sections, result.Sections[i])
- bitsets = append(bitsets, bitset)
- }
- m.schedulers[result.Bit].deliver(sections, bitsets)
- allocs--
-
- // Reschedule missing sections and allocate bit if newly available
- if len(missing) > 0 {
- queue := requests[result.Bit]
- for _, section := range missing {
- index := sort.Search(len(queue), func(i int) bool { return queue[i] >= section })
- queue = append(queue[:index], append([]uint64{section}, queue[index:]...)...)
- }
- requests[result.Bit] = queue
-
- if len(queue) == len(missing) {
- assign(result.Bit)
- }
- }
-
- // End the session when all pending deliveries have arrived.
- if shutdown == nil && allocs == 0 {
- return
- }
- }
- }
-}
-
-// MatcherSession is returned by a started matcher to be used as a terminator
-// for the actively running matching operation.
-type MatcherSession struct {
- matcher *Matcher
-
- closer sync.Once // Sync object to ensure we only ever close once
- quit chan struct{} // Quit channel to request pipeline termination
-
- ctx context.Context // Context used by the light client to abort filtering
- err error // Global error to track retrieval failures deep in the chain
- errLock sync.Mutex
-
- pend sync.WaitGroup
-}
-
-// Close stops the matching process and waits for all subprocesses to terminate
-// before returning. The timeout may be used for graceful shutdown, allowing the
-// currently running retrievals to complete before this time.
-func (s *MatcherSession) Close() {
- s.closer.Do(func() {
- // Signal termination and wait for all goroutines to tear down
- close(s.quit)
- s.pend.Wait()
- })
-}
-
-// Error returns any failure encountered during the matching session.
-func (s *MatcherSession) Error() error {
- s.errLock.Lock()
- defer s.errLock.Unlock()
-
- return s.err
-}
-
-// allocateRetrieval assigns a bloom bit index to a client process that can either
-// immediately request and fetch the section contents assigned to this bit or wait
-// a little while for more sections to be requested.
-func (s *MatcherSession) allocateRetrieval() (uint, bool) {
- fetcher := make(chan uint)
-
- select {
- case <-s.quit:
- return 0, false
- case s.matcher.retrievers <- fetcher:
- bit, ok := <-fetcher
- return bit, ok
- }
-}
-
-// pendingSections returns the number of pending section retrievals belonging to
-// the given bloom bit index.
-func (s *MatcherSession) pendingSections(bit uint) int {
- fetcher := make(chan uint)
-
- select {
- case <-s.quit:
- return 0
- case s.matcher.counters <- fetcher:
- fetcher <- bit
- return int(<-fetcher)
- }
-}
-
-// allocateSections assigns all or part of an already allocated bit-task queue
-// to the requesting process.
-func (s *MatcherSession) allocateSections(bit uint, count int) []uint64 {
- fetcher := make(chan *Retrieval)
-
- select {
- case <-s.quit:
- return nil
- case s.matcher.retrievals <- fetcher:
- task := &Retrieval{
- Bit: bit,
- Sections: make([]uint64, count),
- }
- fetcher <- task
- return (<-fetcher).Sections
- }
-}
-
-// deliverSections delivers a batch of section bit-vectors for a specific bloom
-// bit index to be injected into the processing pipeline.
-func (s *MatcherSession) deliverSections(bit uint, sections []uint64, bitsets [][]byte) {
- s.matcher.deliveries <- &Retrieval{Bit: bit, Sections: sections, Bitsets: bitsets}
-}
-
-// Multiplex polls the matcher session for retrieval tasks and multiplexes it into
-// the requested retrieval queue to be serviced together with other sessions.
-//
-// This method will block for the lifetime of the session. Even after termination
-// of the session, any request in-flight need to be responded to! Empty responses
-// are fine though in that case.
-func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan *Retrieval) {
- for {
- // Allocate a new bloom bit index to retrieve data for, stopping when done
- bit, ok := s.allocateRetrieval()
- if !ok {
- return
- }
- // Bit allocated, throttle a bit if we're below our batch limit
- if s.pendingSections(bit) < batch {
- select {
- case <-s.quit:
- // Session terminating, we can't meaningfully service, abort
- s.allocateSections(bit, 0)
- s.deliverSections(bit, []uint64{}, [][]byte{})
- return
-
- case <-time.After(wait):
- // Throttling up, fetch whatever is available
- }
- }
- // Allocate as much as we can handle and request servicing
- sections := s.allocateSections(bit, batch)
- request := make(chan *Retrieval)
-
- select {
- case <-s.quit:
- // Session terminating, we can't meaningfully service, abort
- s.deliverSections(bit, sections, make([][]byte, len(sections)))
- return
-
- case mux <- request:
- // Retrieval accepted, something must arrive before we're aborting
- request <- &Retrieval{Bit: bit, Sections: sections, Context: s.ctx}
-
- result := <-request
-
- // Deliver a result before s.Close() to avoid a deadlock
- s.deliverSections(result.Bit, result.Sections, result.Bitsets)
-
- if result.Error != nil {
- s.errLock.Lock()
- s.err = result.Error
- s.errLock.Unlock()
- s.Close()
- }
- }
- }
-}
diff --git a/core/bloombits/matcher_test.go b/core/bloombits/matcher_test.go
deleted file mode 100644
index 7401b340e5..0000000000
--- a/core/bloombits/matcher_test.go
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-//
-// This file is a derived work, based on the go-ethereum library whose original
-// notices appear below.
-//
-// It is distributed under a license compatible with the licensing terms of the
-// original code from which it is derived.
-//
-// Much love to the original authors for their work.
-// **********
-// Copyright 2017 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 .
-
-package bloombits
-
-import (
- "context"
- "math/rand"
- "sync/atomic"
- "testing"
- "time"
-
- "github.com/ava-labs/libevm/common"
-)
-
-const testSectionSize = 4096
-
-// Tests that wildcard filter rules (nil) can be specified and are handled well.
-func TestMatcherWildcards(t *testing.T) {
- t.Parallel()
- matcher := NewMatcher(testSectionSize, [][][]byte{
- {common.Address{}.Bytes(), common.Address{0x01}.Bytes()}, // Default address is not a wildcard
- {common.Hash{}.Bytes(), common.Hash{0x01}.Bytes()}, // Default hash is not a wildcard
- {common.Hash{0x01}.Bytes()}, // Plain rule, sanity check
- {common.Hash{0x01}.Bytes(), nil}, // Wildcard suffix, drop rule
- {nil, common.Hash{0x01}.Bytes()}, // Wildcard prefix, drop rule
- {nil, nil}, // Wildcard combo, drop rule
- {}, // Inited wildcard rule, drop rule
- nil, // Proper wildcard rule, drop rule
- })
- if len(matcher.filters) != 3 {
- t.Fatalf("filter system size mismatch: have %d, want %d", len(matcher.filters), 3)
- }
- if len(matcher.filters[0]) != 2 {
- t.Fatalf("address clause size mismatch: have %d, want %d", len(matcher.filters[0]), 2)
- }
- if len(matcher.filters[1]) != 2 {
- t.Fatalf("combo topic clause size mismatch: have %d, want %d", len(matcher.filters[1]), 2)
- }
- if len(matcher.filters[2]) != 1 {
- t.Fatalf("singletone topic clause size mismatch: have %d, want %d", len(matcher.filters[2]), 1)
- }
-}
-
-// Tests the matcher pipeline on a single continuous workflow without interrupts.
-func TestMatcherContinuous(t *testing.T) {
- t.Parallel()
- testMatcherDiffBatches(t, [][]bloomIndexes{{{10, 20, 30}}}, 0, 100000, false, 75)
- testMatcherDiffBatches(t, [][]bloomIndexes{{{32, 3125, 100}}, {{40, 50, 10}}}, 0, 100000, false, 81)
- testMatcherDiffBatches(t, [][]bloomIndexes{{{4, 8, 11}, {7, 8, 17}}, {{9, 9, 12}, {15, 20, 13}}, {{18, 15, 15}, {12, 10, 4}}}, 0, 10000, false, 36)
-}
-
-// Tests the matcher pipeline on a constantly interrupted and resumed work pattern
-// with the aim of ensuring data items are requested only once.
-func TestMatcherIntermittent(t *testing.T) {
- t.Parallel()
- testMatcherDiffBatches(t, [][]bloomIndexes{{{10, 20, 30}}}, 0, 100000, true, 75)
- testMatcherDiffBatches(t, [][]bloomIndexes{{{32, 3125, 100}}, {{40, 50, 10}}}, 0, 100000, true, 81)
- testMatcherDiffBatches(t, [][]bloomIndexes{{{4, 8, 11}, {7, 8, 17}}, {{9, 9, 12}, {15, 20, 13}}, {{18, 15, 15}, {12, 10, 4}}}, 0, 10000, true, 36)
-}
-
-// Tests the matcher pipeline on random input to hopefully catch anomalies.
-func TestMatcherRandom(t *testing.T) {
- t.Parallel()
- for i := 0; i < 10; i++ {
- testMatcherBothModes(t, makeRandomIndexes([]int{1}, 50), 0, 10000, 0)
- testMatcherBothModes(t, makeRandomIndexes([]int{3}, 50), 0, 10000, 0)
- testMatcherBothModes(t, makeRandomIndexes([]int{2, 2, 2}, 20), 0, 10000, 0)
- testMatcherBothModes(t, makeRandomIndexes([]int{5, 5, 5}, 50), 0, 10000, 0)
- testMatcherBothModes(t, makeRandomIndexes([]int{4, 4, 4}, 20), 0, 10000, 0)
- }
-}
-
-// Tests that the matcher can properly find matches if the starting block is
-// shifted from a multiple of 8. This is needed to cover an optimisation with
-// bitset matching https://github.com/ethereum/go-ethereum/issues/15309.
-func TestMatcherShifted(t *testing.T) {
- t.Parallel()
- // Block 0 always matches in the tests, skip ahead of first 8 blocks with the
- // start to get a potential zero byte in the matcher bitset.
-
- // To keep the second bitset byte zero, the filter must only match for the first
- // time in block 16, so doing an all-16 bit filter should suffice.
-
- // To keep the starting block non divisible by 8, block number 9 is the first
- // that would introduce a shift and not match block 0.
- testMatcherBothModes(t, [][]bloomIndexes{{{16, 16, 16}}}, 9, 64, 0)
-}
-
-// Tests that matching on everything doesn't crash (special case internally).
-func TestWildcardMatcher(t *testing.T) {
- t.Parallel()
- testMatcherBothModes(t, nil, 0, 10000, 0)
-}
-
-// makeRandomIndexes generates a random filter system, composed of multiple filter
-// criteria, each having one bloom list component for the address and arbitrarily
-// many topic bloom list components.
-func makeRandomIndexes(lengths []int, max int) [][]bloomIndexes {
- res := make([][]bloomIndexes, len(lengths))
- for i, topics := range lengths {
- res[i] = make([]bloomIndexes, topics)
- for j := 0; j < topics; j++ {
- for k := 0; k < len(res[i][j]); k++ {
- res[i][j][k] = uint(rand.Intn(max-1) + 2)
- }
- }
- }
- return res
-}
-
-// testMatcherDiffBatches runs the given matches test in single-delivery and also
-// in batches delivery mode, verifying that all kinds of deliveries are handled
-// correctly within.
-func testMatcherDiffBatches(t *testing.T, filter [][]bloomIndexes, start, blocks uint64, intermittent bool, retrievals uint32) {
- singleton := testMatcher(t, filter, start, blocks, intermittent, retrievals, 1)
- batched := testMatcher(t, filter, start, blocks, intermittent, retrievals, 16)
-
- if singleton != batched {
- t.Errorf("filter = %v blocks = %v intermittent = %v: request count mismatch, %v in singleton vs. %v in batched mode", filter, blocks, intermittent, singleton, batched)
- }
-}
-
-// testMatcherBothModes runs the given matcher test in both continuous as well as
-// in intermittent mode, verifying that the request counts match each other.
-func testMatcherBothModes(t *testing.T, filter [][]bloomIndexes, start, blocks uint64, retrievals uint32) {
- continuous := testMatcher(t, filter, start, blocks, false, retrievals, 16)
- intermittent := testMatcher(t, filter, start, blocks, true, retrievals, 16)
-
- if continuous != intermittent {
- t.Errorf("filter = %v blocks = %v: request count mismatch, %v in continuous vs. %v in intermittent mode", filter, blocks, continuous, intermittent)
- }
-}
-
-// testMatcher is a generic tester to run the given matcher test and return the
-// number of requests made for cross validation between different modes.
-func testMatcher(t *testing.T, filter [][]bloomIndexes, start, blocks uint64, intermittent bool, retrievals uint32, maxReqCount int) uint32 {
- // Create a new matcher an simulate our explicit random bitsets
- matcher := NewMatcher(testSectionSize, nil)
- matcher.filters = filter
-
- for _, rule := range filter {
- for _, topic := range rule {
- for _, bit := range topic {
- matcher.addScheduler(bit)
- }
- }
- }
- // Track the number of retrieval requests made
- var requested atomic.Uint32
-
- // Start the matching session for the filter and the retriever goroutines
- quit := make(chan struct{})
- matches := make(chan uint64, 16)
-
- session, err := matcher.Start(context.Background(), start, blocks-1, matches)
- if err != nil {
- t.Fatalf("failed to stat matcher session: %v", err)
- }
- startRetrievers(session, quit, &requested, maxReqCount)
-
- // Iterate over all the blocks and verify that the pipeline produces the correct matches
- for i := start; i < blocks; i++ {
- if expMatch3(filter, i) {
- match, ok := <-matches
- if !ok {
- t.Errorf("filter = %v blocks = %v intermittent = %v: expected #%v, results channel closed", filter, blocks, intermittent, i)
- return 0
- }
- if match != i {
- t.Errorf("filter = %v blocks = %v intermittent = %v: expected #%v, got #%v", filter, blocks, intermittent, i, match)
- }
- // If we're testing intermittent mode, abort and restart the pipeline
- if intermittent {
- session.Close()
- close(quit)
-
- quit = make(chan struct{})
- matches = make(chan uint64, 16)
-
- session, err = matcher.Start(context.Background(), i+1, blocks-1, matches)
- if err != nil {
- t.Fatalf("failed to stat matcher session: %v", err)
- }
- startRetrievers(session, quit, &requested, maxReqCount)
- }
- }
- }
- // Ensure the result channel is torn down after the last block
- match, ok := <-matches
- if ok {
- t.Errorf("filter = %v blocks = %v intermittent = %v: expected closed channel, got #%v", filter, blocks, intermittent, match)
- }
- // Clean up the session and ensure we match the expected retrieval count
- session.Close()
- close(quit)
-
- if retrievals != 0 && requested.Load() != retrievals {
- t.Errorf("filter = %v blocks = %v intermittent = %v: request count mismatch, have #%v, want #%v", filter, blocks, intermittent, requested.Load(), retrievals)
- }
- return requested.Load()
-}
-
-// startRetrievers starts a batch of goroutines listening for section requests
-// and serving them.
-func startRetrievers(session *MatcherSession, quit chan struct{}, retrievals *atomic.Uint32, batch int) {
- requests := make(chan chan *Retrieval)
-
- for i := 0; i < 10; i++ {
- // Start a multiplexer to test multiple threaded execution
- go session.Multiplex(batch, 100*time.Microsecond, requests)
-
- // Start a services to match the above multiplexer
- go func() {
- for {
- // Wait for a service request or a shutdown
- select {
- case <-quit:
- return
-
- case request := <-requests:
- task := <-request
-
- task.Bitsets = make([][]byte, len(task.Sections))
- for i, section := range task.Sections {
- if rand.Int()%4 != 0 { // Handle occasional missing deliveries
- task.Bitsets[i] = generateBitset(task.Bit, section)
- retrievals.Add(1)
- }
- }
- request <- task
- }
- }
- }()
- }
-}
-
-// generateBitset generates the rotated bitset for the given bloom bit and section
-// numbers.
-func generateBitset(bit uint, section uint64) []byte {
- bitset := make([]byte, testSectionSize/8)
- for i := 0; i < len(bitset); i++ {
- for b := 0; b < 8; b++ {
- blockIdx := section*testSectionSize + uint64(i*8+b)
- bitset[i] += bitset[i]
- if (blockIdx % uint64(bit)) == 0 {
- bitset[i]++
- }
- }
- }
- return bitset
-}
-
-func expMatch1(filter bloomIndexes, i uint64) bool {
- for _, ii := range filter {
- if (i % uint64(ii)) != 0 {
- return false
- }
- }
- return true
-}
-
-func expMatch2(filter []bloomIndexes, i uint64) bool {
- for _, ii := range filter {
- if expMatch1(ii, i) {
- return true
- }
- }
- return false
-}
-
-func expMatch3(filter [][]bloomIndexes, i uint64) bool {
- for _, ii := range filter {
- if !expMatch2(ii, i) {
- return false
- }
- }
- return true
-}
diff --git a/core/bloombits/scheduler.go b/core/bloombits/scheduler.go
deleted file mode 100644
index 3e0dbcfcb0..0000000000
--- a/core/bloombits/scheduler.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-//
-// This file is a derived work, based on the go-ethereum library whose original
-// notices appear below.
-//
-// It is distributed under a license compatible with the licensing terms of the
-// original code from which it is derived.
-//
-// Much love to the original authors for their work.
-// **********
-// Copyright 2017 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 .
-
-package bloombits
-
-import (
- "sync"
-)
-
-// request represents a bloom retrieval task to prioritize and pull from the local
-// database or remotely from the network.
-type request struct {
- section uint64 // Section index to retrieve the a bit-vector from
- bit uint // Bit index within the section to retrieve the vector of
-}
-
-// response represents the state of a requested bit-vector through a scheduler.
-type response struct {
- cached []byte // Cached bits to dedup multiple requests
- done chan struct{} // Channel to allow waiting for completion
-}
-
-// scheduler handles the scheduling of bloom-filter retrieval operations for
-// entire section-batches belonging to a single bloom bit. Beside scheduling the
-// retrieval operations, this struct also deduplicates the requests and caches
-// the results to minimize network/database overhead even in complex filtering
-// scenarios.
-type scheduler struct {
- bit uint // Index of the bit in the bloom filter this scheduler is responsible for
- responses map[uint64]*response // Currently pending retrieval requests or already cached responses
- lock sync.Mutex // Lock protecting the responses from concurrent access
-}
-
-// newScheduler creates a new bloom-filter retrieval scheduler for a specific
-// bit index.
-func newScheduler(idx uint) *scheduler {
- return &scheduler{
- bit: idx,
- responses: make(map[uint64]*response),
- }
-}
-
-// run creates a retrieval pipeline, receiving section indexes from sections and
-// returning the results in the same order through the done channel. Concurrent
-// runs of the same scheduler are allowed, leading to retrieval task deduplication.
-func (s *scheduler) run(sections chan uint64, dist chan *request, done chan []byte, quit chan struct{}, wg *sync.WaitGroup) {
- // Create a forwarder channel between requests and responses of the same size as
- // the distribution channel (since that will block the pipeline anyway).
- pend := make(chan uint64, cap(dist))
-
- // Start the pipeline schedulers to forward between user -> distributor -> user
- wg.Add(2)
- go s.scheduleRequests(sections, dist, pend, quit, wg)
- go s.scheduleDeliveries(pend, done, quit, wg)
-}
-
-// reset cleans up any leftovers from previous runs. This is required before a
-// restart to ensure the no previously requested but never delivered state will
-// cause a lockup.
-func (s *scheduler) reset() {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- for section, res := range s.responses {
- if res.cached == nil {
- delete(s.responses, section)
- }
- }
-}
-
-// scheduleRequests reads section retrieval requests from the input channel,
-// deduplicates the stream and pushes unique retrieval tasks into the distribution
-// channel for a database or network layer to honour.
-func (s *scheduler) scheduleRequests(reqs chan uint64, dist chan *request, pend chan uint64, quit chan struct{}, wg *sync.WaitGroup) {
- // Clean up the goroutine and pipeline when done
- defer wg.Done()
- defer close(pend)
-
- // Keep reading and scheduling section requests
- for {
- select {
- case <-quit:
- return
-
- case section, ok := <-reqs:
- // New section retrieval requested
- if !ok {
- return
- }
- // Deduplicate retrieval requests
- unique := false
-
- s.lock.Lock()
- if s.responses[section] == nil {
- s.responses[section] = &response{
- done: make(chan struct{}),
- }
- unique = true
- }
- s.lock.Unlock()
-
- // Schedule the section for retrieval and notify the deliverer to expect this section
- if unique {
- select {
- case <-quit:
- return
- case dist <- &request{bit: s.bit, section: section}:
- }
- }
- select {
- case <-quit:
- return
- case pend <- section:
- }
- }
- }
-}
-
-// scheduleDeliveries reads section acceptance notifications and waits for them
-// to be delivered, pushing them into the output data buffer.
-func (s *scheduler) scheduleDeliveries(pend chan uint64, done chan []byte, quit chan struct{}, wg *sync.WaitGroup) {
- // Clean up the goroutine and pipeline when done
- defer wg.Done()
- defer close(done)
-
- // Keep reading notifications and scheduling deliveries
- for {
- select {
- case <-quit:
- return
-
- case idx, ok := <-pend:
- // New section retrieval pending
- if !ok {
- return
- }
- // Wait until the request is honoured
- s.lock.Lock()
- res := s.responses[idx]
- s.lock.Unlock()
-
- select {
- case <-quit:
- return
- case <-res.done:
- }
- // Deliver the result
- select {
- case <-quit:
- return
- case done <- res.cached:
- }
- }
- }
-}
-
-// deliver is called by the request distributor when a reply to a request arrives.
-func (s *scheduler) deliver(sections []uint64, data [][]byte) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- for i, section := range sections {
- if res := s.responses[section]; res != nil && res.cached == nil { // Avoid non-requests and double deliveries
- res.cached = data[i]
- close(res.done)
- }
- }
-}
diff --git a/core/bloombits/scheduler_test.go b/core/bloombits/scheduler_test.go
deleted file mode 100644
index 82f3df5c56..0000000000
--- a/core/bloombits/scheduler_test.go
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-//
-// This file is a derived work, based on the go-ethereum library whose original
-// notices appear below.
-//
-// It is distributed under a license compatible with the licensing terms of the
-// original code from which it is derived.
-//
-// Much love to the original authors for their work.
-// **********
-// Copyright 2017 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 .
-
-package bloombits
-
-import (
- "bytes"
- "math/big"
- "sync"
- "sync/atomic"
- "testing"
-)
-
-// Tests that the scheduler can deduplicate and forward retrieval requests to
-// underlying fetchers and serve responses back, irrelevant of the concurrency
-// of the requesting clients or serving data fetchers.
-func TestSchedulerSingleClientSingleFetcher(t *testing.T) { testScheduler(t, 1, 1, 5000) }
-func TestSchedulerSingleClientMultiFetcher(t *testing.T) { testScheduler(t, 1, 10, 5000) }
-func TestSchedulerMultiClientSingleFetcher(t *testing.T) { testScheduler(t, 10, 1, 5000) }
-func TestSchedulerMultiClientMultiFetcher(t *testing.T) { testScheduler(t, 10, 10, 5000) }
-
-func testScheduler(t *testing.T, clients int, fetchers int, requests int) {
- t.Parallel()
- f := newScheduler(0)
-
- // Create a batch of handler goroutines that respond to bloom bit requests and
- // deliver them to the scheduler.
- var fetchPend sync.WaitGroup
- fetchPend.Add(fetchers)
- defer fetchPend.Wait()
-
- fetch := make(chan *request, 16)
- defer close(fetch)
-
- var delivered atomic.Uint32
- for i := 0; i < fetchers; i++ {
- go func() {
- defer fetchPend.Done()
-
- for req := range fetch {
- delivered.Add(1)
-
- f.deliver([]uint64{
- req.section + uint64(requests), // Non-requested data (ensure it doesn't go out of bounds)
- req.section, // Requested data
- req.section, // Duplicated data (ensure it doesn't double close anything)
- }, [][]byte{
- {},
- new(big.Int).SetUint64(req.section).Bytes(),
- new(big.Int).SetUint64(req.section).Bytes(),
- })
- }
- }()
- }
- // Start a batch of goroutines to concurrently run scheduling tasks
- quit := make(chan struct{})
-
- var pend sync.WaitGroup
- pend.Add(clients)
-
- for i := 0; i < clients; i++ {
- go func() {
- defer pend.Done()
-
- in := make(chan uint64, 16)
- out := make(chan []byte, 16)
-
- f.run(in, fetch, out, quit, &pend)
-
- go func() {
- for j := 0; j < requests; j++ {
- in <- uint64(j)
- }
- close(in)
- }()
- b := new(big.Int)
- for j := 0; j < requests; j++ {
- bits := <-out
- if want := b.SetUint64(uint64(j)).Bytes(); !bytes.Equal(bits, want) {
- t.Errorf("vector %d: delivered content mismatch: have %x, want %x", j, bits, want)
- }
- }
- }()
- }
- pend.Wait()
-
- if have := delivered.Load(); int(have) != requests {
- t.Errorf("request count mismatch: have %v, want %v", have, requests)
- }
-}
diff --git a/eth/api_backend.go b/eth/api_backend.go
index e3b2e34054..fe1a074800 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -35,6 +35,7 @@ import (
"github.com/ava-labs/libevm/accounts"
"github.com/ava-labs/libevm/common"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/state"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/core/vm"
@@ -43,7 +44,6 @@ import (
"github.com/ava-labs/subnet-evm/commontype"
"github.com/ava-labs/subnet-evm/consensus"
"github.com/ava-labs/subnet-evm/core"
- "github.com/ava-labs/subnet-evm/core/bloombits"
"github.com/ava-labs/subnet-evm/core/txpool"
"github.com/ava-labs/subnet-evm/eth/gasprice"
"github.com/ava-labs/subnet-evm/eth/tracers"
diff --git a/eth/backend.go b/eth/backend.go
index 51ca8eef68..bf9a37e00b 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -38,6 +38,7 @@ import (
"github.com/ava-labs/avalanchego/utils/timer/mockable"
"github.com/ava-labs/libevm/accounts"
"github.com/ava-labs/libevm/common"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/rawdb"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/core/vm"
@@ -46,7 +47,6 @@ import (
"github.com/ava-labs/libevm/log"
"github.com/ava-labs/subnet-evm/consensus"
"github.com/ava-labs/subnet-evm/core"
- "github.com/ava-labs/subnet-evm/core/bloombits"
"github.com/ava-labs/subnet-evm/core/state/pruner"
"github.com/ava-labs/subnet-evm/core/txpool"
"github.com/ava-labs/subnet-evm/core/txpool/legacypool"
diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go
index 4df89b1ce6..54919d8684 100644
--- a/eth/filters/bench_test.go
+++ b/eth/filters/bench_test.go
@@ -35,10 +35,10 @@ import (
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/common/bitutil"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/rawdb"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/ethdb"
- "github.com/ava-labs/subnet-evm/core/bloombits"
)
func BenchmarkBloomBits512(b *testing.B) {
diff --git a/eth/filters/filter.go b/eth/filters/filter.go
index d3cbe60f63..b11a460ecf 100644
--- a/eth/filters/filter.go
+++ b/eth/filters/filter.go
@@ -34,8 +34,8 @@ import (
"math/big"
"github.com/ava-labs/libevm/common"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/types"
- "github.com/ava-labs/subnet-evm/core/bloombits"
"github.com/ava-labs/subnet-evm/plugin/evm/customlogs"
"github.com/ava-labs/subnet-evm/rpc"
)
diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go
index 4b9219f0c7..6e50b9c369 100644
--- a/eth/filters/filter_system.go
+++ b/eth/filters/filter_system.go
@@ -37,12 +37,12 @@ import (
ethereum "github.com/ava-labs/libevm"
"github.com/ava-labs/libevm/common"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/ethdb"
"github.com/ava-labs/libevm/event"
"github.com/ava-labs/libevm/log"
"github.com/ava-labs/subnet-evm/core"
- "github.com/ava-labs/subnet-evm/core/bloombits"
"github.com/ava-labs/subnet-evm/params"
"github.com/ava-labs/subnet-evm/rpc"
)
diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go
index 13941e266a..5aeceb3f10 100644
--- a/eth/filters/filter_system_test.go
+++ b/eth/filters/filter_system_test.go
@@ -40,13 +40,13 @@ import (
ethereum "github.com/ava-labs/libevm"
"github.com/ava-labs/libevm/common"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/rawdb"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/ethdb"
"github.com/ava-labs/libevm/event"
"github.com/ava-labs/subnet-evm/consensus/dummy"
"github.com/ava-labs/subnet-evm/core"
- "github.com/ava-labs/subnet-evm/core/bloombits"
"github.com/ava-labs/subnet-evm/internal/ethapi"
"github.com/ava-labs/subnet-evm/params"
"github.com/ava-labs/subnet-evm/plugin/evm/customrawdb"
diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go
index cc812772ca..e3ac3d63a0 100644
--- a/internal/ethapi/api_test.go
+++ b/internal/ethapi/api_test.go
@@ -47,6 +47,7 @@ import (
"github.com/ava-labs/libevm/accounts/keystore"
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/common/hexutil"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/rawdb"
"github.com/ava-labs/libevm/core/state"
"github.com/ava-labs/libevm/core/types"
@@ -60,7 +61,6 @@ import (
"github.com/ava-labs/subnet-evm/consensus"
"github.com/ava-labs/subnet-evm/consensus/dummy"
"github.com/ava-labs/subnet-evm/core"
- "github.com/ava-labs/subnet-evm/core/bloombits"
"github.com/ava-labs/subnet-evm/internal/blocktest"
"github.com/ava-labs/subnet-evm/params"
"github.com/ava-labs/subnet-evm/plugin/evm/upgrade/legacy"
diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go
index d51a76c648..b62133f5e9 100644
--- a/internal/ethapi/backend.go
+++ b/internal/ethapi/backend.go
@@ -35,6 +35,7 @@ import (
"github.com/ava-labs/libevm/accounts"
"github.com/ava-labs/libevm/common"
+ "github.com/ava-labs/libevm/core/bloombits"
"github.com/ava-labs/libevm/core/state"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/core/vm"
@@ -43,7 +44,6 @@ import (
"github.com/ava-labs/subnet-evm/commontype"
"github.com/ava-labs/subnet-evm/consensus"
"github.com/ava-labs/subnet-evm/core"
- "github.com/ava-labs/subnet-evm/core/bloombits"
"github.com/ava-labs/subnet-evm/params"
"github.com/ava-labs/subnet-evm/rpc"
)
diff --git a/internal/ethapi/mocks_test.go b/internal/ethapi/mocks_test.go
index e330d0a8ba..6946fd8e63 100644
--- a/internal/ethapi/mocks_test.go
+++ b/internal/ethapi/mocks_test.go
@@ -17,6 +17,7 @@ import (
accounts "github.com/ava-labs/libevm/accounts"
common "github.com/ava-labs/libevm/common"
+ bloombits "github.com/ava-labs/libevm/core/bloombits"
state "github.com/ava-labs/libevm/core/state"
types "github.com/ava-labs/libevm/core/types"
vm "github.com/ava-labs/libevm/core/vm"
@@ -25,7 +26,6 @@ import (
commontype "github.com/ava-labs/subnet-evm/commontype"
consensus "github.com/ava-labs/subnet-evm/consensus"
core "github.com/ava-labs/subnet-evm/core"
- bloombits "github.com/ava-labs/subnet-evm/core/bloombits"
params "github.com/ava-labs/subnet-evm/params"
rpc "github.com/ava-labs/subnet-evm/rpc"
gomock "go.uber.org/mock/gomock"