Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(taiko-client): only check and trigger P2P sync progress right after starting #18745

Merged
merged 5 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
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
Loading