Skip to content

Commit

Permalink
feat: fastnode support by trigger el-sync when needed (#201)
Browse files Browse the repository at this point in the history
Co-authored-by: Owen <[email protected]>
  • Loading branch information
krish-nr and owen-reorg authored Jun 7, 2024
1 parent 00d3473 commit b8d810a
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 28 deletions.
2 changes: 1 addition & 1 deletion op-e2e/actions/l2_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type safeDB interface {

func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, blobsSrc derive.L1BlobsFetcher, plasmaSrc derive.PlasmaInputFetcher, eng L2API, cfg *rollup.Config, syncCfg *sync.Config, safeHeadListener safeDB) *L2Verifier {
metrics := &testutils.TestDerivationMetrics{}
engine := derive.NewEngineController(eng, log, metrics, cfg, syncCfg.SyncMode)
engine := derive.NewEngineController(eng, log, metrics, cfg, syncCfg)
pipeline := derive.NewDerivationPipeline(log, cfg, l1, blobsSrc, plasmaSrc, eng, engine, metrics, syncCfg, safeHeadListener)
pipeline.Reset()

Expand Down
16 changes: 16 additions & 0 deletions op-node/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,20 @@ var (
EnvVars: prefixEnvVars("SAFEDB_PATH"),
Category: OperationsCategory,
}

FastnodeMode = &cli.BoolFlag{
Name: "fastnode",
Usage: "Fastnode has a strong dependency on a specific synchronization mode during synchronization, so please set this flag when running fastnode.",
EnvVars: prefixEnvVars("FASTNODE"),
Value: false,
}

ELTriggerGap = &cli.IntFlag{
Name: "el-trigger.gap",
Usage: "gap to trigger el-sync",
Value: 86400,
EnvVars: prefixEnvVars("EL_TRIGGER_GAP"),
}
/* Deprecated Flags */
L2EngineSyncEnabled = &cli.BoolFlag{
Name: "l2.engine-sync",
Expand Down Expand Up @@ -395,6 +409,8 @@ var optionalFlags = []cli.Flag{
BeaconCheckIgnore,
BeaconFetchAllSidecars,
SyncModeFlag,
FastnodeMode,
ELTriggerGap,
RPCListenAddr,
RPCListenPort,
L1TrustRPC,
Expand Down
39 changes: 21 additions & 18 deletions op-node/rollup/derive/engine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ type ExecEngine interface {
}

type EngineController struct {
engine ExecEngine // Underlying execution engine RPC
log log.Logger
metrics Metrics
syncMode sync.Mode
syncStatus syncStatusEnum
rollupCfg *rollup.Config
elStart time.Time
clock clock.Clock
engine ExecEngine // Underlying execution engine RPC
log log.Logger
metrics Metrics
syncMode sync.Mode
elTriggerGap int
syncStatus syncStatusEnum
rollupCfg *rollup.Config
elStart time.Time
clock clock.Clock

// Block Head State
unsafeHead eth.L2BlockRef
Expand All @@ -75,20 +76,21 @@ type EngineController struct {
safeAttrs *AttributesWithParent
}

func NewEngineController(engine ExecEngine, log log.Logger, metrics Metrics, rollupCfg *rollup.Config, syncMode sync.Mode) *EngineController {
func NewEngineController(engine ExecEngine, log log.Logger, metrics Metrics, rollupCfg *rollup.Config, syncConfig *sync.Config) *EngineController {
syncStatus := syncStatusCL
if syncMode == sync.ELSync {
if syncConfig.SyncMode == sync.ELSync {
syncStatus = syncStatusWillStartEL
}

return &EngineController{
engine: engine,
log: log,
metrics: metrics,
rollupCfg: rollupCfg,
syncMode: syncMode,
syncStatus: syncStatus,
clock: clock.SystemClock,
engine: engine,
log: log,
metrics: metrics,
rollupCfg: rollupCfg,
syncMode: syncConfig.SyncMode,
elTriggerGap: syncConfig.ELTriggerGap,
syncStatus: syncStatus,
clock: clock.SystemClock,
}
}

Expand Down Expand Up @@ -328,7 +330,8 @@ func (e *EngineController) InsertUnsafePayload(ctx context.Context, envelope *et
if e.syncStatus == syncStatusWillStartEL {
b, err := e.engine.L2BlockRefByLabel(ctx, eth.Finalized)
isTransitionBlock := e.rollupCfg.Genesis.L2.Number != 0 && b.Hash == e.rollupCfg.Genesis.L2.Hash
if errors.Is(err, ethereum.NotFound) || isTransitionBlock {
isGapSyncNeeded := ref.Number-e.UnsafeL2Head().Number > uint64(e.elTriggerGap)
if errors.Is(err, ethereum.NotFound) || isTransitionBlock || isGapSyncNeeded {
e.syncStatus = syncStatusStartedEL
e.log.Info("Starting EL sync")
e.elStart = e.clock.Now()
Expand Down
42 changes: 35 additions & 7 deletions op-node/rollup/derive/engine_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,11 @@ func TestEngineQueue_Finalize(t *testing.T) {

prev := &fakeAttributesQueue{}

ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync)
ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, &sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})
eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled)
require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF)

Expand Down Expand Up @@ -493,7 +497,11 @@ func TestEngineQueue_ResetWhenUnsafeOriginNotCanonical(t *testing.T) {

prev := &fakeAttributesQueue{origin: refE}

ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync)
ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, &sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})
eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled)
require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF)

Expand Down Expand Up @@ -832,7 +840,11 @@ func TestVerifyNewL1Origin(t *testing.T) {
}, nil)

prev := &fakeAttributesQueue{origin: refE}
ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync)
ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, &sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})
eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled)
require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF)

Expand Down Expand Up @@ -934,7 +946,11 @@ func TestBlockBuildingRace(t *testing.T) {
}

prev := &fakeAttributesQueue{origin: refA, attrs: attrs, islastInSpan: true}
ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, sync.CLSync)
ec := NewEngineController(eng, logger, metrics, &rollup.Config{}, &sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})
eq := NewEngineQueue(logger, cfg, eng, ec, metrics, prev, l1F, &sync.Config{}, safedb.Disabled)
require.ErrorIs(t, eq.Reset(context.Background(), eth.L1BlockRef{}, eth.SystemConfig{}), io.EOF)

Expand Down Expand Up @@ -1108,7 +1124,11 @@ func TestResetLoop(t *testing.T) {

prev := &fakeAttributesQueue{origin: refA, attrs: attrs, islastInSpan: true}

ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, sync.CLSync)
ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, &sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})
eq := NewEngineQueue(logger, cfg, eng, ec, metrics.NoopMetrics, prev, l1F, &sync.Config{}, safedb.Disabled)
eq.ec.SetUnsafeHead(refA2)
eq.ec.SetSafeHead(refA1)
Expand Down Expand Up @@ -1216,7 +1236,11 @@ func TestEngineQueue_StepPopOlderUnsafe(t *testing.T) {

prev := &fakeAttributesQueue{origin: refA}

ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, sync.CLSync)
ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, &sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})
eq := NewEngineQueue(logger, cfg, eng, ec, metrics.NoopMetrics, prev, l1F, &sync.Config{}, safedb.Disabled)
eq.ec.SetUnsafeHead(refA2)
eq.ec.SetSafeHead(refA0)
Expand Down Expand Up @@ -1296,7 +1320,11 @@ func TestPlasmaFinalityData(t *testing.T) {
SequenceNumber: 1,
}

ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, sync.CLSync)
ec := NewEngineController(eng, logger, metrics.NoopMetrics, &rollup.Config{}, &sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})

eq := NewEngineQueue(logger, cfg, eng, ec, metrics.NoopMetrics, prev, l1F, &sync.Config{}, safedb.Disabled)
require.Equal(t, expFinalityLookback, cap(eq.finalityData))
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func NewDriver(
sequencerConfDepth := NewConfDepth(driverCfg.SequencerConfDepth, l1State.L1Head, l1)
findL1Origin := NewL1OriginSelector(log, cfg, sequencerConfDepth)
verifConfDepth := NewConfDepth(driverCfg.VerifierConfDepth, l1State.L1Head, l1)
engine := derive.NewEngineController(l2, log, metrics, cfg, syncCfg.SyncMode)
engine := derive.NewEngineController(l2, log, metrics, cfg, syncCfg)
derivationPipeline := derive.NewDerivationPipeline(log, cfg, verifConfDepth, l1Blobs, plasma, l2, engine, metrics, syncCfg, safeHeadListener)
attrBuilder := derive.NewFetchingAttributesBuilder(cfg, l1, l2)
meteredEngine := NewMeteredEngine(cfg, engine, metrics, log) // Only use the metered engine in the sequencer b/c it records sequencing metrics.
Expand Down
2 changes: 2 additions & 0 deletions op-node/rollup/sync/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,6 @@ type Config struct {
// Note: We probably need to detect the condition that snap sync has not complete when we do a restart prior to running sync-start if we are doing
// snap sync with a genesis finalization data.
SkipSyncStartCheck bool `json:"skip_sync_start_check"`
// gap for trigger el-sync
ELTriggerGap int `json:"el_trigger_gap"`
}
10 changes: 10 additions & 0 deletions op-node/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,19 @@ func NewSyncConfig(ctx *cli.Context, log log.Logger) (*sync.Config, error) {
if err != nil {
return nil, err
}

//fastnode config
elTriggerGap := ctx.Int(flags.ELTriggerGap.Name)
if ctx.Bool(flags.FastnodeMode.Name) {
mode = sync.ELSync
// fastnode needs a smaller gap
elTriggerGap = 120
}

cfg := &sync.Config{
SyncMode: mode,
SkipSyncStartCheck: ctx.Bool(flags.SkipSyncStartCheck.Name),
ELTriggerGap: elTriggerGap,
}
if ctx.Bool(flags.L2EngineSyncEnabled.Name) {
cfg.SyncMode = sync.ELSync
Expand Down
7 changes: 6 additions & 1 deletion op-program/client/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ type Driver struct {
}

func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher, l1BlobsSource derive.L1BlobsFetcher, l2Source L2Source, targetBlockNum uint64) *Driver {
engine := derive.NewEngineController(l2Source, logger, metrics.NoopMetrics, cfg, sync.CLSync)
engine := derive.NewEngineController(l2Source, logger, metrics.NoopMetrics, cfg,
&sync.Config{
SyncMode: sync.CLSync,
SkipSyncStartCheck: false,
ELTriggerGap: 0,
})
pipeline := derive.NewDerivationPipeline(logger, cfg, l1Source, l1BlobsSource, plasma.Disabled, l2Source, engine, metrics.NoopMetrics, &sync.Config{}, safedb.Disabled)
pipeline.Reset()
return &Driver{
Expand Down

0 comments on commit b8d810a

Please sign in to comment.