diff --git a/driver/chain_syncer/beaconsync/syncer.go b/driver/chain_syncer/beaconsync/syncer.go index f955e54f6..c9f85893a 100644 --- a/driver/chain_syncer/beaconsync/syncer.go +++ b/driver/chain_syncer/beaconsync/syncer.go @@ -52,19 +52,6 @@ func (s *Syncer) TriggerBeaconSync() error { ) } - // Keep the heartbeat with L2 execution engine. - fcRes, err := s.rpc.L2Engine.ForkchoiceUpdate(s.ctx, &engine.ForkchoiceStateV1{ - HeadBlockHash: s.progressTracker.LastSyncedVerifiedBlockHash(), - SafeBlockHash: s.progressTracker.LastSyncedVerifiedBlockHash(), - FinalizedBlockHash: s.progressTracker.LastSyncedVerifiedBlockHash(), - }, nil) - if err != nil { - return err - } - if fcRes.PayloadStatus.Status != engine.SYNCING { - return fmt.Errorf("unexpected ForkchoiceUpdate response status: %s", fcRes.PayloadStatus.Status) - } - return nil } @@ -109,19 +96,6 @@ func (s *Syncer) TriggerBeaconSync() error { return nil } -func (s *Syncer) Synced() (bool, error) { - if !s.progressTracker.Triggered() { - return false, nil - } - heightToSync := s.progressTracker.LastSyncedVerifiedBlockHeight() - l2Head, err := s.rpc.L2.BlockNumber(s.ctx) - if err != nil { - return false, err - } - log.Debug("Check if the L2 execution engine is synced", "heightToSync", heightToSync, "l2Head", l2Head) - return new(big.Int).SetUint64(l2Head).Cmp(heightToSync) >= 0, nil -} - // 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 to start beacon syncing. func (s *Syncer) getVerifiedBlockPayload(ctx context.Context) (*big.Int, *engine.ExecutableData, error) { diff --git a/driver/chain_syncer/chain_syncer.go b/driver/chain_syncer/chain_syncer.go index 14cf8a8e3..92764acab 100644 --- a/driver/chain_syncer/chain_syncer.go +++ b/driver/chain_syncer/chain_syncer.go @@ -67,12 +67,7 @@ func (s *L2ChainSyncer) Sync(l1End *types.Header) error { // If current L2 execution engine's chain is behind of the protocol's latest verified block head, and the // `P2PSyncVerifiedBlocks` flag is set, try triggering a beacon sync in L2 execution engine to catch up the // latest verified block head. - needBeaconSyncTriggered, err := s.needNewBeaconSyncTriggered() - if err != nil { - return err - } - - if needBeaconSyncTriggered { + if s.needNewBeaconSyncTriggered() { if err := s.beaconSyncer.TriggerBeaconSync(); err != nil { return fmt.Errorf("trigger beacon sync error: %w", err) } @@ -124,17 +119,40 @@ func (s *L2ChainSyncer) Sync(l1End *types.Header) error { return s.calldataSyncer.ProcessL1Blocks(s.ctx, l1End) } +// AheadOfProtocolVerifiedHead checks whether the L2 chain is ahead of verified head in protocol. +func (s *L2ChainSyncer) AheadOfProtocolVerifiedHead() bool { + verifiedHeightToCompare := s.state.GetLatestVerifiedBlock().Height.Uint64() + log.Debug( + "Checking whether the execution engine is ahead of protocol's verified head", + "latestVerifiedBlock", verifiedHeightToCompare, + "executionEngineHead", s.state.GetL2Head().Number, + ) + if verifiedHeightToCompare > 0 { + // If latest verified head height is equal to L2 execution engine's synced head height minus one, + // we also mark the triggered P2P sync progress as finished to prevent a potential `InsertBlockWithoutSetHead` in + // execution engine, which may cause errors since we do not pass all transactions in ExecutePayload when calling + // NewPayloadV1. + verifiedHeightToCompare -= 1 + } + + if s.state.GetL2Head().Number.Uint64() < verifiedHeightToCompare { + return false + } + + if s.progressTracker.LastSyncedVerifiedBlockHeight() != nil { + return s.state.GetL2Head().Number.Uint64() >= s.progressTracker.LastSyncedVerifiedBlockHeight().Uint64() + } + + return true +} + // needNewBeaconSyncTriggered checks whether the current L2 execution engine needs to trigger // another new beacon sync. -func (s *L2ChainSyncer) needNewBeaconSyncTriggered() (bool, error) { - synced, err := s.BeaconSyncer().Synced() - if err != nil { - return false, err - } +func (s *L2ChainSyncer) needNewBeaconSyncTriggered() bool { return s.p2pSyncVerifiedBlocks && s.state.GetLatestVerifiedBlock().Height.Uint64() > 0 && - !synced && - !s.progressTracker.OutOfSync(), nil + !s.AheadOfProtocolVerifiedHead() && + !s.progressTracker.OutOfSync() } // BeaconSyncer returns the inner beacon syncer. diff --git a/driver/chain_syncer/chain_syncer_test.go b/driver/chain_syncer/chain_syncer_test.go index f439f12bb..e58f5c4f6 100644 --- a/driver/chain_syncer/chain_syncer_test.go +++ b/driver/chain_syncer/chain_syncer_test.go @@ -49,3 +49,7 @@ func (s *ChainSyncerTestSuite) TestSync() { func TestChainSyncerTestSuite(t *testing.T) { suite.Run(t, new(ChainSyncerTestSuite)) } + +func (s *ChainSyncerTestSuite) TestAheadOfProtocolVerifiedHead() { + s.True(s.s.AheadOfProtocolVerifiedHead()) +}