From 975146cf60d0397a9e8d0209abfc375757a854d3 Mon Sep 17 00:00:00 2001 From: maskpp Date: Mon, 20 May 2024 15:57:18 +0800 Subject: [PATCH 1/7] fix driver p2p sync --- .../beaconsync/progress_tracker.go | 28 +++++++++++++++++++ .../driver/chain_syncer/beaconsync/syncer.go | 6 ++++ 2 files changed, 34 insertions(+) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go index d86e47408bf..d2e376e14c1 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go @@ -29,6 +29,9 @@ type SyncProgressTracker struct { lastSyncedBlockID *big.Int lastSyncedBlockHash common.Hash + // Sync block ID + syncBlockID *big.Int + // Out-of-sync check related lastSyncProgress *ethereum.SyncProgress lastProgressedTime time.Time @@ -133,6 +136,31 @@ func (t *SyncProgressTracker) track(ctx context.Context) { } } +// ShouldReSync checks whether a re-sync is needed. +func (t *SyncProgressTracker) ShouldReSync(id *big.Int) (uint64, bool) { + // Sync block ID is nil or reorg appears, re-sync from the latest known block. + if t.syncBlockID == nil || t.syncBlockID.Cmp(id) > 0 { + t.syncBlockID = new(big.Int).Set(id) + return t.syncBlockID.Uint64(), true + } + + // Latest id is the same as the current one, no need to re-sync + if t.syncBlockID.Cmp(id) == 0 { + return 0, false + } + + _, err := t.client.BlockByNumber(context.Background(), t.syncBlockID) + if err != nil { + if err.Error() != "not found" { + log.Error("block not found when check should re-sync or not", "blockID", t.syncBlockID.Uint64(), "error", err) + } + return 0, false + } + t.syncBlockID = new(big.Int).Set(id) + + return t.syncBlockID.Uint64(), true +} + // UpdateMeta updates the inner beacon sync metadata. func (t *SyncProgressTracker) UpdateMeta(id *big.Int, blockHash common.Hash) { t.mutex.Lock() diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go index d593d868be2..9f0dc990ca7 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -39,6 +39,12 @@ func NewSyncer( // TriggerBeaconSync triggers the L2 execution engine to start performing a beacon sync, if the // latest verified block has changed. func (s *Syncer) TriggerBeaconSync(blockID uint64) error { + var shouldSync bool + blockID, shouldSync = s.progressTracker.ShouldReSync(new(big.Int).SetUint64(blockID)) + if !shouldSync { + return nil + } + latestVerifiedHeadPayload, err := s.getVerifiedBlockPayload(s.ctx, blockID) if err != nil { return err From 12148416c701153e73ab29da657a020985a38934 Mon Sep 17 00:00:00 2001 From: maskpp Date: Mon, 20 May 2024 17:22:27 +0800 Subject: [PATCH 2/7] check syncBlockID equal to verifyBlockID --- .../beaconsync/progress_tracker.go | 2 +- .../driver/chain_syncer/beaconsync/syncer.go | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go index d2e376e14c1..068a87a201b 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go @@ -149,7 +149,7 @@ func (t *SyncProgressTracker) ShouldReSync(id *big.Int) (uint64, bool) { return 0, false } - _, err := t.client.BlockByNumber(context.Background(), t.syncBlockID) + _, err := t.client.HeaderByNumber(context.Background(), t.syncBlockID) if err != nil { if err.Error() != "not found" { log.Error("block not found when check should re-sync or not", "blockID", t.syncBlockID.Uint64(), "error", err) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go index 9f0dc990ca7..eca3a9881f0 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -38,20 +38,19 @@ func NewSyncer( // TriggerBeaconSync triggers the L2 execution engine to start performing a beacon sync, if the // latest verified block has changed. -func (s *Syncer) TriggerBeaconSync(blockID uint64) error { - var shouldSync bool - blockID, shouldSync = s.progressTracker.ShouldReSync(new(big.Int).SetUint64(blockID)) +func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { + syncBlockID, shouldSync := s.progressTracker.ShouldReSync(new(big.Int).SetUint64(verifyBlockID)) if !shouldSync { return nil } - latestVerifiedHeadPayload, err := s.getVerifiedBlockPayload(s.ctx, blockID) + latestVerifiedHeadPayload, err := s.getVerifiedBlockPayload(s.ctx, syncBlockID, verifyBlockID) if err != nil { return err } - if !s.progressTracker.HeadChanged(new(big.Int).SetUint64(blockID)) { - log.Debug("Verified head has not changed", "blockID", blockID, "hash", latestVerifiedHeadPayload.BlockHash) + if !s.progressTracker.HeadChanged(new(big.Int).SetUint64(syncBlockID)) { + log.Debug("Verified head has not changed", "blockID", syncBlockID, "hash", latestVerifiedHeadPayload.BlockHash) return nil } @@ -60,7 +59,7 @@ func (s *Syncer) TriggerBeaconSync(blockID uint64) error { log.Info( "Syncing beacon headers, please check L2 execution engine logs for progress", "currentSyncHead", s.progressTracker.LastSyncedBlockID(), - "newBlockID", blockID, + "newBlockID", syncBlockID, ) } } @@ -87,11 +86,11 @@ func (s *Syncer) TriggerBeaconSync(blockID uint64) error { } // Update sync status. - s.progressTracker.UpdateMeta(new(big.Int).SetUint64(blockID), latestVerifiedHeadPayload.BlockHash) + s.progressTracker.UpdateMeta(new(big.Int).SetUint64(syncBlockID), latestVerifiedHeadPayload.BlockHash) log.Info( "⛓️ Beacon sync triggered", - "newHeadID", blockID, + "newHeadID", syncBlockID, "newHeadHash", s.progressTracker.LastSyncedBlockHash(), ) @@ -100,14 +99,15 @@ func (s *Syncer) TriggerBeaconSync(blockID uint64) error { // getVerifiedBlockPayload fetches the latest verified block's header, and converts it to an Engine API executable data, // which will be used to let the node start beacon syncing. -func (s *Syncer) getVerifiedBlockPayload(ctx context.Context, blockID uint64) (*engine.ExecutableData, error) { - header, err := s.rpc.L2CheckPoint.HeaderByNumber(s.ctx, new(big.Int).SetUint64(blockID)) +func (s *Syncer) getVerifiedBlockPayload(ctx context.Context, syncBlockID, verifyBlockID uint64) (*engine.ExecutableData, error) { + header, err := s.rpc.L2CheckPoint.HeaderByNumber(s.ctx, new(big.Int).SetUint64(syncBlockID)) if err != nil { return nil, err } - if s.syncMode == downloader.FullSync.String() { - blockInfo, err := s.rpc.GetL2BlockInfo(ctx, new(big.Int).SetUint64(blockID)) + // check block hash if the sync mode is full sync and the latest verified block is the same as the block we are trying to sync. + if s.syncMode == downloader.FullSync.String() && verifyBlockID == syncBlockID { + blockInfo, err := s.rpc.GetL2BlockInfo(ctx, new(big.Int).SetUint64(syncBlockID)) if err != nil { return nil, err } From cb76d40350458fa8be131798a50d83b912bdd404 Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 21 May 2024 09:24:24 +0800 Subject: [PATCH 3/7] fix go lint --- .../driver/chain_syncer/beaconsync/syncer.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go index cf3bfb1b371..3681224fd46 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -99,13 +99,18 @@ func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { // getVerifiedBlockPayload fetches the latest verified block's header, and converts it to an Engine API executable data, // which will be used to let the node start beacon syncing. -func (s *Syncer) getVerifiedBlockPayload(ctx context.Context, syncBlockID, verifyBlockID uint64) (*engine.ExecutableData, error) { +func (s *Syncer) getVerifiedBlockPayload( + ctx context.Context, + syncBlockID, + verifyBlockID uint64, +) (*engine.ExecutableData, error) { header, err := s.rpc.L2CheckPoint.HeaderByNumber(s.ctx, new(big.Int).SetUint64(syncBlockID)) if err != nil { return nil, err } - // check block hash if the sync mode is full sync and the latest verified block is the same as the block we are trying to sync. + // Check block hash if the sync mode is full sync + // and the latest verified block is the same as the block we are trying to sync. if s.syncMode == downloader.FullSync.String() && verifyBlockID == syncBlockID { blockInfo, err := s.rpc.GetL2BlockInfo(ctx, new(big.Int).SetUint64(syncBlockID)) if err != nil { From 04ce7d76d1604c837f67d29c1660a35723812b60 Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 21 May 2024 11:54:08 +0800 Subject: [PATCH 4/7] trigger again if verify number is ahead more than 32 blocks --- .../beaconsync/progress_tracker.go | 45 ++++++++----------- .../beaconsync/progress_tracker_test.go | 6 --- .../driver/chain_syncer/beaconsync/syncer.go | 9 ++-- 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go index 068a87a201b..616fbe4c9b1 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go @@ -30,7 +30,8 @@ type SyncProgressTracker struct { lastSyncedBlockHash common.Hash // Sync block ID - syncBlockID *big.Int + verifyBlockID *big.Int + syncBlockID *big.Int // Out-of-sync check related lastSyncProgress *ethereum.SyncProgress @@ -137,28 +138,30 @@ func (t *SyncProgressTracker) track(ctx context.Context) { } // ShouldReSync checks whether a re-sync is needed. -func (t *SyncProgressTracker) ShouldReSync(id *big.Int) (uint64, bool) { +func (t *SyncProgressTracker) ShouldReSync(verifyBlockID *big.Int) (uint64, bool) { + if t.verifyBlockID == nil { + t.verifyBlockID = new(big.Int).Set(verifyBlockID) + } // Sync block ID is nil or reorg appears, re-sync from the latest known block. - if t.syncBlockID == nil || t.syncBlockID.Cmp(id) > 0 { - t.syncBlockID = new(big.Int).Set(id) + if t.syncBlockID == nil || t.syncBlockID.Cmp(verifyBlockID) > 0 { + t.syncBlockID = new(big.Int).Set(verifyBlockID) return t.syncBlockID.Uint64(), true } - // Latest id is the same as the current one, no need to re-sync - if t.syncBlockID.Cmp(id) == 0 { - return 0, false + // Current p2p syncing is finished, set the latest verified block and re-sync again. + lastSyncedBlockID := t.LastSyncedBlockID() + if lastSyncedBlockID != nil && t.syncBlockID.Cmp(lastSyncedBlockID) == 0 { + t.syncBlockID = new(big.Int).Set(verifyBlockID) + return t.syncBlockID.Uint64(), true } - _, err := t.client.HeaderByNumber(context.Background(), t.syncBlockID) - if err != nil { - if err.Error() != "not found" { - log.Error("block not found when check should re-sync or not", "blockID", t.syncBlockID.Uint64(), "error", err) - } - return 0, false + // If the latest verified block is ahead of the current sync block ID 32 blocks, re-sync again. + if t.verifyBlockID.Uint64()+32 <= verifyBlockID.Uint64() { + t.verifyBlockID = new(big.Int).Set(verifyBlockID) + return t.syncBlockID.Uint64(), true } - t.syncBlockID = new(big.Int).Set(id) - return t.syncBlockID.Uint64(), true + return t.syncBlockID.Uint64(), false } // UpdateMeta updates the inner beacon sync metadata. @@ -190,18 +193,6 @@ func (t *SyncProgressTracker) ClearMeta() { t.outOfSync = false } -// HeadChanged checks if a new beacon sync request will be needed. -func (t *SyncProgressTracker) HeadChanged(newID *big.Int) bool { - t.mutex.RLock() - defer t.mutex.RUnlock() - - if !t.triggered { - return true - } - - return t.lastSyncedBlockID != nil && t.lastSyncedBlockID != newID -} - // OutOfSync tells whether the L2 execution engine is marked as out of sync. func (t *SyncProgressTracker) OutOfSync() bool { t.mutex.RLock() diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go index 084e57c41f7..fe9d5eaa157 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker_test.go @@ -55,12 +55,6 @@ func (s *BeaconSyncProgressTrackerTestSuite) TestClearMeta() { s.False(s.t.triggered) } -func (s *BeaconSyncProgressTrackerTestSuite) TestHeadChanged() { - s.True(s.t.HeadChanged(common.Big256)) - s.t.triggered = true - s.False(s.t.HeadChanged(common.Big256)) -} - func (s *BeaconSyncProgressTrackerTestSuite) TestOutOfSync() { s.False(s.t.OutOfSync()) } diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go index 3681224fd46..ebb19d65133 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -49,11 +49,6 @@ func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { return err } - if !s.progressTracker.HeadChanged(new(big.Int).SetUint64(syncBlockID)) { - log.Debug("Verified head has not changed", "blockID", syncBlockID, "hash", latestVerifiedHeadPayload.BlockHash) - return nil - } - if s.progressTracker.Triggered() { if s.progressTracker.lastSyncProgress == nil { log.Info( @@ -86,7 +81,9 @@ func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { } // Update sync status. - s.progressTracker.UpdateMeta(new(big.Int).SetUint64(syncBlockID), latestVerifiedHeadPayload.BlockHash) + if fcRes.PayloadStatus.Status == engine.VALID { + s.progressTracker.UpdateMeta(new(big.Int).SetUint64(syncBlockID), latestVerifiedHeadPayload.BlockHash) + } log.Info( "⛓️ Beacon sync triggered", From ab41815d6845ae96b4e27d76781717d063c12c16 Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 21 May 2024 13:29:47 +0800 Subject: [PATCH 5/7] update comments --- .../chain_syncer/beaconsync/progress_tracker.go | 15 ++++++++------- .../driver/chain_syncer/beaconsync/syncer.go | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go index 616fbe4c9b1..faa909907c4 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/progress_tracker.go @@ -29,9 +29,10 @@ type SyncProgressTracker struct { lastSyncedBlockID *big.Int lastSyncedBlockHash common.Hash - // Sync block ID + // latest verified block ID. verifyBlockID *big.Int - syncBlockID *big.Int + // current syncing block ID. + syncBlockID *big.Int // Out-of-sync check related lastSyncProgress *ethereum.SyncProgress @@ -137,25 +138,25 @@ func (t *SyncProgressTracker) track(ctx context.Context) { } } -// ShouldReSync checks whether a re-sync is needed. -func (t *SyncProgressTracker) ShouldReSync(verifyBlockID *big.Int) (uint64, bool) { +// ShouldSync checks whether sync is needed. +func (t *SyncProgressTracker) ShouldSync(verifyBlockID *big.Int) (uint64, bool) { if t.verifyBlockID == nil { t.verifyBlockID = new(big.Int).Set(verifyBlockID) } - // Sync block ID is nil or reorg appears, re-sync from the latest known block. + // If sync blockID is null or the new verifyBlockID is ahead of the current sync block ID, sync again. if t.syncBlockID == nil || t.syncBlockID.Cmp(verifyBlockID) > 0 { t.syncBlockID = new(big.Int).Set(verifyBlockID) return t.syncBlockID.Uint64(), true } - // Current p2p syncing is finished, set the latest verified block and re-sync again. + // This check means that the current syncing work is finished syncing, update syncBlockID and sync again. lastSyncedBlockID := t.LastSyncedBlockID() if lastSyncedBlockID != nil && t.syncBlockID.Cmp(lastSyncedBlockID) == 0 { t.syncBlockID = new(big.Int).Set(verifyBlockID) return t.syncBlockID.Uint64(), true } - // If the latest verified block is ahead of the current sync block ID 32 blocks, re-sync again. + // If the latest verified block is ahead of the current sync block ID 32 blocks, trigger the current syncing again. if t.verifyBlockID.Uint64()+32 <= verifyBlockID.Uint64() { t.verifyBlockID = new(big.Int).Set(verifyBlockID) return t.syncBlockID.Uint64(), true diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go index ebb19d65133..9b68736ebe5 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -39,7 +39,7 @@ func NewSyncer( // TriggerBeaconSync triggers the L2 execution engine to start performing a beacon sync, if the // latest verified block has changed. func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { - syncBlockID, shouldSync := s.progressTracker.ShouldReSync(new(big.Int).SetUint64(verifyBlockID)) + syncBlockID, shouldSync := s.progressTracker.ShouldSync(new(big.Int).SetUint64(verifyBlockID)) if !shouldSync { return nil } @@ -80,8 +80,8 @@ func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { return fmt.Errorf("unexpected ForkchoiceUpdate response status: %s", fcRes.PayloadStatus.Status) } - // Update sync status. - if fcRes.PayloadStatus.Status == engine.VALID { + // If the beacon sync is not in progress, update the sync progress. + if fcRes.PayloadStatus.Status != engine.SYNCING { s.progressTracker.UpdateMeta(new(big.Int).SetUint64(syncBlockID), latestVerifiedHeadPayload.BlockHash) } From e91db57d9ca230a5490a30f56663360ed52c96eb Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 21 May 2024 13:31:46 +0800 Subject: [PATCH 6/7] update check --- packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go index 9b68736ebe5..50b759dfb8a 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -81,7 +81,7 @@ func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { } // If the beacon sync is not in progress, update the sync progress. - if fcRes.PayloadStatus.Status != engine.SYNCING { + if fcRes.PayloadStatus.Status == engine.VALID { s.progressTracker.UpdateMeta(new(big.Int).SetUint64(syncBlockID), latestVerifiedHeadPayload.BlockHash) } From 13412de49634929ccc3dc0953fb0d7cef48b3bc7 Mon Sep 17 00:00:00 2001 From: maskpp Date: Tue, 21 May 2024 16:15:44 +0800 Subject: [PATCH 7/7] update latest blockID depends on p2p sync status --- packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go index 50b759dfb8a..9b68736ebe5 100644 --- a/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go +++ b/packages/taiko-client/driver/chain_syncer/beaconsync/syncer.go @@ -81,7 +81,7 @@ func (s *Syncer) TriggerBeaconSync(verifyBlockID uint64) error { } // If the beacon sync is not in progress, update the sync progress. - if fcRes.PayloadStatus.Status == engine.VALID { + if fcRes.PayloadStatus.Status != engine.SYNCING { s.progressTracker.UpdateMeta(new(big.Int).SetUint64(syncBlockID), latestVerifiedHeadPayload.BlockHash) }