Fix multi-leader jitter target receding instead of anchoring to round start#6484
Closed
ma2bd wants to merge 1 commit into
Closed
Fix multi-leader jitter target receding instead of anchoring to round start#6484ma2bd wants to merge 1 commit into
ma2bd wants to merge 1 commit into
Conversation
pull Bot
pushed a commit
to Spencerx/linera-protocol
that referenced
this pull request
Jun 18, 2026
## Motivation `main` still runs multi-leader jitter (linera-io#6289, plus the default bump in linera-io#6359). On `testnet_conway` the jitter variant (linera-io#6338) was reverted in linera-io#6433 ("We found several issues in the PR") following the 2026-05-29 PM-market incident. This brings `main` in line by backing the feature out here too. **Alternatively we could try to fix things with linera-io#6484** ## Proposal `git revert` of linera-io#6289 ("Multi-leader jitter"). Because `main`'s jitter is a different commit than the one reverted on `testnet_conway` (linera-io#6338 was the testnet variant), this is a fresh revert rather than a cherry-pick of linera-io#6433. Scope is jitter only: - Removes `multi_leader_jitter_target` (chain client), `multi_leader_proposal_delay` (ownership), and the `--multi-leader-jitter` client option. - **Keeps** the `multi_leader_rounds` default change (linera-io#6359, 2 → 5) — unrelated to jitter. One conflict in `chain_client/mod.rs` (the seam where linera-io#6289 inserted the jitter fn before `clear_pending_proposal`) was resolved by keeping `main`'s current `clear_pending_proposal` definition. ## Test Plan - `cargo build` / `cargo check` clean on `linera-base`, `linera-core`, `linera-client`. - `cargo clippy --all-targets` clean (no dangling references to removed jitter symbols anywhere in the tree). - `cargo test -p linera-base ownership` green. - CI. ## Release Plan - These changes follow the usual release cycle. (`testnet_conway` already reverted the equivalent change.) ## Links - Reverts: linera-io#6289 - Mirrors the `testnet_conway` revert: linera-io#6433 (which reverted the testnet variant linera-io#6338) - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist)
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Motivation
Forward-port of #6431 (which targeted
testnet_conway) tomain. The bug it fixes exists onmaintoo.This is an experimental alternative solution to a full revert as in #6455
On 2026-05-29 several PM market chains froze: each was stuck in a multi-leader round, never committing a block, which crash-looped the workers via the idle-chain liveness probe. Disabling multi-leader jitter on the workers recovered them, pinpointing the jitter path.
Root cause is in
multi_leader_jitter_target(linera-core/src/client/chain_client/mod.rs) added by #6338. It anchors the proposal delay to the current time whenever the round start cannot be derived from a round timeout:ChainOwnership::round_timeout(round)returnsNonefor every multi-leader round except the last (linera-base/src/ownership.rs). The affected chains runmulti_leader_rounds = 1000, so this is essentially every round.nowwhen proposing in a round different from the manager's current round (the conflict-bump case).With the anchor at
now,propose_at = now + delayis recomputed on every call. On a busy chainprocess_inboxruns constantly — each inbox notification interrupts the wait and re-evaluates — so the target recedes bydelayevery time and the non-preferred sole proposer never reaches it.round_for_new_proposalreturnsWaitForTimeoutforever, the worker never proposes, and the chain wedges.Proposal
When the round start cannot be derived from a timeout, anchor to the time the round was first observed (remembered per round in a new in-memory
jitter_round_anchorfield) instead ofnow. Thenpropose_atis a fixed point the clock catches up to: the worker waits out the jitter delay once and proposes. Theround_timeout − durationderivation is unchanged where it already worked (single-leader rounds, final multi-leader round).The pure timing logic is extracted into a free
multi_leader_jitter_targetfunction (the method becomes a thin adapter reading the clock + anchor) so it can be unit-tested.Backward compatible: this changes only local proposal timing — no wire format, consensus rule, or persisted state changes. Mixed-version clients/validators interoperate.
Test Plan
multi_leader_jitter_target_is_anchored_not_receding: in a non-final multi-leader round, the target stays fixed as the clock advances, and the owner proposes once the clock reaches it.cargo clippy -p linera-core --all-targetsclean;cargo +nightly fmt --checkclean.Release Plan
Links