Commit caf41c55 authored by Sam Stokes's avatar Sam Stokes Committed by GitHub

op-proposer: Add option to wait for rollup sync during startup (#10262)

parent 08f3dbed
......@@ -72,6 +72,13 @@ var (
Value: 2 * time.Minute,
EnvVars: prefixEnvVars("ACTIVE_SEQUENCER_CHECK_DURATION"),
}
WaitNodeSyncFlag = &cli.BoolFlag{
Name: "wait-node-sync",
Usage: "Indicates if, during startup, the proposer should wait for the rollup node to sync to " +
"the current L1 tip before proceeding with its driver loop.",
Value: false,
EnvVars: prefixEnvVars("WAIT_NODE_SYNC"),
}
// Legacy Flags
L2OutputHDPathFlag = txmgr.L2OutputHDPathFlag
)
......@@ -90,6 +97,7 @@ var optionalFlags = []cli.Flag{
ProposalIntervalFlag,
DisputeGameTypeFlag,
ActiveSequencerCheckDurationFlag,
WaitNodeSyncFlag,
}
func init() {
......
......@@ -58,6 +58,9 @@ type CLIConfig struct {
// ActiveSequencerCheckDuration is the duration between checks to determine the active sequencer endpoint.
ActiveSequencerCheckDuration time.Duration
// Whether to wait for the sequencer to sync to a recent block at startup.
WaitNodeSync bool
}
func (c *CLIConfig) Check() error {
......@@ -106,5 +109,6 @@ func NewConfig(ctx *cli.Context) *CLIConfig {
ProposalInterval: ctx.Duration(flags.ProposalIntervalFlag.Name),
DisputeGameType: uint32(ctx.Uint(flags.DisputeGameTypeFlag.Name)),
ActiveSequencerCheckDuration: ctx.Duration(flags.ActiveSequencerCheckDurationFlag.Name),
WaitNodeSync: ctx.Bool(flags.WaitNodeSyncFlag.Name),
}
}
......@@ -415,6 +415,14 @@ func (l *L2OutputSubmitter) loop() {
defer l.wg.Done()
ctx := l.ctx
if l.Cfg.WaitNodeSync {
err := l.waitNodeSync()
if err != nil {
l.Log.Error("Error waiting for node sync", "err", err)
return
}
}
if l.dgfContract == nil {
l.loopL2OO(ctx)
} else {
......@@ -422,6 +430,23 @@ func (l *L2OutputSubmitter) loop() {
}
}
func (l *L2OutputSubmitter) waitNodeSync() error {
ctx, cancel := context.WithTimeout(l.ctx, l.Cfg.NetworkTimeout)
defer cancel()
l1head, err := l.Txmgr.BlockNumber(ctx)
if err != nil {
return fmt.Errorf("failed to retrieve current L1 block number: %w", err)
}
rollupClient, err := l.RollupProvider.RollupClient(ctx)
if err != nil {
return fmt.Errorf("failed to get rollup client: %w", err)
}
return dial.WaitRollupSync(l.ctx, l.Log, rollupClient, l1head, time.Second*12)
}
func (l *L2OutputSubmitter) loopL2OO(ctx context.Context) {
ticker := time.NewTicker(l.Cfg.PollInterval)
defer ticker.Stop()
......
......@@ -44,6 +44,8 @@ type ProposerConfig struct {
// is never valid on an alternative L1 chain that would produce different L2 data.
// This option is not necessary when higher proposal latency is acceptable and L1 is healthy.
AllowNonFinalized bool
WaitNodeSync bool
}
type ProposerService struct {
......@@ -89,6 +91,7 @@ func (ps *ProposerService) initFromCLIConfig(ctx context.Context, version string
ps.PollInterval = cfg.PollInterval
ps.NetworkTimeout = cfg.TxMgrConfig.NetworkTimeout
ps.AllowNonFinalized = cfg.AllowNonFinalized
ps.WaitNodeSync = cfg.WaitNodeSync
ps.initL2ooAddress(cfg)
ps.initDGF(cfg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment