Skip to main content

SsaShareGenerator

Struct SsaShareGenerator 

Source
pub struct SsaShareGenerator<S: PixSpec> {
    polynomials: Cache<S::Pseudonym, Arc<Mutex<SsaPseudonymEntry<S>>>, RandomState>,
    cfg: SsaGeneratorConfig,
}
Expand description

Generator for Session Stealth Address (SSA) shares distributed over Single Use Reply Blocks (SURBs).

Fields§

§polynomials: Cache<S::Pseudonym, Arc<Mutex<SsaPseudonymEntry<S>>>, RandomState>§cfg: SsaGeneratorConfig

Implementations§

Source§

impl<S: PixSpec> SsaShareGenerator<S>

Source

pub fn try_new(cfg: SsaGeneratorConfig) -> Result<Self, S::Pseudonym>

Creates a new share generator with the provided configuration.

Fails if the configuration does not validate. Prefer this over Self::new anywhere the configuration is assembled at runtime — a config built programmatically or read from a file is input, not a constant, and turning it into a panic makes it un-handleable by the caller.

Source

pub fn new(cfg: SsaGeneratorConfig) -> Self

Creates a new share generator with the provided configuration.

§Panics

Panics if the configuration fails validation. Use Self::try_new to handle that case instead.

Source

pub fn config(&self) -> &SsaGeneratorConfig

Returns the configuration used to generate this SsaShareGenerator.

Source

pub fn forget(&self, pseudonym: &S::Pseudonym)

Discards all polynomial state held for pseudonym.

The same observable state the cache’s own idle retention produces, reached deliberately: no further share can be emitted for any cycle of this pseudonym, and emission_progress goes back to None.

The distinction that state has been lost rather than never created is not recoverable from here — an evicted entry leaves nothing behind — so a caller that needs it has to hold the fact itself, for as long as it needs it to mean something. hopr-transport-session keeps it per Session, because a successor SsaRequest arriving against lost state is indistinguishable from the opening one otherwise, and the two must not be answered alike.

Source

pub fn emission_progress( &self, pseudonym: &S::Pseudonym, ) -> Option<EmissionProgress>

How far share emission has got for pseudonym.

None when nothing has been committed for the pseudonym yet.

Exists so an Entry can refuse to commit to another batch while emission has not yet reached the end of the batch it is already serving — an Exit asking earlier is asking for deposits it cannot have earned yet. Emission rather than reconstruction, because the Entry never learns what the Exit actually recovered.

Because the window is clamped to one cycle (see SHARE_EMISSION_WINDOW), is_serving_last_committed means every earlier cycle is exhausted — exactly, at every dimension, rather than approximately near a boundary. It becomes true on the last cycle’s first share, though, so it answers “which cycle” and not “how far in”; front_fraction is the second half, and an admission rule needs both.

Source

pub fn recommit( &self, pseudonym: &S::Pseudonym, ssa_index: SsaIndex, runs: impl IntoIterator<Item = (PolynomialIndex, PolynomialIndex)>, ) -> Result<SsaCommitment<S>, S::Pseudonym>

Rebuilds the commitment of an already-committed cycle, restricted to the polynomial indices the peer says it never received.

A cycle’s commitment ships as hundreds of packets and the peer can use it only once every one of them has landed. Nothing else in the protocol repairs a lost packet: the peer cannot reconstruct the missing commitment, and this side cannot tell which one went missing — so without this a single drop costs a cycle the peer has usually already been told to fund. The peer names the gaps, this fills them.

The result is shaped exactly like new_ssa_commitment’s, so the caller re-sends it through the same message splitting, carrying the same bytes and the same proof. It advances no state the peer is charged for: no new index, no new polynomial, and no second deposit — the caller must not announce one, since the address is unchanged and was announced when the cycle was first committed.

Each run is an inclusive (first, last) polynomial-index pair, expected ascending and disjoint. Indices this cycle does not have are skipped.

§Errors
  • PixError::MissingSsaCommitment — nothing retained for ssa_index. Either it was never committed, or MAX_RETAINED_COMMITMENT_CYCLES newer cycles have pushed it out. Having exhausted a cycle’s polynomials does not put it here: whether a repair still helps depends on what the peer holds, not on what this side can still emit.
  • PixError::InvalidInput — MAX_COMMITMENT_RETRANSMISSIONS answers have already been given for this cycle, or runs selects nothing. The cap is what keeps a peer that has already been served from farming whole bursts out of this node; a request that selects nothing still spends an attempt, so malformed scopes are not free either.

Trait Implementations§

Source§

impl<S: PixSpec> Default for SsaShareGenerator<S>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<S: PixSpec> EntryShareGenerator<S> for SsaShareGenerator<S>

Source§

fn next_share( &self, pseudonym: &S::Pseudonym, msg: &impl AsRef<[u8]>, ) -> Result<Option<GeneratedShare<S>>, S::Pseudonym>

Generate the next PartialSsaShare for the given pseudonym and message msg.

IMPORTANT: Each msg MUST be unique for a given pseudonym.

Returns None if all polynomials for the given pseudonym have been used up. This signals that a new SSA must be committed.

Source§

fn new_ssa_commitment( &self, pseudonym: &S::Pseudonym, ssa_index: SsaIndex, ) -> Result<SsaCommitment<S>, S::Pseudonym>

Generates a new SSA commitment from the sender side, for the given pseudonym.

Returns the new random SSA-commitment and the corresponding SSA share verifier.

Source§

type Error = PixError<<S as PixSpec>::Pseudonym>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more