Conversation
48b2bbf to
14f3132
Compare
6f42ea8 to
62be375
Compare
Dev Cluster Validation — CL Redis HADeployed ResultsLeader election: Working. One pod acquires the redsync mutex, the other follows via Redis. CL sync body propagation: Verified. Both pods serve the same Metrics (both pods reporting):
Failure modes observed:
k8s changes: Pushed to |
Failover & Store Reuse AnalysisPod Deletion Test (Leader Kill)Deleted the leader pod (
3 consecutive requests after failover all returned identical Redis Store ReuseAll Redis keys are scoped by the redsync lock token (a random value per leader election): Old keys are never reused — they expire via TTL (
|
62be375 to
64a5c05
Compare
Move the CL sync body cache (optimism_syncStatus response) from ConsensusPoller into the ConsensusTracker interface. The InMemory implementation stores it locally; the Redis implementation propagates it via Redis so all pods serve the same response regardless of which pod the load balancer routes to. Add group_consensus_ha_cl_pin_l1 Prometheus gauge so operators can track the CL pin L1 block number on both leader and follower. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
64a5c05 to
9045f0d
Compare
| ct.clRemoteSyncBody = payload.Body | ||
| ct.clRemoteL1Num = payload.L1Num |
There was a problem hiding this comment.
shouldn't you also update ct.remote.clSyncBody and ct.remote.clLastServedL1?
There was a problem hiding this comment.
Also, why not mirror this data to ct.clLocalSyncBody and ct.clLocalL1Num as well? (i.e. directly call c.SetCLSyncBody(...))
| clLocalSyncBody json.RawMessage | ||
| clLocalL1Num uint64 | ||
| clRemoteSyncBody json.RawMessage | ||
| clRemoteL1Num uint64 |
There was a problem hiding this comment.
how are these different from the fields under local and remote trackers?
…sync state Eliminate duplicate CL sync body fields on RedisConsensusTracker by delegating to the existing local/remote InMemoryConsensusTracker instances, matching the pattern already used for EL block numbers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lability Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… write Ensures postPayload updates ct.remote with the CL sync body after a successful Redis write, matching the pattern used for consensus state. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bef6c40 to
9604802
Compare
The 1.3.0 orb uses cimg/python:3.9 which is incompatible with the latest pip bootstrap script (requires Python 3.10+). v3.0.0 removes the Python dependency entirely, using pure Bash instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #611 +/- ##
==========================================
- Coverage 59.01% 58.82% -0.20%
==========================================
Files 97 97
Lines 15121 15170 +49
==========================================
Hits 8923 8923
- Misses 5651 5700 +49
Partials 547 547
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
| cp.consensusSyncBody = pin.body | ||
| cp.lastServedCLL1Num = pin.l1 | ||
| cp.syncStatusBodyMu.Unlock() | ||
| cp.tracker.SetCLSyncBody(pin.body, pin.l1) |
There was a problem hiding this comment.
this ends up setting both the local and remote trackers.
The fact that this is setting the remote tracker, shouldn't it also make this update to Redis as well?
|
|
||
| func (ct *RedisConsensusTracker) SetCLSyncBody(body json.RawMessage, l1Num uint64) { | ||
| ct.local.SetCLSyncBody(body, l1Num) | ||
| // Mirror to remote so GetCLSyncBody returns fresh data on the leader immediately. |
There was a problem hiding this comment.
Q: Am I misunderstanding this comment? How would this freshly set data get to the leader?
- assuming leadder is a difference instance/pod of proxyd.
This method updates ct.remote which is an in-memory view scoped to this proxyd process only, and it doesn't actually propagate this update to Redis or other instances. I think the comment should clarify that this mirrors to the local (not to be confused with ct.local) in-memory ct.remote state so GetCLSyncBody returns fresh data immediately on this instance, without waiting for the next Redis poll.
There was a problem hiding this comment.
Unless, the intention is to actually propagate this update all the way to the leader, which then would require updating this method to also a wrap up a corresponding write to Redis as well (like what postPayload(...) method does)
Signed-off-by: Yashvardhan Kukreja <yashvardhan@oplabs.co>
fd6c8de to
29f091b
Compare
Signed-off-by: Yashvardhan Kukreja <yashvardhan@oplabs.co>
Signed-off-by: Yashvardhan Kukreja <yashvardhan@oplabs.co>
Summary
ConsensusTrackerinterface withGetCLSyncBody/SetCLSyncBodymethods to store the CL consensus pin-backend'soptimism_syncStatusresponse bodyInMemoryConsensusTracker: stores the body with an RWMutex (preserves existing single-pod behavior)RedisConsensusTracker: the leader pod writes the selected sync body to Redis on each heartbeat; follower pods read it back, ensuring all pods behind a load balancer serve the sameoptimism_syncStatusresponsesyncStatusBodyMu,consensusSyncBody, andlastServedCLL1Numfields fromConsensusPoller, delegating to the tracker insteadRef: ethereum-optimism/core-team#2211
Test plan
go build ./...compiles cleanlygo test ./...passes (unit + integration tests)consensus_ha = trueandrouting_strategy = "consensus_aware_consensus_layer", verify all pods return identicaloptimism_syncStatusresponses🤖 Generated with Claude Code