struct PerSsaState {Show 21 fields
ssa_id: SsaId<HoprPseudonym>,
batch_id: u32,
phase: SsaPhase,
commitment_deadline: Option<Instant>,
recommit_deadline: Option<Instant>,
recommit_attempts: u8,
deposit_deadline: Option<Instant>,
recovery_idle_deadline: Option<Instant>,
recovery_hard_deadline: Option<Instant>,
deposit_uhopr: u64,
phase_entered_at: Instant,
largest_useful_shares: u64,
largest_shares_seen: u64,
target_useful_shares: u64,
recovered_polynomials: u16,
next_request_pending_deposit: bool,
next_requested: bool,
is_batch_last: bool,
recovered_pending: bool,
served_total_at_last_progress: u64,
served_total_at_front: Option<u64>,
}Expand description
Internal state for one supervised SSA.
Fields§
§ssa_id: SsaId<HoprPseudonym>§batch_id: u32First SSA index allocated in this request batch.
phase: SsaPhase§commitment_deadline: Option<Instant>§recommit_deadline: Option<Instant>When to re-request the parts of this commitment that have not arrived, or None while there
is nothing to ask for.
Set only once some of the commitment has arrived, and pushed out by every further part, so
it measures silence in the delivery rather than elapsed time. A cycle for which nothing was
ever delivered leaves it unset and dies on commitment_deadline, which is all the Exit can
do about one: it has no scope to name.
recommit_attempts: u8Re-requests already made for this cycle, capped at
MAX_COMMITMENT_RETRANSMISSIONS.
The cap is a count and not a duration on purpose. commitment_deadline bounds the asks in
time, which is what protects the Entry, but the packets they cost are this node’s own: at a
misconfigured millisecond interval inside a 20-second deadline the time bound alone permits
twenty thousand of them. Matching the figure the Entry will answer means none of the asks is
wasted either.
deposit_deadline: Option<Instant>§recovery_idle_deadline: Option<Instant>§recovery_hard_deadline: Option<Instant>§deposit_uhopr: u64What the Entry deposited for this cycle, in µHOPR, or zero until the deposit confirms.
phase_entered_at: InstantWhen phase was entered, for hopr_pix_cycle_phase_seconds.
Largest shares_seen observed for this cycle — the liveness counter, which moves for surplus
shares too. Also the staleness discriminator for snapshots, since it moves for every share
while largest_useful_shares does not.
recovered_polynomials: u16§next_request_pending_deposit: bool§next_requested: bool§is_batch_last: boolSet on the last cycle allocated by SessionPixSupervisor::emit_request_next_ssa, and only
on that one.
The successor gate: a batch asks for its replacement once, when its last cycle is nearly
recovered. Every other flag here is per-cycle, so without this one each member of a batch
would answer its own AlmostRecovered with a whole batch of its own — ssas_per_request
batches per batch, compounding, each cycle a separate on-chain deposit for the Entry.
The last cycle rather than the first because the batch is served in index order: gating on
the first would ask for the successor a whole batch too early, which is the exposure
ssas_per_request deliberately bounds.
If the two-generation admission bound defers that request, next_requested remains set and
the supervisor-level successor_request_deferred flag owns the retry; the gate must not be
handed to another cycle and spend the request twice.
recovered_pending: boolSet when Recovered arrives before deposit confirms (i.e. during
AwaitingCommitment or AwaitingDeposit). Once deposit is confirmed
and the SSA enters Recovering, this flag triggers an immediate
tombstone transition — replaying the deferred Recovered event.
served_total_at_last_progress: u64§served_total_at_front: Option<u64>The Session’s served count when this cycle reached the front of the batch, or None while
it is still queued behind one.
Subtracted from the served count at finalization to give the cycle’s own egress. Baselined
at the front rather than at the request, because a queued cycle is not being served: the
Entry’s emission window is clamped to one cycle, so charging a batch member for everything
its predecessors consumed would report the last cycle of a batch as having cost the whole
batch. None on a cycle that never reached the front is therefore the honest answer, and it
is reported as zero egress rather than as the Session’s whole history.
Implementations§
Source§impl PerSsaState
impl PerSsaState
fn new( ssa_id: SsaId<HoprPseudonym>, batch_id: u32, target_useful_shares: u64, now: Instant, ) -> Self
Sourcefn enter_phase(
&mut self,
phase: SsaPhase,
now: Instant,
) -> Option<(PixCyclePhase, u64)>
fn enter_phase( &mut self, phase: SsaPhase, now: Instant, ) -> Option<(PixCyclePhase, u64)>
Moves to phase, returning how long the outgoing one lasted in milliseconds.
None for an outgoing Recovered or Closing, which have no PixCyclePhase label — both
are retained state rather than live state, so neither is measured.
Sourcefn telemetry_summary(
&self,
outcome: PixCycleOutcome,
served_total: u64,
) -> PixCycleSummary
fn telemetry_summary( &self, outcome: PixCycleOutcome, served_total: u64, ) -> PixCycleSummary
This cycle’s coverage, for the histograms observed once when it finalizes.
Sourcefn is_terminal(&self) -> bool
fn is_terminal(&self) -> bool
True if this SSA is past the recovery phase.
Source§impl PerSsaState
impl PerSsaState
Sourcefn check_deadlines(&self, now: Instant) -> Option<SessionPixCloseReason>
fn check_deadlines(&self, now: Instant) -> Option<SessionPixCloseReason>
Check which deadline expired, if any.
Auto Trait Implementations§
impl Freeze for PerSsaState
impl RefUnwindSafe for PerSsaState
impl Send for PerSsaState
impl Sync for PerSsaState
impl Unpin for PerSsaState
impl UnsafeUnpin for PerSsaState
impl UnwindSafe for PerSsaState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.