Commit 43b1c4c0 authored by Minhyuk Kim's avatar Minhyuk Kim Committed by GitHub

Add new sync config: l2.enginekind (#10767)

* Add new syncmode "force-execution-layer"

* Add tests

* Add l2.enginekind flag instead of ForceELSync

* Move l2EngineClientKind to EngineController

* Fix lint

* Rename engine.EngineClientKind to engine.Kind and added engineKind.SupportsPostFinalizationELSync()

* Refactor EL/CL tests in sync_test.go

* Refactor tests in sync_test.go

* Rename engine to ec

* Incorporate enginekind-specific flags into syncConfig, and hide engine kind from the engine controller logic

* Fix tests

---------
Co-authored-by: default avatarprotolambda <proto@protolambda.com>
parent 822df50b
...@@ -37,10 +37,7 @@ import ( ...@@ -37,10 +37,7 @@ import (
type L2Verifier struct { type L2Verifier struct {
log log.Logger log log.Logger
eng interface { eng L2API
engine.Engine
L2BlockRefByNumber(ctx context.Context, num uint64) (eth.L2BlockRef, error)
}
syncStatus driver.SyncStatusTracker syncStatus driver.SyncStatusTracker
...@@ -100,7 +97,7 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, blobsSrc deri ...@@ -100,7 +97,7 @@ func NewL2Verifier(t Testing, log log.Logger, l1 derive.L1Fetcher, blobsSrc deri
}) })
metrics := &testutils.TestDerivationMetrics{} metrics := &testutils.TestDerivationMetrics{}
ec := engine.NewEngineController(eng, log, metrics, cfg, syncCfg.SyncMode, synchronousEvents) ec := engine.NewEngineController(eng, log, metrics, cfg, syncCfg, synchronousEvents)
engineResetDeriver := engine.NewEngineResetDeriver(ctx, log, cfg, l1, eng, syncCfg, synchronousEvents) engineResetDeriver := engine.NewEngineResetDeriver(ctx, log, cfg, l1, eng, syncCfg, synchronousEvents)
clSync := clsync.NewCLSync(log, cfg, metrics, synchronousEvents) clSync := clsync.NewCLSync(log, cfg, metrics, synchronousEvents)
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
crand "crypto/rand" crand "crypto/rand"
"fmt" "fmt"
"math/big" "math/big"
"math/rand" "math/rand"
"testing" "testing"
......
This diff is collapsed.
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"github.com/ethereum-optimism/optimism/op-node/rollup/engine"
"github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-node/rollup/sync"
plasma "github.com/ethereum-optimism/optimism/op-plasma" plasma "github.com/ethereum-optimism/optimism/op-plasma"
openum "github.com/ethereum-optimism/optimism/op-service/enum" openum "github.com/ethereum-optimism/optimism/op-service/enum"
...@@ -191,6 +192,17 @@ var ( ...@@ -191,6 +192,17 @@ var (
Value: time.Second * 12, Value: time.Second * 12,
Category: L1RPCCategory, Category: L1RPCCategory,
} }
L2EngineKind = &cli.GenericFlag{
Name: "l2.enginekind",
Usage: "The kind of engine client, used to control the behavior of optimism in respect to different types of engine clients. Valid options: " +
openum.EnumString(engine.Kinds),
EnvVars: prefixEnvVars("L2_ENGINE_KIND"),
Value: func() *engine.Kind {
out := engine.Geth
return &out
}(),
Category: RollupCategory,
}
VerifierL1Confs = &cli.Uint64Flag{ VerifierL1Confs = &cli.Uint64Flag{
Name: "verifier.l1-confs", Name: "verifier.l1-confs",
Usage: "Number of L1 blocks to keep distance from the L1 head before deriving L2 data from. Reorgs are supported, but may be slow to perform.", Usage: "Number of L1 blocks to keep distance from the L1 head before deriving L2 data from. Reorgs are supported, but may be slow to perform.",
...@@ -404,6 +416,7 @@ var optionalFlags = []cli.Flag{ ...@@ -404,6 +416,7 @@ var optionalFlags = []cli.Flag{
ConductorRpcFlag, ConductorRpcFlag,
ConductorRpcTimeoutFlag, ConductorRpcTimeoutFlag,
SafeDBPath, SafeDBPath,
L2EngineKind,
} }
var DeprecatedFlags = []cli.Flag{ var DeprecatedFlags = []cli.Flag{
......
...@@ -110,6 +110,7 @@ func TestEnvVarFormat(t *testing.T) { ...@@ -110,6 +110,7 @@ func TestEnvVarFormat(t *testing.T) {
L2EngineJWTSecret.Name, L2EngineJWTSecret.Name,
L1TrustRPC.Name, L1TrustRPC.Name,
L1RPCProviderKind.Name, L1RPCProviderKind.Name,
L2EngineKind.Name,
SnapshotLog.Name, SnapshotLog.Name,
BackupL2UnsafeSyncRPC.Name, BackupL2UnsafeSyncRPC.Name,
BackupL2UnsafeSyncRPCTrustRPC.Name, BackupL2UnsafeSyncRPCTrustRPC.Name,
......
...@@ -194,7 +194,7 @@ func NewDriver( ...@@ -194,7 +194,7 @@ func NewDriver(
sequencerConfDepth := NewConfDepth(driverCfg.SequencerConfDepth, statusTracker.L1Head, l1) sequencerConfDepth := NewConfDepth(driverCfg.SequencerConfDepth, statusTracker.L1Head, l1)
findL1Origin := NewL1OriginSelector(log, cfg, sequencerConfDepth) findL1Origin := NewL1OriginSelector(log, cfg, sequencerConfDepth)
verifConfDepth := NewConfDepth(driverCfg.VerifierConfDepth, statusTracker.L1Head, l1) verifConfDepth := NewConfDepth(driverCfg.VerifierConfDepth, statusTracker.L1Head, l1)
ec := engine.NewEngineController(l2, log, metrics, cfg, syncCfg.SyncMode, synchronousEvents) ec := engine.NewEngineController(l2, log, metrics, cfg, syncCfg, synchronousEvents)
engineResetDeriver := engine.NewEngineResetDeriver(driverCtx, log, cfg, l1, l2, syncCfg, synchronousEvents) engineResetDeriver := engine.NewEngineResetDeriver(driverCtx, log, cfg, l1, l2, syncCfg, synchronousEvents)
clSync := clsync.NewCLSync(log, cfg, metrics, synchronousEvents) clSync := clsync.NewCLSync(log, cfg, metrics, synchronousEvents)
......
...@@ -48,7 +48,7 @@ type EngineController struct { ...@@ -48,7 +48,7 @@ type EngineController struct {
engine ExecEngine // Underlying execution engine RPC engine ExecEngine // Underlying execution engine RPC
log log.Logger log log.Logger
metrics derive.Metrics metrics derive.Metrics
syncMode sync.Mode syncCfg *sync.Config
syncStatus syncStatusEnum syncStatus syncStatusEnum
chainSpec *rollup.ChainSpec chainSpec *rollup.ChainSpec
rollupCfg *rollup.Config rollupCfg *rollup.Config
...@@ -79,9 +79,9 @@ type EngineController struct { ...@@ -79,9 +79,9 @@ type EngineController struct {
} }
func NewEngineController(engine ExecEngine, log log.Logger, metrics derive.Metrics, func NewEngineController(engine ExecEngine, log log.Logger, metrics derive.Metrics,
rollupCfg *rollup.Config, syncMode sync.Mode, emitter event.Emitter) *EngineController { rollupCfg *rollup.Config, syncCfg *sync.Config, emitter event.Emitter) *EngineController {
syncStatus := syncStatusCL syncStatus := syncStatusCL
if syncMode == sync.ELSync { if syncCfg.SyncMode == sync.ELSync {
syncStatus = syncStatusWillStartEL syncStatus = syncStatusWillStartEL
} }
...@@ -91,7 +91,7 @@ func NewEngineController(engine ExecEngine, log log.Logger, metrics derive.Metri ...@@ -91,7 +91,7 @@ func NewEngineController(engine ExecEngine, log log.Logger, metrics derive.Metri
metrics: metrics, metrics: metrics,
chainSpec: rollup.NewChainSpec(rollupCfg), chainSpec: rollup.NewChainSpec(rollupCfg),
rollupCfg: rollupCfg, rollupCfg: rollupCfg,
syncMode: syncMode, syncCfg: syncCfg,
syncStatus: syncStatus, syncStatus: syncStatus,
clock: clock.SystemClock, clock: clock.SystemClock,
emitter: emitter, emitter: emitter,
...@@ -329,7 +329,7 @@ func (e *EngineController) resetBuildingState() { ...@@ -329,7 +329,7 @@ func (e *EngineController) resetBuildingState() {
// checkNewPayloadStatus checks returned status of engine_newPayloadV1 request for next unsafe payload. // checkNewPayloadStatus checks returned status of engine_newPayloadV1 request for next unsafe payload.
// It returns true if the status is acceptable. // It returns true if the status is acceptable.
func (e *EngineController) checkNewPayloadStatus(status eth.ExecutePayloadStatus) bool { func (e *EngineController) checkNewPayloadStatus(status eth.ExecutePayloadStatus) bool {
if e.syncMode == sync.ELSync { if e.syncCfg.SyncMode == sync.ELSync {
if status == eth.ExecutionValid && e.syncStatus == syncStatusStartedEL { if status == eth.ExecutionValid && e.syncStatus == syncStatusStartedEL {
e.syncStatus = syncStatusFinishedELButNotFinalized e.syncStatus = syncStatusFinishedELButNotFinalized
} }
...@@ -342,7 +342,7 @@ func (e *EngineController) checkNewPayloadStatus(status eth.ExecutePayloadStatus ...@@ -342,7 +342,7 @@ func (e *EngineController) checkNewPayloadStatus(status eth.ExecutePayloadStatus
// checkForkchoiceUpdatedStatus checks returned status of engine_forkchoiceUpdatedV1 request for next unsafe payload. // checkForkchoiceUpdatedStatus checks returned status of engine_forkchoiceUpdatedV1 request for next unsafe payload.
// It returns true if the status is acceptable. // It returns true if the status is acceptable.
func (e *EngineController) checkForkchoiceUpdatedStatus(status eth.ExecutePayloadStatus) bool { func (e *EngineController) checkForkchoiceUpdatedStatus(status eth.ExecutePayloadStatus) bool {
if e.syncMode == sync.ELSync { if e.syncCfg.SyncMode == sync.ELSync {
if status == eth.ExecutionValid && e.syncStatus == syncStatusStartedEL { if status == eth.ExecutionValid && e.syncStatus == syncStatusStartedEL {
e.syncStatus = syncStatusFinishedELButNotFinalized e.syncStatus = syncStatusFinishedELButNotFinalized
} }
...@@ -398,7 +398,7 @@ func (e *EngineController) InsertUnsafePayload(ctx context.Context, envelope *et ...@@ -398,7 +398,7 @@ func (e *EngineController) InsertUnsafePayload(ctx context.Context, envelope *et
if e.syncStatus == syncStatusWillStartEL { if e.syncStatus == syncStatusWillStartEL {
b, err := e.engine.L2BlockRefByLabel(ctx, eth.Finalized) b, err := e.engine.L2BlockRefByLabel(ctx, eth.Finalized)
rollupGenesisIsFinalized := b.Hash == e.rollupCfg.Genesis.L2.Hash rollupGenesisIsFinalized := b.Hash == e.rollupCfg.Genesis.L2.Hash
if errors.Is(err, ethereum.NotFound) || rollupGenesisIsFinalized { if errors.Is(err, ethereum.NotFound) || rollupGenesisIsFinalized || e.syncCfg.SupportsPostFinalizationELSync {
e.syncStatus = syncStatusStartedEL e.syncStatus = syncStatusStartedEL
e.log.Info("Starting EL sync") e.log.Info("Starting EL sync")
e.elStart = e.clock.Now() e.elStart = e.clock.Now()
......
package engine
import "fmt"
// Kind identifies the engine client's kind, used to control the behavior of optimism in different engine clients.
type Kind string
const (
Geth Kind = "geth"
Reth Kind = "reth"
Erigon Kind = "erigon"
)
var Kinds = []Kind{
Geth,
Reth,
Erigon,
}
func (kind Kind) String() string {
return string(kind)
}
func (kind *Kind) Set(value string) error {
if !ValidEngineKind(Kind(value)) {
return fmt.Errorf("unknown engine client kind: %q", value)
}
*kind = Kind(value)
return nil
}
func (kind *Kind) Clone() any {
cpy := *kind
return &cpy
}
func (kind Kind) SupportsPostFinalizationELSync() bool {
switch kind {
case Geth:
return false
case Erigon, Reth:
return true
}
return false
}
func ValidEngineKind(value Kind) bool {
for _, k := range Kinds {
if k == value {
return true
}
}
return false
}
...@@ -70,4 +70,6 @@ type Config struct { ...@@ -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 // 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. // snap sync with a genesis finalization data.
SkipSyncStartCheck bool `json:"skip_sync_start_check"` SkipSyncStartCheck bool `json:"skip_sync_start_check"`
SupportsPostFinalizationELSync bool `json:"supports_post_finalization_elsync"`
} }
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
p2pcli "github.com/ethereum-optimism/optimism/op-node/p2p/cli" p2pcli "github.com/ethereum-optimism/optimism/op-node/p2p/cli"
"github.com/ethereum-optimism/optimism/op-node/rollup" "github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/driver" "github.com/ethereum-optimism/optimism/op-node/rollup/driver"
"github.com/ethereum-optimism/optimism/op-node/rollup/engine"
"github.com/ethereum-optimism/optimism/op-node/rollup/sync" "github.com/ethereum-optimism/optimism/op-node/rollup/sync"
opflags "github.com/ethereum-optimism/optimism/op-service/flags" opflags "github.com/ethereum-optimism/optimism/op-service/flags"
) )
...@@ -269,9 +270,12 @@ func NewSyncConfig(ctx *cli.Context, log log.Logger) (*sync.Config, error) { ...@@ -269,9 +270,12 @@ func NewSyncConfig(ctx *cli.Context, log log.Logger) (*sync.Config, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
engineKind := engine.Kind(ctx.String(flags.L2EngineKind.Name))
cfg := &sync.Config{ cfg := &sync.Config{
SyncMode: mode, SyncMode: mode,
SkipSyncStartCheck: ctx.Bool(flags.SkipSyncStartCheck.Name), SkipSyncStartCheck: ctx.Bool(flags.SkipSyncStartCheck.Name),
SupportsPostFinalizationELSync: engineKind.SupportsPostFinalizationELSync(),
} }
if ctx.Bool(flags.L2EngineSyncEnabled.Name) { if ctx.Bool(flags.L2EngineSyncEnabled.Name) {
cfg.SyncMode = sync.ELSync cfg.SyncMode = sync.ELSync
......
...@@ -39,7 +39,7 @@ func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher, ...@@ -39,7 +39,7 @@ func NewDriver(logger log.Logger, cfg *rollup.Config, l1Source derive.L1Fetcher,
pipeline := derive.NewDerivationPipeline(logger, cfg, l1Source, l1BlobsSource, plasma.Disabled, l2Source, metrics.NoopMetrics) pipeline := derive.NewDerivationPipeline(logger, cfg, l1Source, l1BlobsSource, plasma.Disabled, l2Source, metrics.NoopMetrics)
pipelineDeriver := derive.NewPipelineDeriver(context.Background(), pipeline, d) pipelineDeriver := derive.NewPipelineDeriver(context.Background(), pipeline, d)
ec := engine.NewEngineController(l2Source, logger, metrics.NoopMetrics, cfg, sync.CLSync, d) ec := engine.NewEngineController(l2Source, logger, metrics.NoopMetrics, cfg, &sync.Config{SyncMode: sync.CLSync}, d)
engineDeriv := engine.NewEngDeriver(logger, context.Background(), cfg, ec, d) engineDeriv := engine.NewEngDeriver(logger, context.Background(), cfg, ec, d)
syncCfg := &sync.Config{SyncMode: sync.CLSync} syncCfg := &sync.Config{SyncMode: sync.CLSync}
engResetDeriv := engine.NewEngineResetDeriver(context.Background(), logger, cfg, l1Source, l2Source, syncCfg, d) engResetDeriv := engine.NewEngineResetDeriver(context.Background(), logger, cfg, l1Source, l2Source, syncCfg, d)
......
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