Frontier

Struct Frontier 

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

Management of the transaction pool frontier, that is, the set of transactions in the transaction pool which have no mempool ancestors and are essentially ready to enter the next block template.

Implementations§

Source§

impl Frontier

Source

pub fn total_weight(&self) -> f64

Source

pub fn total_mass(&self) -> u64

Source

pub fn len(&self) -> usize

Source

pub fn is_empty(&self) -> bool

Source

pub fn insert(&mut self, key: FeerateTransactionKey) -> bool

Source

pub fn remove(&mut self, key: &FeerateTransactionKey) -> bool

Source

pub fn sample_inplace<R>( &self, rng: &mut R, policy: &Policy, _collisions: &mut u64, ) -> SequenceSelectorInput
where R: Rng + ?Sized,

Samples the frontier in-place based on the provided policy and returns a SequenceSelector.

This sampling algorithm should be used when frontier total mass is high enough compared to policy mass limit so that the probability of sampling collisions remains low.

Convergence analysis: 1. Based on the above we can safely assume that k << n, where n is the total number of frontier items and k is the number of actual samples (since desired_mass << total_mass and mass per item is bounded) 2. Indeed, if the weight distribution is not too spread (i.e., max(weights) = O(min(weights))), k << n means that the probability of collisions is low enough and the sampling process will converge in O(k log(n)) w.h.p. 3. It remains to deal with the case where the weight distribution is highly biased. The process implemented below keeps track of the top-weight element. If the distribution is highly biased, this element will be sampled with sufficient probability (in constant time). Following each sampling collision we search for a consecutive range of top elements which were already sampled and narrow the sampling space to exclude them all. We do this by computing the prefix weight up to the top most item which wasn’t sampled yet (inclusive) and then continue the sampling process over the narrowed space. This process is repeated until acquiring the desired mass.
4. Numerical stability. Naively, one would simply subtract total_weight -= top.weight in order to narrow the sampling space. However, if top.weight is much larger than the remaining weight, the above f64 subtraction will yield a number close or equal to zero. We fix this by implementing a log(n) prefix weight operation. 5. Q. Why not just use u64 weights? A. The current weight calculation is feerate^alpha with alpha=3. Using u64 would mean that the feerate space is limited to a range of size (2^64)^(1/3) = ~2^21 = ~2M. Already with current usages, the feerate can vary from ~1/50 (2000 sompi for a transaction with 100K storage mass), to 5M (100 KAS fee for a transaction with 2000 mass = 100·100_000_000/2000), resulting in a range of size 250M (5M/(1/50)). By using floating point arithmetics we gain the adjustment of the probability space to the accuracy level required for current samples. And if the space is highly biased, the repeated elimination of top items and the prefix weight computation will readjust it.

Source

pub fn build_selector( &self, policy: &Policy, ) -> Box<dyn TemplateTransactionSelector>

Dynamically builds a transaction selector based on the specific state of the ready transactions frontier.

The logic is divided into three cases: 1. The frontier is small and can fit entirely into a block: perform no sampling and return a TakeAllSelector 2. The frontier has at least ~4x the capacity of a block: expected collision rate is low, perform in-place k*log(n) sampling and return a SequenceSelector 3. The frontier has 1-4x capacity of a block. In this case we expect a high collision rate while the number of overall transactions is still low, so we take all of the transactions and use the rebalancing weighted selector (performing the actual sampling out of the mempool lock)

The above thresholds were selected based on benchmarks. Overall, this dynamic selection provides full transaction selection in less than 150 µs even if the frontier has 1M entries (!!). See mining/benches for more details.

Source

pub fn build_selector_sample_inplace( &self, _collisions: &mut u64, ) -> Box<dyn TemplateTransactionSelector>

Exposed for benchmarking purposes

Source

pub fn build_selector_take_all(&self) -> Box<dyn TemplateTransactionSelector>

Exposed for benchmarking purposes

Source

pub fn build_rebalancing_selector(&self) -> Box<dyn TemplateTransactionSelector>

Exposed for benchmarking purposes

Source

pub fn build_feerate_estimator( &self, args: FeerateEstimatorArgs, ) -> FeerateEstimator

Builds a feerate estimator based on internal state of the ready transactions frontier

Source

pub fn ascending_iter( &self, ) -> impl DoubleEndedIterator<Item = &Arc<Transaction>> + ExactSizeIterator + FusedIterator

Returns an iterator to the transactions in the frontier in increasing feerate order

Trait Implementations§

Source§

impl Default for Frontier

Source§

fn default() -> Frontier

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

Auto Trait Implementations§

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Source§

fn type_name(&self) -> &'static str

Source§

impl<T> AnySync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
Source§

impl<S> CastArc for S
where S: CastFromSync + ?Sized,

Source§

fn cast<T>(self: Arc<S>) -> Result<Arc<T>, Arc<S>>
where T: 'static + ?Sized,

Casts an Arc for this trait into that for type T.
Source§

impl<S> CastBox for S
where S: CastFrom + ?Sized,

Source§

fn cast<T>(self: Box<S>) -> Result<Box<T>, Box<S>>
where T: 'static + ?Sized,

Casts a box to this trait into that of type T. If fails, returns the receiver.
Source§

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

Source§

fn ref_any(&self) -> &(dyn Any + 'static)

Returns a immutable reference to Any, which is backed by the type implementing this trait.
Source§

fn mut_any(&mut self) -> &mut (dyn Any + 'static)

Returns a mutable reference to Any, which is backed by the type implementing this trait.
Source§

fn box_any(self: Box<T>) -> Box<dyn Any>

Returns a Box of Any, which is backed by the type implementing this trait.
Source§

fn rc_any(self: Rc<T>) -> Rc<dyn Any>

Returns an Rc of Any, which is backed by the type implementing this trait.
Source§

impl<T> CastFromSync for T
where T: Sync + Send + 'static,

Source§

fn arc_any(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Source§

impl<S> CastMut for S
where S: CastFrom + ?Sized,

Source§

fn cast<T>(&mut self) -> Option<&mut T>
where T: 'static + ?Sized,

Casts a mutable reference to this trait into that of type T.
Source§

impl<S> CastRc for S
where S: CastFrom + ?Sized,

Source§

fn cast<T>(self: Rc<S>) -> Result<Rc<T>, Rc<S>>
where T: 'static + ?Sized,

Casts an Rc for this trait into that for type T.
Source§

impl<S> CastRef for S
where S: CastFrom + ?Sized,

Source§

fn cast<T>(&self) -> Option<&T>
where T: 'static + ?Sized,

Casts a reference to this trait into that of type T.
Source§

fn impls<T>(&self) -> bool
where T: 'static + ?Sized,

Tests if this trait object can be cast into T.
Source§

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

Source§

fn exact_from(value: T) -> U

Source§

impl<T, U> ExactInto<U> for T
where U: ExactFrom<T>,

Source§

fn exact_into(self) -> U

§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

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

impl<T, U> OverflowingInto<U> for T
where U: OverflowingFrom<T>,

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

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

Initializes a with the given initializer. Read more
Source§

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

Dereferences the given pointer. Read more
Source§

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

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

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

impl<T, U> RoundingInto<U> for T
where U: RoundingFrom<T>,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> SaturatingInto<U> for T
where U: SaturatingFrom<T>,

§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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

§

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

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

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

Performs the conversion.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T, U> WrappingInto<U> for T
where U: WrappingFrom<T>,

Source§

fn wrapping_into(self) -> U

Source§

impl<T> UnsafeAny for T
where T: Any,