-
Notifications
You must be signed in to change notification settings - Fork 838
feat(statesync): introduce Finalizer interface for syncer cleanup #4623
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
base: master
Are you sure you want to change the base?
Changes from all commits
a19bd5e
746ab4b
eaef2ad
cd986bc
e5cbefc
51f258a
7190c80
d3f9869
07546b5
29e2310
ce4f9e7
5796e07
cbd0706
0bde2b9
841ef64
f077d73
58adc19
d9c9720
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import ( | |
| "errors" | ||
| "fmt" | ||
| "sync" | ||
| "sync/atomic" | ||
|
|
||
| "github.com/ava-labs/libevm/common" | ||
| "github.com/ava-labs/libevm/ethdb" | ||
|
|
@@ -59,6 +60,10 @@ type stateSync struct { | |
| storageTriesDone chan struct{} | ||
| triesInProgressSem chan struct{} | ||
| stats *trieSyncStats | ||
|
|
||
| // syncCompleted is set to true when the sync completes successfully. | ||
| // This provides an explicit success signal for Finalize(). | ||
| syncCompleted atomic.Bool | ||
| } | ||
|
|
||
| // SyncerOption configures the state syncer via functional options. | ||
|
|
@@ -106,7 +111,6 @@ func NewSyncer(client syncclient.Client, db ethdb.Database, root common.Hash, co | |
| ss.syncer = syncclient.NewCallbackLeafSyncer(client, ss.segments, &syncclient.LeafSyncerConfig{ | ||
| RequestSize: leafsRequestSize, | ||
| NumWorkers: defaultNumWorkers, | ||
| OnFailure: ss.onSyncFailure, | ||
| }) | ||
|
|
||
| if codeQueue == nil { | ||
|
|
@@ -214,7 +218,11 @@ func (t *stateSync) onMainTrieFinished() error { | |
| // [mainTrie]'s batch last to avoid persisting the state | ||
| // root before all storage tries are done syncing. | ||
| func (t *stateSync) onSyncComplete() error { | ||
| return t.mainTrie.batch.Write() | ||
| if err := t.mainTrie.batch.Write(); err != nil { | ||
| return err | ||
| } | ||
| t.syncCompleted.Store(true) | ||
| return nil | ||
| } | ||
|
|
||
| // storageTrieProducer waits for the main trie to finish | ||
|
|
@@ -301,19 +309,22 @@ func (t *stateSync) removeTrieInProgress(root common.Hash) (int, error) { | |
| return len(t.triesInProgress), nil | ||
| } | ||
|
|
||
| // onSyncFailure is called if the sync fails, this writes all | ||
| // batches of in-progress trie segments to disk to have maximum | ||
| // progress to restore. | ||
| func (t *stateSync) onSyncFailure() { | ||
| // Finalize flushes in-progress trie batches to disk to preserve progress on failure. | ||
| func (t *stateSync) Finalize() error { | ||
| if t.syncCompleted.Load() { | ||
| return nil | ||
| } | ||
|
|
||
| t.lock.RLock() | ||
| defer t.lock.RUnlock() | ||
|
|
||
| for _, trie := range t.triesInProgress { | ||
| for _, segment := range trie.segments { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (could be an over-cautious comment)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. check my previous reply #4623 (comment) |
||
| if err := segment.batch.Write(); err != nil { | ||
| log.Error("failed to write segment batch on sync failure", "err", err) | ||
| return | ||
| log.Error("failed to write segment batch on finalize", "err", err) | ||
| return err | ||
| } | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.