pub const SHARE_EMISSION_WINDOW: usize = 256;Expand description
Number of polynomials the generator emits shares for concurrently.
Shares are emitted round-robin across the first SHARE_EMISSION_WINDOW polynomials of the
queue rather than draining one polynomial to exhaustion before starting the next. Both orderings
emit exactly the same shares — every share carries its own SsaPolynomialId, which the Exit
files by, so arrival order is irrelevant to reconstruction — but they fail very differently.
A share only reaches the reconstructor when the Exit uses the SURB carrying it, so a SURB
dropped from the Exit’s per-pseudonym ring buffer is a permanently lost share. That buffer
overwrites its oldest entries, which is a contiguous run of the emission order. Draining one
polynomial at a time makes such a run land on a single polynomial: lose more than
surplus_shares of it and it can never reach threshold, and since the SSA is the sum of
every polynomial’s constant term, the whole cycle becomes unrecoverable — silently, because a
starved polynomial never fails a check, it simply never completes. Round-robin spreads the same
run across the window, so a contiguous loss of up to surplus_shares × SHARE_EMISSION_WINDOW
shares is absorbed by the surplus that exists for exactly this purpose.
The window is bounded rather than spanning the whole SSA because the Exit holds a part builder’s
collected shares until that part reconstructs (release_verification_state). One polynomial at
a time keeps one part live; the full 8192 would keep every part live at once, polys × threshold
shares of peak memory. 256 keeps that peak around a megabyte while covering a contiguous loss
far larger than the ring buffer’s entire overshoot allowance.
§The window never crosses a cycle boundary
It is clamped to the polynomials of the cycle at the front of the queue, so no share for cycle
k + 1 is ever emitted while any polynomial of cycle k is unexhausted. That is what lets an
Exit treat progress on a later cycle as misbehaviour rather than as a boundary artefact: a batch
of n cycles is served as n separate quotas, so the Exit is exposed to one cycle’s worth of
unpaid traffic at a time instead of n. An Entry free to spread shares across a whole batch could
take n × quota of service while leaving every cycle short of recovery — and since an SSA is the
sum of every polynomial’s constant term, a cycle short of recovery is worth nothing at all.
The clamp costs no loss tolerance while polynomials_per_ssa is a multiple of the window, which
the deployed 8192 is: polynomials in the window advance in lockstep, so a cycle drains as
polys / window full-width blocks and the last one is swept out inside a single next_share
call. A cycle whose polynomial count is not a multiple runs its final partial block at that
remainder’s width, absorbing a proportionally shorter contiguous loss.