feat(l1): introduce SettlementLayer and EthMessagingClient abstractions#3738
feat(l1): introduce SettlementLayer and EthMessagingClient abstractions#3738brbrr wants to merge 15 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3738 +/- ##
==========================================
+ Coverage 75.40% 75.50% +0.09%
==========================================
Files 438 437 -1
Lines 39501 39549 +48
==========================================
+ Hits 29786 29861 +75
+ Misses 7646 7618 -28
- Partials 2069 2070 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Claude finished @brbrr's task in 5m 10s —— View job PR Review: L1 SettlementLayer abstractionI reviewed the diff against Reviewed:
This is a clean, well-structured refactor. Logic is correct; I found no blockers — one test-coverage gap worth addressing and two nits. Important
Nits
Verified (no action needed)
|
|
Claude finished @brbrr's task in 3m 41s —— View job PR Review: L1 SettlementLayer abstraction — follow-up
Re-reviewed after the Resolved
Nits (non-blocking)
VerdictNo blockers. The previously-flagged test gap is closed and both nits are addressed — this is good to merge from my side (note: I cannot approve PRs). I was unable to run |
rodrodros
left a comment
There was a problem hiding this comment.
This PR looks more complicated than it should, let's discuss it more on Monday
|
Claude finished @brbrr's task in 4m 21s —— View job PR Review: SettlementLayer & EthMessagingClient abstractions
I reviewed this against the branch base ( Verified (no action needed)
Nits (non-blocking)
Note: I could not run Re @rodrodros's "more complicated than it should be" — that's a design-altitude question (worth the Monday discussion) rather than a correctness one; from a bug/race/leak standpoint the implementation is sound. |
|
Claude finished @brbrr's task in 3m 47s —— View job PR Review: SettlementLayer & EthMessagingClient abstractions
Re-reviewed after the latest The simplification is a real improvementThe hand-rolled
Verified (no action needed)
Nits (non-blocking)
Note: build is clean, but I couldn't run |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new L1 abstraction boundary by splitting the “settlement layer” (watch/filter state update events, heights, chain ID, receipts) from the higher-level l1.Client sync loop, and wires the new adapter into node startup/migrations and RPC.
Changes:
- Add
l1.SettlementLayer+l1.StateUpdateas chain-neutral types consumed byl1.Client, and implement a go-ethereum-backed adapter (l1.GethSettlement). - Remove the old geth-specific
EthSubscriberand the RPCEthReceiptAdapter, wiringGethSettlementdirectly into RPC handlers forstarknet_getMessageStatus. - Refactor L1 metrics so the listener is shared across
l1.Clientand the settlement adapter, and split settlement polling gauges into a separate registrar.
Reviewed changes
Copilot reviewed 18 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| rpc/rpccore/rpccore.go | Adds/clarifies the L1Client interface documentation used by RPC for message status. |
| rpc/rpccore/eth_receipt_adapter.go | Removes the receipt adapter now that the settlement client returns Juno eth types directly. |
| rpc/rpccore/eth_receipt_adapter_test.go | Removes adapter tests (adapter deleted). |
| node/node.go | Constructs GethSettlement, attaches metrics listener/options, passes settlement to both l1.Client and RPC. |
| node/migration.go | Uses GethSettlement + l1.Client to fetch L1 head during migration without metrics listener. |
| node/metrics.go | Splits L1 metrics into listener vs settlement polling gauges; hooks into SettlementLayer. |
| node/metrics_test.go | Updates tests to use MockSettlementLayer and the split metric registration flow. |
| mocks/mock_subscriber.go | Deletes mock for the removed Subscriber interface. |
| mocks/mock_settlement_layer.go | Adds mock for the new SettlementLayer interface. |
| l1/settlement.go | Introduces SettlementLayer and chain-neutral StateUpdate. |
| l1/l1.go | Refactors l1.Client to depend on SettlementLayer and StateUpdate instead of geth types. |
| l1/l1_test.go | Updates internal tests to use MockSettlementLayer and StateUpdate. |
| l1/l1_pkg_test.go | Moves tests to l1_test and uses exported test helpers to avoid import cycles. |
| l1/export_test.go | Exposes package-private hooks to external tests (SetSettlement, cache accessors, retry loops). |
| l1/geth/contract/starknet.go | Adds generated contract binding used by GethSettlement. |
| l1/geth/contract/starknet_filter.go | Adds helper to fully drain filtered logs from abigen’s FilterLogs. |
| l1/geth_settlement.go | Adds go-ethereum-backed GethSettlement implementing SettlementLayer (+ receipt lookup). |
| l1/geth_settlement_test.go | Adds unit tests for GethSettlement via a minimal JSON-RPC test server. |
| l1/geth_forwarder_test.go | Adds tests for forwarding/teardown behavior of the state update forwarder. |
| l1/eth/subscription.go | Removes the old eth.Subscription interface (now expected to live at the l1 boundary). |
| l1/eth_subscriber.go | Deletes the old go-ethereum-backed subscriber implementation (replaced by GethSettlement). |
Files not reviewed (1)
- mocks/mock_settlement_layer.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
c30556e to
1c464ae
Compare
|
Claude finished @brbrr's task in 3m 48s —— View job PR Review: SettlementLayer abstraction
Re-reviewed the current tip ( Verified (no action needed)
Nits (non-blocking, all cosmetic — no inline comments posted)
Re @rodrodros's "more complicated than it should be" — the Verdict: No blockers. Good to merge from a correctness standpoint (note: I can't approve PRs). I couldn't run |
| // L2BlockHash is the Starknet block hash for that block. | ||
| L2BlockHash *felt.Felt | ||
| // StateRoot is the Starknet global state root after the block | ||
| // (the "globalRoot" field in the on-chain event). | ||
| StateRoot *felt.Felt |
There was a problem hiding this comment.
It was a mechanical change, driven by the old usage, and the fact that L1Head uses pointers. But also it seems consistent with Felt usage across the codebase 🤷. Do you think they should be values?
rodrodros
left a comment
There was a problem hiding this comment.
First review, overall looks good and makes sense, will perform additional rounds
RafaelGranza
left a comment
There was a problem hiding this comment.
LGTM. Just the one nit on the unused fields.
Signed-off-by: Yaroslav Kukharuk <i.kukharuk@gmail.com>
|
Claude finished @brbrr's task in 3m 43s —— View job PR Review: L1StateProvider abstraction
Re-reviewed the current tip on 🔴 Blocker
Nit
Verified (no action needed)
Once the signature is fixed and the file is |
| return nil | ||
| case stateUpdate := <-updateCh: | ||
| c.applyLogStateUpdate(stateUpdate) | ||
| c.applyStateUpdate(stateUpdate) |
There was a problem hiding this comment.
Nit: this line is indented with spaces instead of a tab, so gofmt -l flags the file (CI lint will fail). Re-indent with a tab.
| c.applyStateUpdate(stateUpdate) | |
| c.applyStateUpdate(stateUpdate) |
|
Claude finished @brbrr's task in 3m 34s —— View job PR Review: L1StateProvider abstraction — re-review after latest push
Re-reviewed the current tip on ✅ Resolved since last review
Verified (no action needed)
Nits (non-blocking, cosmetic — carried over, no inline comments)
Verdict: No blockers — the previous compile/format breakage is fixed, the package builds and is gofmt-clean, and all cross-round feedback is addressed. Good to merge from a correctness standpoint (note: I can't approve PRs). I couldn't run |
This is the first part of #3727 (deprecated) that adds an abstraction layer between the Geth L1 client and Juno, separating the settlement layer and the actual RPC client.