Skip to content
This repository has been archived by the owner on May 11, 2024. It is now read-only.

feat(prover): ensure L2 EE is fully synced when calling initL1Current #170

Merged
merged 2 commits into from
Mar 6, 2023
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
37 changes: 37 additions & 0 deletions pkg/rpc/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package rpc

import (
"context"
"errors"
"fmt"
"math/big"
"time"

"github.com/cenkalti/backoff/v4"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -17,6 +19,14 @@ import (
"golang.org/x/sync/errgroup"
)

var (
// errSyncing is returned when the L2 execution engine is syncing.
errSyncing = errors.New("syncing")
// syncProgressRecheckDelay is the time delay of rechecking the L2 execution engine's sync progress again,
// if the previous check failed.
syncProgressRecheckDelay = 12 * time.Second
)

// ensureGenesisMatched fetches the L2 genesis block from TaikoL1 contract,
// and checks whether the fetched genesis is same to the node local genesis.
func (c *Client) ensureGenesisMatched(ctx context.Context) error {
Expand Down Expand Up @@ -60,6 +70,33 @@ func (c *Client) ensureGenesisMatched(ctx context.Context) error {
return fmt.Errorf("genesis block not found in TaikoL1")
}

// WaitTillL2Synced keeps waiting until the L2 execution engine is fully synced.
func (c *Client) WaitTillL2Synced(ctx context.Context) error {
return backoff.Retry(
func() error {
if ctx.Err() != nil {
return nil
}
progress, err := c.L2ExecutionEngineSyncProgress(ctx)
if err != nil {
log.Error("Fetch L2 execution engine sync progress error", "error", err)
return err
}

if progress.SyncProgress != nil ||
progress.CurrentBlockID == nil ||
progress.HighestBlockID == nil ||
progress.CurrentBlockID.Cmp(progress.HighestBlockID) < 0 {
log.Info("L2 execution engine is syncing", "progress", progress)
return errSyncing
}

return nil
},
backoff.NewConstantBackOff(syncProgressRecheckDelay),
)
}

// LatestL2KnownL1Header fetches the L2 execution engine's latest known L1 header.
func (c *Client) LatestL2KnownL1Header(ctx context.Context) (*types.Header, error) {
headL1Origin, err := c.L2.HeadL1Origin(ctx)
Expand Down
39 changes: 1 addition & 38 deletions proposer/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package proposer
import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
"math/rand"
"sync"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
Expand All @@ -25,14 +23,6 @@ import (
"github.com/urfave/cli/v2"
)

var (
// errSyncing is returned when the L2 execution engine is syncing.
errSyncing = errors.New("syncing")
// syncProgressRecheckDelay is the time delay of rechecking the L2 execution engine's sync progress again,
// if the previous check failed.
syncProgressRecheckDelay = 12 * time.Second
)

// Proposer keep proposing new transactions from L2 execution engine's tx pool at a fixed interval.
type Proposer struct {
// RPC clients
Expand Down Expand Up @@ -146,7 +136,7 @@ func (p *Proposer) ProposeOp(ctx context.Context) error {
}

// Wait until L2 execution engine is synced at first.
if err := p.waitTillSynced(ctx); err != nil {
if err := p.rpc.WaitTillL2Synced(ctx); err != nil {
return fmt.Errorf("failed to wait until L2 execution engine synced: %w", err)
}

Expand Down Expand Up @@ -310,33 +300,6 @@ func (p *Proposer) ProposeTxList(
return nil
}

// waitTillSynced keeps waiting until the L2 execution engine is fully synced.
func (p *Proposer) waitTillSynced(ctx context.Context) error {
return backoff.Retry(
func() error {
if ctx.Err() != nil {
return nil
}
progress, err := p.rpc.L2ExecutionEngineSyncProgress(p.ctx)
if err != nil {
log.Error("Fetch L2 execution engine sync progress error", "error", err)
return err
}

if progress.SyncProgress != nil ||
progress.CurrentBlockID == nil ||
progress.HighestBlockID == nil ||
progress.CurrentBlockID.Cmp(progress.HighestBlockID) < 0 {
log.Info("L2 execution engine is syncing", "progress", progress)
return errSyncing
}

return nil
},
backoff.NewConstantBackOff(syncProgressRecheckDelay),
)
}

// updateProposingTicker updates the internal proposing timer.
func (p *Proposer) updateProposingTicker() {
if p.proposingTimer != nil {
Expand Down
4 changes: 4 additions & 0 deletions prover/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,10 @@ func (p *Prover) Name() string {

// initL1Current initializes prover's L1Current cursor.
func (p *Prover) initL1Current(startingBlockID *big.Int) error {
if err := p.rpc.WaitTillL2Synced(p.ctx); err != nil {
return err
}

if startingBlockID == nil {
stateVars, err := p.rpc.GetProtocolStateVariables(nil)
if err != nil {
Expand Down