Skip to content
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
a2b5450
feat(sync/vm): parallelize syncer execution with errgroup
powerslider Aug 19, 2025
2b8b9e3
Merge branch 'master' into powerslider/1130-concurrent-syncers
powerslider Aug 19, 2025
13f7c4a
test(sync/vm): simplify registry tests using utilstest
powerslider Aug 20, 2025
292f8b2
test(sync/vm): remove unnecessary test cleanups
powerslider Aug 20, 2025
47e71af
test: forgot to add FuncSyncer implementations
powerslider Aug 20, 2025
f6174a4
test: improve comments
powerslider Aug 21, 2025
9772d76
test: use require.FailNow instead of t.Fatal
powerslider Aug 21, 2025
f3e03b8
test: make the base test timeout be derived by t.Deadline
powerslider Aug 21, 2025
0d62f6d
Merge branch 'master' into powerslider/1130-concurrent-syncers
powerslider Aug 21, 2025
90d2911
fix: gci formatting
powerslider Aug 21, 2025
5c49827
fix: do not assume on first syncer failing
powerslider Aug 21, 2025
40b7313
fix: more remarks
powerslider Aug 22, 2025
a6497d2
Merge branch 'master' into powerslider/1130-concurrent-syncers
powerslider Aug 22, 2025
489cb79
feat(sync): decouple code syncer from state syncer and run concurrently
powerslider Aug 22, 2025
8645bc3
fix: split table test into separate tests to reduce complexity
powerslider Aug 25, 2025
5436497
Merge branch 'powerslider/1130-concurrent-syncers' into powerslider/1…
powerslider Aug 25, 2025
0451ace
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Aug 27, 2025
d4be816
chore: refactor and rename code syncer interfaces
powerslider Aug 27, 2025
e569f56
fix: more renaming
powerslider Aug 27, 2025
f86373b
fix: goimports
powerslider Aug 27, 2025
bab7f02
fix: gci format
powerslider Aug 27, 2025
49f3c53
chore(sync): add Ready() to CodeFetcher and gate state sync startup
powerslider Aug 27, 2025
c422987
fix: broken test and lint issue
powerslider Aug 27, 2025
19fe953
chore: rename FinishCodeCollection to Finalize
powerslider Aug 27, 2025
b3c04be
docs: document CodeFetcher
powerslider Aug 27, 2025
9f2f658
fix: ignore require_no_error_inline_func due to messing with the cont…
powerslider Aug 27, 2025
ed714de
fix: workaround for require_no_error_inline_func due to messing with …
powerslider Aug 27, 2025
78f536e
fix: modify test_require_no_error_inline_func to flag only single-LHS…
powerslider Aug 27, 2025
b7d98a3
fix: remove atomic name in client.go
powerslider Aug 28, 2025
0ec9d1d
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Aug 28, 2025
f20fe23
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Aug 29, 2025
01aeeee
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 1, 2025
14fe808
feat(sync): add Name() and ID() to Syncer interface to make syncer im…
powerslider Sep 2, 2025
5063873
feat(statesync): introduce CodeFetcherQueue and decouple CodeSyncer c…
powerslider Sep 3, 2025
c7b86db
fix: move getCodeToFetchFromDB to code fetcher
powerslider Sep 3, 2025
e8fee23
fix: add CodeFetcherOption type
powerslider Sep 3, 2025
3a447b6
fix: some formatting
powerslider Sep 3, 2025
bd5be21
fix: PR remarks on tests
powerslider Sep 3, 2025
af55380
fix: more PR remarks on tests
powerslider Sep 4, 2025
1f971aa
fix: add ability to track in-flight AddCode calls to coordinate clean…
powerslider Sep 4, 2025
401b564
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 5, 2025
5be557a
refactor(sync/statesync): harden code fetcher lifecycle, improve shut…
powerslider Sep 5, 2025
ee8b54f
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 9, 2025
51873a1
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 11, 2025
2097dbc
fix: apply recommended optimizations
powerslider Sep 12, 2025
4c64aa5
feat(sync/statesync): adopt single forwarder pattern for CodeQueue
powerslider Sep 12, 2025
8492d1e
fix: channel close races
powerslider Sep 15, 2025
af18251
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 15, 2025
63b8dbd
fix: linter error and simplify in tests
powerslider Sep 15, 2025
3151ef3
fix: some naming changes
powerslider Sep 15, 2025
be20084
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 16, 2025
aed34f1
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 17, 2025
0b35e75
refactor(plugin/evm): move syncer client/registry to plugin/evm/vmsyn…
powerslider Sep 17, 2025
5487e18
Remove libevm `cmd/*` packages. (#1224)
JonathanOppenheimer Sep 17, 2025
ed6bb70
Remove libevm `signer` package (#1225)
JonathanOppenheimer Sep 17, 2025
35e6b12
Remove duplicate cancun checks (#1223)
alarso16 Sep 17, 2025
446f283
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 18, 2025
f8a7e4c
fix: some naming changes
powerslider Sep 23, 2025
adadd3c
refactor: simplify `CodeQueue` fan-in (#1254)
powerslider Sep 23, 2025
e5d0c7d
refactor(statesync): simplify CodeQueue, remove auto-init, rename cap…
powerslider Sep 23, 2025
76e1ce0
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 23, 2025
41f199e
refactor(statesync): move code deduplication from queue (producer) to…
powerslider Sep 23, 2025
8f779fd
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 23, 2025
dc046e8
fix: some naming changes
powerslider Sep 23, 2025
3e9f945
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 24, 2025
416a906
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 24, 2025
54c2592
fix(statesync): prevent data race by serializing out close with enqueues
powerslider Sep 24, 2025
6b1a6e3
fix(statesync): eliminate send/close race in code queue
powerslider Sep 24, 2025
3b596bb
fix: remove unused method
powerslider Sep 24, 2025
ebfbed4
Merge branch 'master' into powerslider/1139-code-syncer-decoupling
powerslider Sep 24, 2025
aea5f06
fix(statesync): serialize code ownership and release after durable co…
powerslider Sep 25, 2025
c895e3d
fix: handle error for `Finalize` call
powerslider Sep 25, 2025
a40996b
fix(statesync): make Finalize idempotent via CAS; error only on quit
powerslider Sep 25, 2025
f535b36
refactor(statesync): remove `CodeRequestQueue` interface and use `Cod…
powerslider Sep 25, 2025
1aad3e7
refactor(statesync): simplify CodeQueue by removing AddCode state che…
powerslider Sep 25, 2025
13d652e
fix(statesync): add fix to align with `AddCode` contract
powerslider Sep 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions scripts/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,17 @@ function test_require_error_is_no_funcs_as_params {
}

function test_require_no_error_inline_func {
if grep -R -zo -P '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' "${DEFAULT_FILES[@]}"; then
# Flag only when a single variable whose name contains "err" or "Err"
# (e.g., err, myErr, parseError) is assigned from a call (:= or =), and later
# that same variable is passed to require.NoError(...). We explicitly require
# no commas on the LHS to avoid flagging multi-return assignments like
# "val, err := f()" or "err, val := f()".
#
# Capture the variable name and enforce it matches in the subsequent require.NoError.
local -r pattern='^\s*([A-Za-z_][A-Za-z0-9_]*[eE]rr[A-Za-z0-9_]*)\s*:?=\s*[^,\n]*\([^)]*\).*\n(?:(?!^\s*(?:if|require)).*\n)*^\s*require\.NoError\((?:t,\s*)?\1\)'
if grep -R -zo -P "$pattern" "${DEFAULT_FILES[@]}"; then
echo ""
echo "Checking that a function with a single error return doesn't error should be done in-line."
echo "Checking that a function with a single error return doesn't error should be done in-line (single LHS var containing 'err')."
echo ""
return 1
fi
Expand Down
42 changes: 23 additions & 19 deletions sync/statesync/code_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ const (
)

var (
_ synccommon.Syncer = (*codeSyncer)(nil)
_ synccommon.Syncer = (*CodeSyncer)(nil)

errFailedToAddCodeHashesToQueue = errors.New("failed to add code hashes to queue")
)

// codeSyncer syncs code bytes from the network in a seprate thread.
// CodeSyncer syncs code bytes from the network in a seprate thread.
// Tracks outstanding requests in the DB, so that it will still fulfill them if interrupted.
type codeSyncer struct {
type CodeSyncer struct {
db ethdb.Database
client statesyncclient.Client
config Config
Expand All @@ -47,16 +47,17 @@ type codeSyncer struct {
done <-chan struct{}
}

// newCodeSyncer returns a code syncer that will sync code bytes from the network in a separate thread.
func newCodeSyncer(client statesyncclient.Client, db ethdb.Database, config Config) (*codeSyncer, error) {
// NewCodeSyncer allows external packages (e.g., registry wiring) to create a code syncer as a separate task and
// inject it as a [CodeFetcher] into the state syncer.
func NewCodeSyncer(client statesyncclient.Client, db ethdb.Database, config Config) (*CodeSyncer, error) {
cfg := config.WithUnsetDefaults()

dbCodeHashes, err := getCodeToFetchFromDB(db)
if err != nil {
return nil, fmt.Errorf("failed to add code hashes to queue: %w", err)
}

return &codeSyncer{
return &CodeSyncer{
db: db,
client: client,
config: cfg,
Expand All @@ -66,10 +67,10 @@ func newCodeSyncer(client statesyncclient.Client, db ethdb.Database, config Conf
}, nil
}

// Start the worker thread and populate the code hashes queue with active work.
// Sync starts the worker thread and populates the code hashes queue with active work.
// Blocks until all outstanding code requests from a previous sync have been
// fetched and the code channel has been closed, or the context is cancelled.
func (c *codeSyncer) Sync(ctx context.Context) error {
func (c *CodeSyncer) Sync(ctx context.Context) error {
eg, egCtx := errgroup.WithContext(ctx)
c.done = egCtx.Done()

Expand All @@ -80,7 +81,7 @@ func (c *codeSyncer) Sync(ctx context.Context) error {

// Queue the code hashes from the previous sync
if err := c.addCode(c.dbCodeHashes); err != nil {
return fmt.Errorf("Unable to resume previous sync: %w", err)
return fmt.Errorf("unable to resume previous sync: %w", err)
}
c.dbCodeHashes = nil
close(c.open)
Expand Down Expand Up @@ -128,7 +129,7 @@ func getCodeToFetchFromDB(db ethdb.Database) ([]common.Hash, error) {

// work fulfills any incoming requests from the producer channel by fetching code bytes from the network
// and fulfilling them by updating the database.
func (c *codeSyncer) work(ctx context.Context) error {
func (c *CodeSyncer) work(ctx context.Context) error {
codeHashes := make([]common.Hash, 0, message.MaxCodeHashesPerRequest)

for {
Expand Down Expand Up @@ -165,7 +166,7 @@ func (c *codeSyncer) work(ctx context.Context) error {
// marks the work as complete.
// codeHashes should not be empty or contain duplicate hashes.
// Returns an error if one is encountered, signaling the worker thread to terminate.
func (c *codeSyncer) fulfillCodeRequest(ctx context.Context, codeHashes []common.Hash) error {
func (c *CodeSyncer) fulfillCodeRequest(ctx context.Context, codeHashes []common.Hash) error {
codeByteSlices, err := c.client.GetCode(ctx, codeHashes)
if err != nil {
return err
Expand All @@ -190,12 +191,12 @@ func (c *codeSyncer) fulfillCodeRequest(ctx context.Context, codeHashes []common
// AddCode checks if [codeHashes] need to be fetched from the network and adds them to the queue if so.
// assumes that [codeHashes] are valid non-empty code hashes.
// This blocks until the code syncer is open and ready to accept requests.
func (c *codeSyncer) AddCode(codeHashes []common.Hash) error {
func (c *CodeSyncer) AddCode(codeHashes []common.Hash) error {
<-c.open
return c.addCode(codeHashes)
}

func (c *codeSyncer) addCode(codeHashes []common.Hash) error {
func (c *CodeSyncer) addCode(codeHashes []common.Hash) error {
batch := c.db.NewBatch()

c.lock.Lock()
Expand All @@ -217,18 +218,21 @@ func (c *codeSyncer) addCode(codeHashes []common.Hash) error {
return c.addHashesToQueue(selectedCodeHashes)
}

// notifyAccountTrieCompleted notifies the code syncer that there will be no more incoming
// code hashes from syncing the account trie, so it only needs to compelete its outstanding
// work.
// Finalize implements CodeFetcher by signaling no further code hashes will be added.
// Notifies the code syncer that there will be no more incoming code hashes from syncing the account trie,
// so it only needs to complete its outstanding work.
// Note: this allows the worker threads to exit and return a nil error.
func (c *codeSyncer) notifyAccountTrieCompleted() {
<-c.open // The code syncer must queue the previous code from the db first
func (c *CodeSyncer) Finalize() {
<-c.open // The code syncer must queue the previous code from the db first.
close(c.codeHashes)
}

// Ready returns a channel that is closed when the code syncer is ready to accept code hashes.
func (c *CodeSyncer) Ready() <-chan struct{} { return c.open }

// addHashesToQueue adds [codeHashes] to the queue and blocks until it is able to do so.
// This should be called after all other operation to add code hashes to the queue has been completed.
func (c *codeSyncer) addHashesToQueue(codeHashes []common.Hash) error {
func (c *CodeSyncer) addHashesToQueue(codeHashes []common.Hash) error {
for _, codeHash := range codeHashes {
select {
case c.codeHashes <- codeHash:
Expand Down
56 changes: 49 additions & 7 deletions sync/statesync/code_syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
package statesync

import (
"context"
"errors"
"testing"
"time"

"github.com/ava-labs/avalanchego/utils"
"github.com/ava-labs/libevm/common"
Expand All @@ -19,14 +19,15 @@ import (
"github.com/ava-labs/coreth/plugin/evm/customrawdb"
"github.com/ava-labs/coreth/plugin/evm/message"
"github.com/ava-labs/coreth/sync/handlers"
"github.com/ava-labs/coreth/utils/utilstest"

statesyncclient "github.com/ava-labs/coreth/sync/client"
handlerstats "github.com/ava-labs/coreth/sync/handlers/stats"
)

type codeSyncerTest struct {
clientDB ethdb.Database
setupCodeSyncer func(*codeSyncer)
setupCodeSyncer func(*CodeSyncer)
codeRequestHashes [][]common.Hash
codeByteSlices [][]byte
getCodeIntercept func(hashes []common.Hash, codeBytes [][]byte) ([][]byte, error)
Expand Down Expand Up @@ -54,10 +55,11 @@ func testCodeSyncer(t *testing.T, test codeSyncerTest) {
clientDB = rawdb.NewMemoryDatabase()
}

codeSyncer, err := newCodeSyncer(
cfg := NewDefaultConfig(testRequestSize)
codeSyncer, err := NewCodeSyncer(
mockClient,
clientDB,
NewDefaultConfig(testRequestSize),
cfg,
)
require.NoError(t, err)
if test.setupCodeSyncer != nil {
Expand All @@ -69,10 +71,14 @@ func testCodeSyncer(t *testing.T, test codeSyncerTest) {
require.ErrorIs(t, err, test.err)
}
}
codeSyncer.notifyAccountTrieCompleted()
codeSyncer.Finalize()
}()

err = codeSyncer.Sync(context.Background())
ctx, cancel := utilstest.NewTestContext(t)
defer cancel()

// Run the sync and handle expected error.
err = codeSyncer.Sync(ctx)
require.ErrorIs(t, err, test.err)
if err != nil {
return // don't check the state
Expand Down Expand Up @@ -106,7 +112,7 @@ func TestCodeSyncerManyCodeHashes(t *testing.T) {
}

testCodeSyncer(t, codeSyncerTest{
setupCodeSyncer: func(c *codeSyncer) {
setupCodeSyncer: func(c *CodeSyncer) {
c.codeHashes = make(chan common.Hash, 10)
},
codeRequestHashes: [][]common.Hash{codeHashes[0:100], codeHashes[100:2000], codeHashes[2000:2005], codeHashes[2005:]},
Expand Down Expand Up @@ -162,3 +168,39 @@ func TestCodeSyncerAddsMoreInProgressThanQueueSize(t *testing.T) {
codeByteSlices: codeByteSlices,
})
}

func TestCodeSyncerReady(t *testing.T) {
serverDB := memorydb.New()
codeRequestHandler := handlers.NewCodeRequestHandler(serverDB, message.Codec, handlerstats.NewNoopHandlerStats())
mockClient := statesyncclient.NewTestClient(message.Codec, nil, codeRequestHandler, nil)

clientDB := rawdb.NewMemoryDatabase()
cfg := NewDefaultConfig(testRequestSize)
codeSyncer, err := NewCodeSyncer(mockClient, clientDB, cfg)
require.NoError(t, err)

select {
case <-codeSyncer.Ready():
// If already closed, this would mean ready before Sync which shouldn't happen.
t.Fatalf("Ready should not be closed before Sync starts")
default:
}

ctx, cancel := utilstest.NewTestContext(t)

doneCh := make(chan error, 1)
go func() { doneCh <- codeSyncer.Sync(ctx) }()

// Wait briefly for Sync to initialize and close the ready channel.
utilstest.SleepWithContext(ctx, 50*time.Millisecond)

select {
case <-codeSyncer.Ready():
// ok
default:
t.Fatalf("Ready should be closed after Sync initialization")
}

cancel()
require.Error(t, <-doneCh)
}
40 changes: 25 additions & 15 deletions sync/statesync/state_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package statesync

import (
"context"
"errors"
"fmt"
"sync"

Expand All @@ -27,7 +28,10 @@ const (
defaultNumWorkers = 8
)

var _ synccommon.Syncer = (*stateSync)(nil)
var (
_ synccommon.Syncer = (*stateSync)(nil)
errCodeFetcherRequired = errors.New("code fetcher is required")
)

type Config struct {
BatchSize uint
Expand Down Expand Up @@ -76,10 +80,10 @@ type stateSync struct {
snapshot snapshot.SnapshotIterable // used to access the database we are syncing as a snapshot.
batchSize uint // write batches when they reach this size

segments chan syncclient.LeafSyncTask // channel of tasks to sync
syncer *syncclient.CallbackLeafSyncer // performs the sync, looping over each task's range and invoking specified callbacks
codeSyncer *codeSyncer // manages the asynchronous download and batching of code hashes
trieQueue *trieQueue // manages a persistent list of storage tries we need to sync and any segments that are created for them
segments chan syncclient.LeafSyncTask // channel of tasks to sync
syncer *syncclient.CallbackLeafSyncer // performs the sync, looping over each task's range and invoking specified callbacks
codeFetcher synccommon.CodeFetcher // fetcher that manages the asynchronous download and batching of code hashes
trieQueue *trieQueue // manages a persistent list of storage tries we need to sync and any segments that are created for them

// track the main account trie specifically to commit its root at the end of the operation
mainTrie *trieToSync
Expand All @@ -95,7 +99,7 @@ type stateSync struct {
stats *trieSyncStats
}

func NewSyncer(client syncclient.Client, db ethdb.Database, root common.Hash, config Config) (synccommon.Syncer, error) {
func NewSyncer(client syncclient.Client, db ethdb.Database, root common.Hash, fetcher synccommon.CodeFetcher, config Config) (synccommon.Syncer, error) {
cfg := config.WithUnsetDefaults()

ss := &stateSync{
Expand Down Expand Up @@ -125,12 +129,13 @@ func NewSyncer(client syncclient.Client, db ethdb.Database, root common.Hash, co
OnFailure: ss.onSyncFailure,
})

var err error
ss.codeSyncer, err = newCodeSyncer(client, db, cfg)
if err != nil {
return nil, err
if fetcher == nil {
return nil, errCodeFetcherRequired
}

ss.codeFetcher = fetcher

var err error
ss.trieQueue = NewTrieQueue(db)
if err := ss.trieQueue.clearIfRootDoesNotMatch(ss.root); err != nil {
return nil, err
Expand Down Expand Up @@ -171,7 +176,7 @@ func (t *stateSync) onStorageTrieFinished(root common.Hash) error {

// onMainTrieFinished is called after the main trie finishes syncing.
func (t *stateSync) onMainTrieFinished() error {
t.codeSyncer.notifyAccountTrieCompleted()
t.codeFetcher.Finalize()

// count the number of storage tries we need to sync for eta purposes.
numStorageTries, err := t.trieQueue.countTries()
Expand Down Expand Up @@ -255,7 +260,14 @@ func (t *stateSync) storageTrieProducer(ctx context.Context) error {
}

func (t *stateSync) Sync(ctx context.Context) error {
// Start the code syncer and leaf syncer.
// Wait for the code fetcher to be ready before starting.
select {
case <-t.codeFetcher.Ready():
case <-ctx.Done():
return ctx.Err()
}

// Start the leaf syncer and storage trie producer.
eg, egCtx := errgroup.WithContext(ctx)

eg.Go(func() error {
Expand All @@ -264,9 +276,7 @@ func (t *stateSync) Sync(ctx context.Context) error {
}
return t.onSyncComplete()
})
eg.Go(func() error {
return t.codeSyncer.Sync(egCtx)
})
// Note: code syncer is no longer started here. It should be run by the [SyncerRegistry] and registered separately.
eg.Go(func() error {
return t.storageTrieProducer(egCtx)
})
Expand Down
15 changes: 12 additions & 3 deletions sync/statesync/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/ava-labs/libevm/trie"
"github.com/ava-labs/libevm/triedb"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"

"github.com/ava-labs/coreth/core/state/snapshot"
"github.com/ava-labs/coreth/plugin/evm/customrawdb"
Expand Down Expand Up @@ -57,13 +58,21 @@ func testSync(t *testing.T, test syncTest) {
mockClient.GetLeafsIntercept = test.GetLeafsIntercept
mockClient.GetCodeIntercept = test.GetCodeIntercept

s, err := NewSyncer(mockClient, clientDB, root, Config{
cfg := Config{
BatchSize: 1000, // Use a lower batch size in order to get test coverage of batches being written early.
RequestSize: testRequestSize,
})
}
codeSyncer, err := NewCodeSyncer(mockClient, clientDB, cfg)
require.NoError(t, err, "failed to create code syncer")
stateSyncer, err := NewSyncer(mockClient, clientDB, root, codeSyncer, cfg)
require.NoError(t, err, "failed to create state syncer")

err = s.Sync(ctx)
// Run both syncers concurrently and wait for the first error.
eg, egCtx := errgroup.WithContext(ctx)
eg.Go(func() error { return codeSyncer.Sync(egCtx) })
eg.Go(func() error { return stateSyncer.Sync(egCtx) })

err = eg.Wait()
require.ErrorIs(t, err, test.expectedError, "unexpected error during sync")

// Only assert database consistency if the sync was expected to succeed.
Expand Down
4 changes: 2 additions & 2 deletions sync/statesync/trie_sync_tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ func (m *mainTrieTask) OnLeafs(db ethdb.KeyValueWriter, keys, vals [][]byte) err
codeHashes = append(codeHashes, codeHash)
}
}
// Add collected code hashes to the code syncer.
return m.sync.codeSyncer.AddCode(codeHashes)
// Add collected code hashes to the code fetcher.
return m.sync.codeFetcher.AddCode(codeHashes)
}

type storageTrieTask struct {
Expand Down
Loading
Loading