pub struct PixGlobalConfig {
pub num_ssa_parts: usize,
pub ssa_part_size: usize,
pub additional_shares: Option<usize>,
pub max_ssas_per_request: usize,
pub reconstructor: PixReconstructorConfig,
}Expand description
Global configuration for the Protocol for Incentivization of eXits (PIX).
Fields§
§num_ssa_parts: usizeNumber of parts an SSA is split into.
This scales will with the CPU parallelism.
Defaults to DEFAULT_PIX_POLYS_PER_SSA, which is also what
IncomingSessionPixConfig::quota_range is derived from — changing this without
widening the peer Exit’s quota_range accordingly will get the Session rejected.
The range below bounds this field alone. What actually costs is the product with
ssa_part_size, which validation bounds separately at 4× the profiled
operating point — see validate_pix_dimension_product.
ssa_part_size: usizeNumber of shares required to reconstruct an SSA part.
This does not scale well with CPU parallelism.
Defaults to DEFAULT_PIX_SHARES_PER_POLY. See num_ssa_parts
for the interaction with the Exit’s accepted quota range, and
validate_pix_dimension_product for the bound on the two together.
Capped at 255 because the threshold is one byte of the negotiated
PixParams word — see
MAX_POLY_THRESHOLD.
Number of shares sent in addition to ssa_part_size to reconstruct an SSA part.
This is used to account for potential packet loss but makes it take longer for the other side to reconstruct the entire SSA from all its parts. This is because if no packet loss is present, the other side can reconstruct the SSA from fewer shares.
Leave unset unless you have measured your return-path loss. None derives the surplus
from ssa_part_size via
default_surplus_for, which sizes it to absorb
20 % of a polynomial’s shares going missing. Read
surplus_shares for the resolved value.
It is a ratio because the physics is a ratio: a polynomial reconstructs from the first
ssa_part_size distinct shares to arrive out of ssa_part_size + surplus emitted, so
surviving loss rate p needs surplus >= ssa_part_size · p/(1−p). Setting an absolute count
therefore means a different loss tolerance at every threshold — a flat 20 covers 24 % at
ssa_part_size 64 but 56 % at 16, where it exceeds the shares it insures and is rejected.
The factor is what matters, because it is what this costs. A polynomial leaves the
generator’s queue at ssa_part_size + surplus shares whether or not any were
lost, so this is service the Exit performs in every case — and since the surplus travels to
the peer as part of the negotiated PixParams, the per-SSA
quota counts it and the deposit pays for it. It buys loss tolerance, and it is charged for
like any other insurance: on purchase, not on claim.
Raising it therefore costs money rather than earning free service, which is the way round it should be. It used to be the other way: the surplus was excluded from the quota, so the rational Entry raised this dial to take traffic it was not billed for.
Capped at 255 because it is the other byte of that word, and at ssa_part_size because
insurance costing more than the payload is a misconfiguration rather than a preference.
max_ssas_per_request: usizeMaximum number of SSA commitments this node, acting as an Entry, accepts in a single
SsaRequest from an Exit.
This is a protection against a misbehaving Exit rather than a preference: each accepted entry
costs a full client commitment, its own burst of SsaCommit packets and its own on-chain
deposit, so an uncapped request would let one inbound packet amplify into minutes of CPU and
as many simultaneous deposits as the wire format admits (27). An over-cap request is rejected
in full before any of that work starts.
Must be at least the ssas_per_request of every Exit this node uses. The batch size is not
negotiated — the Exit cannot learn this value — so an Exit batching above it has every request
rejected, and every such Session is lost. The refusal is reported to the Exit as an
UnacceptablePixParams SessionError so it fails in about a round trip rather than as a
deposit timeout minutes later, but raising the Exit side still requires raising this in step.
Unlike its neighbours this is not a dimension, so validate_pix_dimension_product ignores it.
Defaults to 2, minimum 1, maximum 20 (MAX_SSA_BATCH_SIZE).
reconstructor: PixReconstructorConfigExit-side SSA reconstructor configuration.
Nested rather than flattened so the whole PIX surface stays under one key, and so that Exit-side capacity does not intermix with the Entry-side dimensions above.
Implementations§
Source§impl PixGlobalConfig
impl PixGlobalConfig
Surplus shares per polynomial: the operator’s value if set, otherwise derived from
ssa_part_size.
Every reader must go through this rather than the field. The field is Option precisely
because serde cannot express “default to a function of a sibling”, so the field alone is not
the configuration — reading it directly is how the unset case would silently become zero
surplus, i.e. no loss tolerance at all.
Trait Implementations§
Source§impl Clone for PixGlobalConfig
impl Clone for PixGlobalConfig
Source§fn clone(&self) -> PixGlobalConfig
fn clone(&self) -> PixGlobalConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for PixGlobalConfig
Source§impl Debug for PixGlobalConfig
impl Debug for PixGlobalConfig
Source§impl Default for PixGlobalConfig
impl Default for PixGlobalConfig
Source§impl PartialEq for PixGlobalConfig
impl PartialEq for PixGlobalConfig
impl StructuralPartialEq for PixGlobalConfig
Auto Trait Implementations§
impl Freeze for PixGlobalConfig
impl RefUnwindSafe for PixGlobalConfig
impl Send for PixGlobalConfig
impl Sync for PixGlobalConfig
impl Unpin for PixGlobalConfig
impl UnsafeUnpin for PixGlobalConfig
impl UnwindSafe for PixGlobalConfig
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§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.