-
Notifications
You must be signed in to change notification settings - Fork 3.9k
[PoC] op-node: Light CL #18196
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
Closed
Closed
[PoC] op-node: Light CL #18196
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
ca2f695
docs: Add implementation plan for --safe-source=l2 feature
0f44862
feat(op-node): Add --safe-source=l2 config and flags (Phase 1)
a636c00
feat(op-node): Implement safe-source=l2 mode (Phases 2-4)
9f6fd1a
feat(op-node): Add payload fetching and reorg logic for safe-source=l2
a6ada8d
test(op-node): Add unit tests for safe-source=l2 mode
ee1789f
fix: address PR review comments
47d6dcd
fix: add ResetStepBackoff back to safe-source=l2 block
6eacf92
style: match EL sync comment style for safe-source=l2 block
b370957
test: remove config_test.go for SafeSource
f7731d8
test: add safe-source=l2 devstack preset and acceptance test
fbfa1ec
test: add sync_tester test for safe-source=l2
86c3c9c
test: add init_test.go for safe_source_l2
5df9133
fix(op-node): ensure safe-source=l2 runs periodically and handles mis…
a4a4f97
refactor: move safe-source=l2 logic to dedicated ticker
e0daad4
docs: remove implementation planning document
5022f92
fix: skip safe-source=l2 updates when EL is syncing
e2c9d92
refactor: rename safesource to safesourcel2 for consistency
34604e6
fix: address PR review comments
3221aa4
fix: fetch finalized before safe to maintain invariant
a8d157e
refactor: simplify SafeSource type and extract ticker logic
4755c5c
refactor: fetch unsafe head and rename payload insertion function
ec5f81c
refactor(safe-source-l2): improve reorg handling and simplify error h…
e13f62e
refactor(safe-source-l2): simplify syncSafeHeadFromL2 to rely on EL sync
da1b08a
fix(safe-source-l2): remove startup engine reset to prevent FCU to ge…
9541f7f
Fix unit test?
pcw109550 633779a
Rm unused method and unit tests
pcw109550 8be9545
Deflake
pcw109550 8590515
linter happy
pcw109550 5342a5d
safe source with sequencer
pcw109550 fbecf30
blast every logs
pcw109550 dc42477
disable derivation + seq works?
pcw109550 2ffc9bd
Do not FCU to genesis
pcw109550 f958ffd
revert back
pcw109550 8a9f55e
Fix seq + light node?
pcw109550 b73e69e
edge case
pcw109550 89c60af
try another approach
pcw109550 6811966
linter
pcw109550 bda342f
logs
pcw109550 6b18dee
make RR Sync work + allow initial Sync using syncmode=execution-layer
pcw109550 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package safe_source_l2 | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ethereum-optimism/optimism/op-devstack/compat" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/presets" | ||
| ) | ||
|
|
||
| func TestMain(m *testing.M) { | ||
| presets.DoMain(m, | ||
| presets.WithSingleChainMultiNodeWithSafeSourceL2(true /* seqWithSafeSourceL2 */), | ||
| presets.WithCompatibleTypes(compat.SysGo), | ||
| // test should work w/wo WithExecutionLayerSyncOnVerifiers. | ||
| // presets.WithExecutionLayerSyncOnVerifiers(), | ||
| ) | ||
| } |
39 changes: 39 additions & 0 deletions
39
op-acceptance-tests/tests/safe_source_l2/seq/safe_source_l2_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package safe_source_l2 | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ethereum-optimism/optimism/op-devstack/devtest" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/dsl" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/presets" | ||
| "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" | ||
| ) | ||
|
|
||
| // TestSafeSourceL2BasicSync verifies that a verifier node configured with --safe-source=l2 | ||
| // can follow the safe head of another verifier without performing derivation. | ||
| func TestSafeSourceL2BasicSync(gt *testing.T) { | ||
| t := devtest.SerialT(gt) | ||
| sys := presets.NewSingleChainMultiNodeWithSafeSourceL2(t) | ||
|
|
||
| // Advance the normal verifier's safe head | ||
| dsl.CheckAll(t, | ||
| sys.L2CL.AdvancedFn(types.LocalSafe, 5, 30), | ||
| ) | ||
|
|
||
| // Verify the safe-source=l2 verifier matches the normal verifier | ||
| sys.L2CLB.Matched(sys.L2CL, types.LocalSafe, 30) | ||
|
|
||
| // Get sync status from both nodes | ||
| l2CLStatus := sys.L2CL.SyncStatus() | ||
| l2CLBStatus := sys.L2CLB.SyncStatus() | ||
|
|
||
| require := t.Require() | ||
| require.Equal(l2CLStatus.SafeL2.Hash, l2CLBStatus.SafeL2.Hash, "Safe heads should match") | ||
| require.Equal(l2CLStatus.SafeL2.Number, l2CLBStatus.SafeL2.Number, "Safe block numbers should match") | ||
| require.Equal(l2CLStatus.FinalizedL2.Hash, l2CLBStatus.FinalizedL2.Hash, "Finalized heads should match") | ||
| require.Equal(l2CLStatus.FinalizedL2.Number, l2CLBStatus.FinalizedL2.Number, "Finalized block numbers should match") | ||
|
|
||
| // Advance further to ensure continued sync | ||
| sys.L2CL.Advanced(types.LocalSafe, 5, 30) | ||
| sys.L2CLB.Matched(sys.L2CL, types.LocalSafe, 30) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package safe_source_l2 | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ethereum-optimism/optimism/op-devstack/compat" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/presets" | ||
| ) | ||
|
|
||
| func TestMain(m *testing.M) { | ||
| presets.DoMain(m, | ||
| presets.WithSingleChainMultiNodeWithSafeSourceL2(false /* seqWithSafeSourceL2 */), | ||
| presets.WithCompatibleTypes(compat.SysGo), | ||
| // test should work w/wo WithExecutionLayerSyncOnVerifiers. | ||
| // presets.WithExecutionLayerSyncOnVerifiers(), | ||
| ) | ||
| } |
39 changes: 39 additions & 0 deletions
39
op-acceptance-tests/tests/safe_source_l2/ver/safe_source_l2_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package safe_source_l2 | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ethereum-optimism/optimism/op-devstack/devtest" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/dsl" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/presets" | ||
| "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" | ||
| ) | ||
|
|
||
| // TestSafeSourceL2BasicSync verifies that a verifier node configured with --safe-source=l2 | ||
| // can follow the safe head of another verifier without performing derivation. | ||
| func TestSafeSourceL2BasicSync(gt *testing.T) { | ||
| t := devtest.SerialT(gt) | ||
| sys := presets.NewSingleChainMultiNodeWithSafeSourceL2(t) | ||
|
|
||
| // Advance the normal verifier's safe head | ||
| dsl.CheckAll(t, | ||
| sys.L2CL.AdvancedFn(types.LocalSafe, 5, 30), | ||
| ) | ||
|
|
||
| // Verify the safe-source=l2 verifier matches the normal verifier | ||
| sys.L2CLB.Matched(sys.L2CL, types.LocalSafe, 30) | ||
|
|
||
| // Get sync status from both nodes | ||
| l2CLStatus := sys.L2CL.SyncStatus() | ||
| l2CLBStatus := sys.L2CLB.SyncStatus() | ||
|
|
||
| require := t.Require() | ||
| require.Equal(l2CLStatus.SafeL2.Hash, l2CLBStatus.SafeL2.Hash, "Safe heads should match") | ||
| require.Equal(l2CLStatus.SafeL2.Number, l2CLBStatus.SafeL2.Number, "Safe block numbers should match") | ||
| require.Equal(l2CLStatus.FinalizedL2.Hash, l2CLBStatus.FinalizedL2.Hash, "Finalized heads should match") | ||
| require.Equal(l2CLStatus.FinalizedL2.Number, l2CLBStatus.FinalizedL2.Number, "Finalized block numbers should match") | ||
|
|
||
| // Advance further to ensure continued sync | ||
| sys.L2CL.Advanced(types.LocalSafe, 5, 30) | ||
| sys.L2CLB.Matched(sys.L2CL, types.LocalSafe, 30) | ||
| } |
17 changes: 17 additions & 0 deletions
17
op-acceptance-tests/tests/sync_tester/sync_tester_safesourcel2/init_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package sync_tester_safesourcel2 | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ethereum-optimism/optimism/op-devstack/compat" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/presets" | ||
| ) | ||
|
|
||
| func TestMain(m *testing.M) { | ||
| presets.DoMain(m, | ||
| presets.WithELSyncActive(), | ||
| presets.WithSimpleWithSyncTesterSafeSourceL2(), | ||
| presets.WithExecutionLayerSyncOnVerifiers(), | ||
| presets.WithCompatibleTypes(compat.SysGo), | ||
| ) | ||
| } |
65 changes: 65 additions & 0 deletions
65
op-acceptance-tests/tests/sync_tester/sync_tester_safesourcel2/safesourcel2_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| package sync_tester_safesourcel2 | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/ethereum-optimism/optimism/op-devstack/devtest" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/dsl" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/presets" | ||
| "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" | ||
| ) | ||
|
|
||
| func TestSyncTesterSafeSourceL2(gt *testing.T) { | ||
| t := devtest.SerialT(gt) | ||
| sys := presets.NewSimpleWithSyncTesterSafeSourceL2(t) | ||
| require := t.Require() | ||
| logger := t.Logger() | ||
| ctx := t.Ctx() | ||
|
|
||
| target := uint64(5) | ||
| dsl.CheckAll(t, | ||
| sys.L2CL.AdvancedFn(types.LocalUnsafe, target, 30), | ||
| sys.L2CL2.AdvancedFn(types.LocalUnsafe, target, 30), | ||
| ) | ||
|
|
||
| // Stop L2CL2 which is using safe-source=l2 | ||
| sys.L2CL2.Stop() | ||
|
|
||
| // Reset Sync Tester EL | ||
| sessionIDs := sys.SyncTester.ListSessions() | ||
| require.GreaterOrEqual(len(sessionIDs), 1, "at least one session") | ||
| sessionID := sessionIDs[0] | ||
| logger.Info("SyncTester EL", "sessionID", sessionID) | ||
| syncTesterClient := sys.SyncTester.Escape().APIWithSession(sessionID) | ||
| require.NoError(syncTesterClient.ResetSession(ctx)) | ||
|
|
||
| // Wait for L2CL to advance more unsafe and safe blocks | ||
| sys.L2CL.Advanced(types.LocalUnsafe, target+5, 30) | ||
| sys.L2CL.Advanced(types.LocalSafe, target+3, 30) | ||
|
|
||
| // Restarting will allow L2CL2 to query safe head from L2CL via safe-source=l2 | ||
| sys.L2CL2.Start() | ||
|
|
||
| // Wait until P2P is connected for unsafe head gossip | ||
| sys.L2CL2.IsP2PConnected(sys.L2CL) | ||
|
|
||
| // L2CL2 should catch up via safe-source=l2 | ||
| target = uint64(20) | ||
| sys.L2CL.Reached(types.LocalSafe, target, 30) | ||
| sys.L2CL2.Reached(types.LocalSafe, target, 30) | ||
|
|
||
| sys.L2CL.Matched(sys.L2CL2, types.LocalSafe, 30) | ||
|
|
||
| logger.Info("SyncTester SafeSourceL2 test completed successfully") | ||
|
|
||
| logger.Info("### Safe ", "ver", sys.L2CL2.SafeL2BlockRef(), "seq", sys.L2CL.SafeL2BlockRef()) | ||
| logger.Info("### Unsafe", "ver", sys.L2CL2.UnsafeHead(), "seq", sys.L2CL.UnsafeHead()) | ||
| // Safe matches but unsafe gap still happen | ||
|
|
||
| sys.L2CL.Matched(sys.L2CL2, types.LocalUnsafe, 100) | ||
|
|
||
| logger.Info("### Safe ", "ver", sys.L2CL2.SafeL2BlockRef(), "seq", sys.L2CL.SafeL2BlockRef()) | ||
| logger.Info("### Unsafe", "ver", sys.L2CL2.UnsafeHead(), "seq", sys.L2CL.UnsafeHead()) | ||
| logger.Info("### Finalzed", "ver", sys.L2CL2.SyncStatus().FinalizedL2, "seq", sys.L2CL.SyncStatus().FinalizedL2) | ||
|
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
op-devstack/presets/simple_with_synctester_safesourcel2.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| package presets | ||
|
|
||
| import ( | ||
| "github.com/ethereum-optimism/optimism/op-devstack/devtest" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/dsl" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/shim" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/stack" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/stack/match" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/sysgo" | ||
| ) | ||
|
|
||
| type SimpleWithSyncTesterSafeSourceL2 struct { | ||
| Minimal | ||
|
|
||
| SyncTester *dsl.SyncTester | ||
| SyncTesterL2EL *dsl.L2ELNode | ||
| L2CL2 *dsl.L2CLNode | ||
| } | ||
|
|
||
| func WithSimpleWithSyncTesterSafeSourceL2() stack.CommonOption { | ||
| return stack.MakeCommon(sysgo.DefaultSimpleSystemWithSyncTesterSafeSourceL2(&sysgo.DefaultSimpleSystemWithSyncTesterSafeSourceL2IDs{})) | ||
| } | ||
|
|
||
| func NewSimpleWithSyncTesterSafeSourceL2(t devtest.T) *SimpleWithSyncTesterSafeSourceL2 { | ||
| system := shim.NewSystem(t) | ||
| orch := Orchestrator() | ||
| orch.Hydrate(system) | ||
| minimal := minimalFromSystem(t, system, orch) | ||
| l2 := system.L2Network(match.L2ChainA) | ||
| syncTester := l2.SyncTester(match.FirstSyncTester) | ||
|
|
||
| // L2CL2 connected to L2EL initialized by sync tester, with safe-source=l2 | ||
| l2CL2 := l2.L2CLNode(match.SecondL2CL) | ||
| // L2EL initialized by sync tester | ||
| syncTesterL2EL := l2.L2ELNode(match.SecondL2EL) | ||
|
|
||
| return &SimpleWithSyncTesterSafeSourceL2{ | ||
| Minimal: *minimal, | ||
| SyncTester: dsl.NewSyncTester(syncTester), | ||
| SyncTesterL2EL: dsl.NewL2ELNode(syncTesterL2EL, orch.ControlPlane()), | ||
| L2CL2: dsl.NewL2CLNode(l2CL2, orch.ControlPlane()), | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| package presets | ||
|
|
||
| import ( | ||
| "github.com/ethereum-optimism/optimism/op-devstack/devtest" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/dsl" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/shim" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/stack" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/stack/match" | ||
| "github.com/ethereum-optimism/optimism/op-devstack/sysgo" | ||
| "github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types" | ||
| ) | ||
|
|
||
| type SingleChainMultiNodeWithSafeSourceL2 struct { | ||
| Minimal | ||
|
|
||
| L2ELB *dsl.L2ELNode | ||
| L2CLB *dsl.L2CLNode | ||
| } | ||
|
|
||
| func WithSingleChainMultiNodeWithSafeSourceL2(seqWithSafeSourceL2 bool) stack.CommonOption { | ||
| return stack.MakeCommon(sysgo.DefaultSingleChainMultiNodeWithSafeSourceL2System(&sysgo.DefaultSingleChainMultiNodeWithSafeSourceL2SystemIDs{}, seqWithSafeSourceL2)) | ||
| } | ||
|
|
||
| func NewSingleChainMultiNodeWithSafeSourceL2(t devtest.T) *SingleChainMultiNodeWithSafeSourceL2 { | ||
| preset := NewSingleChainMultiNodeWithSafeSourceL2WithoutCheck(t) | ||
| // Ensure the L2 sourced node is in sync with the sequencer before starting tests | ||
| dsl.CheckAll(t, | ||
| preset.L2CLB.MatchedFn(preset.L2CL, types.CrossSafe, 30), | ||
| preset.L2CLB.MatchedFn(preset.L2CL, types.LocalUnsafe, 30), | ||
| ) | ||
| return preset | ||
| } | ||
|
|
||
| func NewSingleChainMultiNodeWithSafeSourceL2WithoutCheck(t devtest.T) *SingleChainMultiNodeWithSafeSourceL2 { | ||
| system := shim.NewSystem(t) | ||
| orch := Orchestrator() | ||
| orch.Hydrate(system) | ||
| minimal := minimalFromSystem(t, system, orch) | ||
| l2 := system.L2Network(match.Assume(t, match.L2ChainA)) | ||
| verifierCL := l2.L2CLNode(match.Assume(t, | ||
| match.And( | ||
| match.Not(match.WithSequencerActive(t.Ctx())), | ||
| match.Not[stack.L2CLNodeID, stack.L2CLNode](minimal.L2CL.ID()), | ||
| ))) | ||
| verifierEL := l2.L2ELNode(match.Assume(t, | ||
| match.And( | ||
| match.EngineFor(verifierCL), | ||
| match.Not[stack.L2ELNodeID, stack.L2ELNode](minimal.L2EL.ID())))) | ||
| preset := &SingleChainMultiNodeWithSafeSourceL2{ | ||
| Minimal: *minimal, | ||
| L2ELB: dsl.NewL2ELNode(verifierEL, orch.ControlPlane()), | ||
| L2CLB: dsl.NewL2CLNode(verifierCL, orch.ControlPlane()), | ||
| } | ||
| return preset | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EL never advanced since the underlying sync tester EL did not enable EL Syncing. Fixed