feat(wraith): a full coordinator spills its tier to the next node in the order - #886
Merged
Conversation
…the order Rising demand now reaches more coordinators. A tier's leader takes every round until it runs MAX_LIVE_ROUNDS_PER_TIER at once; the next wallet is answered 503 `coordinator_full`, walks to the next node in the tier's order and joins there. Every wallet walks the same order, so the overflow gathers into one round on the next node rather than scattering; a busier tier spills further down. The demand-sized seat count this replaces never did that for a single tier — each tier routed to exactly one seat — and it was sized from a figure nodes could disagree about. Spilling needs no shared number: the only input is the answer the full coordinator gives. - Registry: live rounds (filling with an open window, locked, signing) are counted inside the same lock as the insert; an open round with room is still joined at the limit; a broadcast round holds no place. - Coordinator: at the limit, find_or_create answers 503 + coordinator_full and creates nothing. - Wallet: enrol walks the coordinator then its alternates, moving on only on coordinator_full (read from the error code, not the status) or unreachable; the round is then pinned to the acceptor (PreparedMix.coordinator_url) and submission goes there. Alternates are not standbys: they share no state. - Daemon: alternates come from the verified election — the rest of the tier's order after the chosen coordinator; a hand-typed coordinator gets none. #873 published the failover order and nothing walked it (the CLI printed it); the daemon now uses it. The limit (4) is a parameter, not a measurement.
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.
Follows #885 (every tier gets its own coordinator). Same release.
What this does
Rising demand now reaches more coordinators. A tier's leader takes every round until it's running
MAX_LIVE_ROUNDS_PER_TIER(4) at once. The next wallet is toldcoordinator_full, walks to the next node in the tier's order, and joins there. Every wallet on the tier walks the same order, so the overflow gathers into one real round on the next node rather than scattering. A busier tier spills further down the order, and more opted-in nodes get called and earn fees.The demand-sized seat count it replaces never did this for a single tier. Each tier was routed to exactly one seat (
shard(tier, epoch) mod seats), so seats beyond the four tiers could never get work. And the count came from each node's own snapshot of gossiped session counters, so nodes could disagree about it. Spilling needs no shared number: the only input is the answer the full coordinator gives.The pieces
MAX_LIVE_ROUNDS_PER_TIERandCOORDINATOR_FULL. The registry counts live rounds inside the same lock as the insert, so two concurrent callers can't both see room for one more. A filling round with room is still joined at the limit; the limit only stops a new round. Live means filling (window open), locked or signing; a round that's broadcast is only waiting for confirmations and doesn't hold a place.find_or_createanswers 503 +coordinator_fulland creates nothing.alternates, moving on only oncoordinator_fullor unreachable. Any other refusal is final. "Full" is read from the error code, not the status, so a proxy's bare 503 doesn't count.PreparedMix.coordinator_urlrecords it, and submit goes there. Alternates are kept separate frompeers: a peer is a standby that mirrors this coordinator's sessions and can take over mid-round, while an alternate is an independent coordinator that has never heard of the session.⚠ Stated rather than discovered
fallbacksand only the CLI printed them; a mix took a single URL. The daemon now uses the order.Verification
wraith_e2e): a wallet sent to a full leader enrols with the next node; and five wallets spilled off a full leader complete a whole round on the next node (join, sign, submit, broadcast), with the leader broadcasting nothing and creating nothing.coordinator_full, nothing created. Wallet: a proxy's bare 503 isn't full; the code under another status isn't full; a pinned client keeps standbys only for its own coordinator. Daemon: alternates follow the chosen node; a hand-typed coordinator gets none.scripts/mutate-wraith.shgains "a full coordinator keeps opening rounds": 31/31 caught.wraith-protocol,wraith-coordinator,wraith-wallet-core,wraith-wallet-daemon). The CI clippy invocation (all targets, includingghost-pool) andcargo doc -D warningsare clean.