From a05e4c99bbcfd5f6f6e37b4222616e40b31cfbaf Mon Sep 17 00:00:00 2001 From: David Date: Fri, 10 Jan 2025 14:55:34 +0800 Subject: [PATCH] feat(taiko-client): only check and trigger P2P sync progress right after starting (#18745) --- .../driver/chain_syncer/chain_syncer.go | 35 +++++++++++++------ .../taiko-client/driver/state/l1_current.go | 13 +++---- packages/taiko-client/pkg/rpc/methods.go | 8 +++-- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/packages/taiko-client/driver/chain_syncer/chain_syncer.go b/packages/taiko-client/driver/chain_syncer/chain_syncer.go index 5402b5766f6..15c6cd69c8a 100644 --- a/packages/taiko-client/driver/chain_syncer/chain_syncer.go +++ b/packages/taiko-client/driver/chain_syncer/chain_syncer.go @@ -88,6 +88,7 @@ func (s *L2ChainSyncer) Sync() error { if err != nil { return err } + // If current L2 execution engine's chain is behind of the block head to sync, and the // `P2PSync` flag is set, try triggering a beacon sync in L2 execution engine to catch up the // head. @@ -99,6 +100,10 @@ func (s *L2ChainSyncer) Sync() error { return nil } + // Mark the beacon sync progress as finished, To make sure that + // we will only check and trigger P2P sync progress once right after the driver starts + s.progressTracker.MarkFinished() + // We have triggered at least a beacon sync in L2 execution engine, we should reset the L1Current // cursor at first, before start inserting pending L2 blocks one by one. if s.progressTracker.Triggered() { @@ -108,26 +113,23 @@ func (s *L2ChainSyncer) Sync() error { "p2pOutOfSync", s.progressTracker.OutOfSync(), ) - // Mark the beacon sync progress as finished. - s.progressTracker.MarkFinished() - // Get the execution engine's chain head. l2Head, err := s.rpc.L2.HeaderByNumber(s.ctx, nil) if err != nil { - return err + return fmt.Errorf("failed to get L2 chain head: %w", err) } log.Info( "L2 head information", "number", l2Head.Number, "hash", l2Head.Hash(), - "lastSyncedVerifiedBlockID", s.progressTracker.LastSyncedBlockID(), - "lastSyncedVerifiedBlockHash", s.progressTracker.LastSyncedBlockHash(), + "lastSyncedBlockID", s.progressTracker.LastSyncedBlockID(), + "lastSyncedBlockHash", s.progressTracker.LastSyncedBlockHash(), ) // Reset the L1Current cursor. if err := s.state.ResetL1Current(s.ctx, l2Head.Number); err != nil { - return err + return fmt.Errorf("failed to reset L1 current cursor: %w", err) } // Reset to the latest L2 execution engine's chain status. @@ -140,7 +142,7 @@ func (s *L2ChainSyncer) Sync() error { // AheadOfHeadToSync checks whether the L2 chain is ahead of the head to sync in protocol. func (s *L2ChainSyncer) AheadOfHeadToSync(heightToSync uint64) bool { - log.Debug( + log.Info( "Checking whether the execution engine is ahead of the head to sync", "heightToSync", heightToSync, "executionEngineHead", s.state.GetL2Head().Number, @@ -156,12 +158,23 @@ func (s *L2ChainSyncer) AheadOfHeadToSync(heightToSync uint64) bool { // If the L2 execution engine's chain is behind of the block head to sync, // we should keep the beacon sync. if s.state.GetL2Head().Number.Uint64() < heightToSync { + log.Info( + "L2 execution engine is behind of the head to sync", + "heightToSync", heightToSync, + "executionEngineHead", s.state.GetL2Head().Number, + ) return false } // If the L2 execution engine's chain is ahead of the block head to sync, // we can mark the beacon sync progress as finished. if s.progressTracker.LastSyncedBlockID() != nil { + log.Info( + "L2 execution engine is ahead of the head to sync", + "heightToSync", heightToSync, + "executionEngineHead", s.state.GetL2Head().Number, + "lastSyncedBlockID", s.progressTracker.LastSyncedBlockID(), + ) return s.state.GetL2Head().Number.Uint64() >= s.progressTracker.LastSyncedBlockID().Uint64() } @@ -170,9 +183,9 @@ func (s *L2ChainSyncer) AheadOfHeadToSync(heightToSync uint64) bool { // needNewBeaconSyncTriggered checks whether the current L2 execution engine needs to trigger // another new beacon sync, the following conditions should be met: -// 1. The `P2PSync` flag is set. -// 2. The protocol's latest verified block head is not zero. -// 3. The L2 execution engine's chain is behind of the protocol's latest verified block head. +// 1. The `--p2p.sync` flag is set. +// 2. The protocol's (last verified) block head is not zero. +// 3. The L2 execution engine's chain is behind of the protocol's (latest verified) block head. // 4. The L2 execution engine's chain has met a sync timeout issue. func (s *L2ChainSyncer) needNewBeaconSyncTriggered() (uint64, bool, error) { // If the flag is not set or there was a finished beacon sync, we simply return false. diff --git a/packages/taiko-client/driver/state/l1_current.go b/packages/taiko-client/driver/state/l1_current.go index 01f038387d4..597635b9710 100644 --- a/packages/taiko-client/driver/state/l1_current.go +++ b/packages/taiko-client/driver/state/l1_current.go @@ -3,6 +3,7 @@ package state import ( "context" "errors" + "fmt" "math/big" "github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings" @@ -38,6 +39,7 @@ func (s *State) ResetL1Current(ctx context.Context, blockID *big.Int) error { // If blockID is zero, reset to genesis L1 height. if blockID.Cmp(common.Big0) == 0 { + log.Info("Reset L1 current cursor to genesis L1 height", "blockID", blockID) l1Current, err := s.rpc.L1.HeaderByNumber(ctx, s.GenesisL1Height) if err != nil { return err @@ -51,17 +53,12 @@ func (s *State) ResetL1Current(ctx context.Context, blockID *big.Int) error { blockInfo bindings.TaikoDataBlockV2 err error ) - if s.IsOnTake(blockID) { - blockInfo, err = s.rpc.GetL2BlockInfoV2(ctx, blockID) - } else { - blockInfo, err = s.rpc.GetL2BlockInfo(ctx, blockID) - } - if err != nil { - return err + if blockInfo, err = s.rpc.GetL2BlockInfoV2(ctx, blockID); err != nil { + return fmt.Errorf("failed to get L2 block (%d) info from TaikoL1 contract: %w", blockID, err) } l1Current, err := s.rpc.L1.HeaderByNumber(ctx, new(big.Int).SetUint64(blockInfo.ProposedIn)) if err != nil { - return err + return fmt.Errorf("failed to fetch L1 header by number (%d): %w", blockID, err) } s.SetL1Current(l1Current) diff --git a/packages/taiko-client/pkg/rpc/methods.go b/packages/taiko-client/pkg/rpc/methods.go index ee267d1ff43..dd3949b8fb6 100644 --- a/packages/taiko-client/pkg/rpc/methods.go +++ b/packages/taiko-client/pkg/rpc/methods.go @@ -672,10 +672,12 @@ func (c *Client) checkSyncedL1SnippetFromAnchor( log.Debug("Check synced L1 snippet from anchor", "blockID", blockID, "l1Height", l1Height) block, err := c.L2.BlockByNumber(ctx, blockID) if err != nil { + log.Error("Failed to fetch L2 block", "blockID", blockID, "error", err) return false, err } parent, err := c.L2.BlockByHash(ctx, block.ParentHash()) if err != nil { + log.Error("Failed to fetch L2 parent block", "blockID", blockID, "parentHash", block.ParentHash(), "error", err) return false, err } @@ -683,6 +685,7 @@ func (c *Client) checkSyncedL1SnippetFromAnchor( block.Transactions()[0], ) if err != nil { + log.Error("Failed to parse L1 snippet from anchor transaction", "blockID", blockID, "error", err) return false, err } @@ -698,6 +701,7 @@ func (c *Client) checkSyncedL1SnippetFromAnchor( l1Header, err := c.L1.HeaderByNumber(ctx, new(big.Int).SetUint64(l1HeightInAnchor)) if err != nil { + log.Error("Failed to fetch L1 header", "blockID", blockID, "error", err) return false, err } @@ -725,7 +729,7 @@ func (c *Client) getSyncedL1SnippetFromAnchor( ) { method, err := encoding.TaikoL2ABI.MethodById(tx.Data()) if err != nil { - return common.Hash{}, 0, 0, err + return common.Hash{}, 0, 0, fmt.Errorf("failed to get TaikoL2.Anchor method by ID: %w", err) } var ok bool @@ -734,7 +738,7 @@ func (c *Client) getSyncedL1SnippetFromAnchor( args := map[string]interface{}{} if err := method.Inputs.UnpackIntoMap(args, tx.Data()[4:]); err != nil { - return common.Hash{}, 0, 0, err + return common.Hash{}, 0, 0, fmt.Errorf("failed to unpack anchor transaction calldata: %w", err) } l1StateRoot, ok = args["_l1StateRoot"].([32]byte)