Skip to content

Commit

Permalink
feat(taiko-client): only check and trigger P2P sync progress right af…
Browse files Browse the repository at this point in the history
…ter starting (#18745)
  • Loading branch information
davidtaikocha authored Jan 10, 2025
1 parent 8c364b1 commit a05e4c9
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 21 deletions.
35 changes: 24 additions & 11 deletions packages/taiko-client/driver/chain_syncer/chain_syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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() {
Expand All @@ -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.
Expand All @@ -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,
Expand All @@ -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()
}

Expand All @@ -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.
Expand Down
13 changes: 5 additions & 8 deletions packages/taiko-client/driver/state/l1_current.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package state
import (
"context"
"errors"
"fmt"
"math/big"

"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings"
Expand Down Expand Up @@ -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
Expand All @@ -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)

Expand Down
8 changes: 6 additions & 2 deletions packages/taiko-client/pkg/rpc/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,17 +672,20 @@ 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
}

l1StateRoot, l1HeightInAnchor, parentGasUsed, err := c.getSyncedL1SnippetFromAnchor(
block.Transactions()[0],
)
if err != nil {
log.Error("Failed to parse L1 snippet from anchor transaction", "blockID", blockID, "error", err)
return false, err
}

Expand All @@ -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
}

Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit a05e4c9

Please sign in to comment.