Skip to main content

NonceManager

Struct NonceManager 

Source
pub struct NonceManager { /* private fields */ }
Expand description

Thread-safe sequential nonce allocator keyed by (account_index, api_key_index).

Construct with NonceManager::new (or NonceManager::default for DEFAULT_SKIP_WINDOW) and seed each key via NonceManager::refresh from the nextNonce REST endpoint before calling NonceManager::next_nonce.

Implementations§

Source§

impl NonceManager

Source

pub fn new(skip_window: u32) -> Self

Construct a manager with an explicit skip_window tolerance.

Source

pub fn skip_window(&self) -> u32

Configured outstanding-allocation bound.

Source

pub fn refresh( &self, account_index: i64, api_key_index: u8, venue_next_nonce: i64, )

Seed (or hard-reset) the nonce baseline for a key.

venue_next_nonce is what the venue’s nextNonce endpoint reports as the next expected nonce for (account_index, api_key_index). After this call, the very next NonceManager::next_nonce for the same key returns venue_next_nonce.

Call this once at startup, and again after a venue rejection signals the local view is stale (mirrors hard_refresh_nonce in the Python reference).

Caller contract: refresh is a control-plane operation and is not mutually exclusive with concurrent NonceManager::next_nonce calls on the same key. A next_nonce that started before refresh may still complete with a pre-refresh value. The Python reference makes the same trade-off; callers that need exclusive semantics must serialize refresh against in-flight allocations themselves (typically by quiescing submission before issuing a hard refresh).

Source

pub fn sync_from_venue( &self, account_index: i64, api_key_index: u8, venue_next_nonce: i64, ) -> Result<(), NonceError>

Monotonically advance the baseline toward the venue’s reported nextNonce without ever moving state backwards.

Unlike NonceManager::refresh, which hard-resets both baseline and last_issued and can therefore reissue nonces already signed into in-flight transactions, this method only lifts values: it is safe to call while submissions are in flight. Use it to recover from NonceError::SkipWindowExhausted when the venue may have applied transactions whose acks never reached the manager (for example HTTP sendTxBatch submissions).

last_issued is lifted before baseline so a concurrent NonceManager::next_nonce never observes a baseline ahead of last_issued, which would make it hand out nonces the venue has already consumed.

§Errors

Returns NonceError::NotInitialized if NonceManager::refresh has not run for this key.

Source

pub fn next_nonce( &self, account_index: i64, api_key_index: u8, ) -> Result<i64, NonceError>

Allocate the next nonce for (account_index, api_key_index).

Returns the issued integer on success. Errors with NonceError::NotInitialized if NonceManager::refresh has not run for this key, and with NonceError::SkipWindowExhausted if the number of nonces already issued past the last baseline exceeds NonceManager::skip_window. The CAS loop guarantees monotonic, gap-free issuance under contention; concurrent callers serialize through the atomic compare-exchange.

Source

pub fn ack_success( &self, account_index: i64, api_key_index: u8, nonce: i64, ) -> Result<(), NonceError>

Record a venue success ack for nonce, monotonically advancing the baseline to max(baseline, nonce).

The venue has applied the acked transaction, so every nonce up to and including nonce no longer counts against the skip window. The advance is a monotonic max: a misattributed ack (one that pops the wrong pending entry) can only open the window early, never shrink it or cause a nonce to be reissued, because acked nonces are always ones this manager issued.

§Errors

Returns NonceError::NotInitialized if NonceManager::refresh has not run for this key.

Source

pub fn ack_failure( &self, account_index: i64, api_key_index: u8, ) -> Result<i64, NonceError>

Roll back the most recently issued nonce for the given key.

Mirrors acknowledge_failure in the Python reference: when the venue rejects a tx outside the “stale nonce” path, the manager decrements last_issued so the next NonceManager::next_nonce reuses the freed integer. Errors with NonceError::NothingToRollBack when called while last_issued == baseline.

Caller contract: only the most recent issuance may be rolled back, and only before any newer nonce reaches the wire. Callers that cannot guarantee this (any path with multiple in-flight txs) must use NonceManager::ack_failure_if_latest instead.

Source

pub fn ack_failure_if_latest( &self, account_index: i64, api_key_index: u8, nonce: i64, ) -> Result<bool, NonceError>

Roll back nonce only when it is still the most recent issuance.

Returns Ok(true) when last_issued was decremented from nonce to nonce - 1, and Ok(false) when the rollback was skipped: either a newer nonce has been issued (so decrementing would free an integer already signed into an in-flight tx, and the next allocation would duplicate it on the wire), or the baseline has already advanced to nonce (the venue applied it, so the failure signal is stale). A skipped rollback leaves a gap that heals through NonceManager::ack_success or NonceManager::sync_from_venue.

§Errors

Returns NonceError::NotInitialized if NonceManager::refresh has not run for this key.

Source

pub fn last_issued(&self, account_index: i64, api_key_index: u8) -> Option<i64>

Snapshot the last issued nonce for diagnostic and test purposes.

Source

pub fn baseline(&self, account_index: i64, api_key_index: u8) -> Option<i64>

Snapshot the configured baseline for diagnostic and test purposes.

Trait Implementations§

Source§

impl Debug for NonceManager

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for NonceManager

Source§

fn default() -> Self

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

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> 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> 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<T> Ungil for T
where T: Send,

§

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