Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
feat(sync): add Finalize method to Syncer interface and integrate int…
…o sync flow

- Add Finalize method to the Syncer interface and implement it across all
syncer types. Integrate Finalize calls into both static and dynamic state
sync flows to allow syncers to clean up their state before VM finalization.
- Dynamic sync: Syncers complete -> Finalize syncers -> Finalize VM -> Execute batch
- Static sync: Syncers complete -> Finalize syncers -> Finalize VM
  • Loading branch information
powerslider committed Dec 3, 2025
commit 74f726ebc1c7077f34ff70fd4caa6c91ea712fc8
4 changes: 4 additions & 0 deletions graft/coreth/plugin/evm/atomic/sync/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ func (*Syncer) UpdateTarget(_ message.Syncable) error {
return nil
}

func (*Syncer) Finalize(_ context.Context) error {
return nil
}

// addZeroes returns the big-endian representation of `height`, prefixed with [common.HashLength] zeroes.
func addZeroes(height uint64) []byte {
// Key format is [height(8 bytes)][blockchainID(32 bytes)]. Start should be the
Expand Down
6 changes: 5 additions & 1 deletion graft/coreth/plugin/evm/vmsync/coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ func (co *Coordinator) Start(ctx context.Context, initial message.Syncable) {
co.finish(cancel, err)
return
}
// All syncers finished successfully: finalize VM and execute the queued batch.
// All syncers finished successfully: finalize syncers, then finalize VM and execute the queued batch.
if err := co.syncerRegistry.FinalizeAll(cctx); err != nil {
co.finish(cancel, err)
return
}
if err := co.ProcessQueuedBlockOperations(cctx); err != nil {
co.finish(cancel, err)
return
Expand Down
1 change: 1 addition & 0 deletions graft/coreth/plugin/evm/vmsync/doubles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func (f FuncSyncer) Sync(ctx context.Context) error { return f.fn(ctx) }
func (FuncSyncer) Name() string { return "Test Name" }
func (FuncSyncer) ID() string { return "test_id" }
func (FuncSyncer) UpdateTarget(_ message.Syncable) error { return nil }
func (FuncSyncer) Finalize(_ context.Context) error { return nil }

var _ syncpkg.Syncer = FuncSyncer{}

Expand Down
14 changes: 14 additions & 0 deletions graft/coreth/plugin/evm/vmsync/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,17 @@ func (r *SyncerRegistry) UpdateSyncTarget(newTarget message.Syncable) error {
}
return nil
}

// FinalizeAll calls Finalize on all registered syncers.
// This should be called after all syncers have completed their Sync() operations
// and before finalizing the VM state.
func (r *SyncerRegistry) FinalizeAll(ctx context.Context) error {
for _, task := range r.syncers {
if err := task.syncer.Finalize(ctx); err != nil {
log.Error("failed finalizing syncer", "name", task.name, "err", err)
return fmt.Errorf("%s finalize failed: %w", task.name, err)
}
log.Info("finalized syncer", "name", task.name)
}
return nil
}
5 changes: 5 additions & 0 deletions graft/coreth/plugin/evm/vmsync/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func (m *mockSyncer) Sync(context.Context) error {
func (m *mockSyncer) Name() string { return m.name }
func (m *mockSyncer) ID() string { return m.name }
func (*mockSyncer) UpdateTarget(_ message.Syncable) error { return nil }
func (*mockSyncer) Finalize(_ context.Context) error { return nil }

// namedSyncer adapts an existing syncer with a provided name to satisfy Syncer with Name().
type namedSyncer struct {
Expand All @@ -55,6 +56,10 @@ func (n *namedSyncer) UpdateTarget(newTarget message.Syncable) error {
return n.syncer.UpdateTarget(newTarget)
}

func (n *namedSyncer) Finalize(ctx context.Context) error {
return n.syncer.Finalize(ctx)
}

// syncerConfig describes a test syncer setup for RunSyncerTasks table tests.
type syncerConfig struct {
name string
Expand Down
4 changes: 4 additions & 0 deletions graft/coreth/sync/blocksync/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,7 @@ func (s *BlockSyncer) Sync(ctx context.Context) error {
func (*BlockSyncer) UpdateTarget(_ message.Syncable) error {
return nil
}

func (*BlockSyncer) Finalize(_ context.Context) error {
return nil
}
4 changes: 4 additions & 0 deletions graft/coreth/sync/statesync/code_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ func (*CodeSyncer) UpdateTarget(_ message.Syncable) error {
return nil
}

func (*CodeSyncer) Finalize(_ context.Context) error {
return nil
}

// 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 {
Expand Down
4 changes: 4 additions & 0 deletions graft/coreth/sync/statesync/state_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ func (*stateSync) UpdateTarget(_ message.Syncable) error {
return nil
}

func (*stateSync) Finalize(_ context.Context) error {
return nil
}

// onStorageTrieFinished is called after a storage trie finishes syncing.
func (t *stateSync) onStorageTrieFinished(root common.Hash) error {
<-t.triesInProgressSem // allow another trie to start (release the semaphore)
Expand Down
3 changes: 3 additions & 0 deletions graft/coreth/sync/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type Syncer interface {

// UpdateTarget updates the syncer's target while running to support dynamic state sync.
UpdateTarget(newTarget message.Syncable) error

// Finalize is called when the syncer is finished.
Finalize(ctx context.Context) error
}

// SummaryProvider is an interface for providing state summaries.
Expand Down