mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-23 12:09:52 +00:00
71 lines
3.1 KiB
Rust
71 lines
3.1 KiB
Rust
|
//! # Dandelion Tower
|
||
|
//!
|
||
|
//! This crate implements [dandelion++](https://arxiv.org/pdf/1805.11060.pdf), using [`tower`].
|
||
|
//!
|
||
|
//! This crate provides 2 [`tower::Service`]s, a [`DandelionRouter`] and a [`DandelionPool`](pool::DandelionPool).
|
||
|
//! The router is pretty minimal and only handles the absolute necessary data to route transactions, whereas the
|
||
|
//! pool keeps track of all data necessary for dandelion++ but requires you to provide a backing tx-pool.
|
||
|
//!
|
||
|
//! This split was done not because the [`DandelionPool`](pool::DandelionPool) is unnecessary but because it is hard
|
||
|
//! to cover a wide range of projects when abstracting over the tx-pool. Not using the [`DandelionPool`](pool::DandelionPool)
|
||
|
//! requires you to implement part of the paper yourself.
|
||
|
//!
|
||
|
//! # Features
|
||
|
//!
|
||
|
//! This crate only has one feature `txpool` which enables [`DandelionPool`](pool::DandelionPool).
|
||
|
//!
|
||
|
//! # Needed Services
|
||
|
//!
|
||
|
//! To use this crate you need to provide a few types.
|
||
|
//!
|
||
|
//! ## Diffuse Service
|
||
|
//!
|
||
|
//! This service should implement diffusion, which is sending the transaction to every peer, with each peer
|
||
|
//! having a timer using the exponential distribution and batch sending all txs that were queued in that time.
|
||
|
//!
|
||
|
//! The diffuse service should have a request of [`DiffuseRequest`](traits::DiffuseRequest) and it's error
|
||
|
//! should be [`tower::BoxError`].
|
||
|
//!
|
||
|
//! ## Outbound Peer Discoverer
|
||
|
//!
|
||
|
//! The outbound peer [`Discover`](tower::discover::Discover) should provide a stream of randomly selected outbound
|
||
|
//! peers, these peers will then be used to route stem txs to.
|
||
|
//!
|
||
|
//! The peers will not be returned anywhere, so it is recommended to wrap them in some sort of drop guard that returns
|
||
|
//! them back to a peer set.
|
||
|
//!
|
||
|
//! ## Peer Service
|
||
|
//!
|
||
|
//! This service represents a connection to an individual peer, this should be returned from the Outbound Peer
|
||
|
//! Discover. This should immediately send the transaction to the peer when requested, i.e. it should _not_ set
|
||
|
//! a timer.
|
||
|
//!
|
||
|
//! The diffuse service should have a request of [`StemRequest`](traits::StemRequest) and it's error
|
||
|
//! should be [`tower::BoxError`].
|
||
|
//!
|
||
|
//! ## Backing Pool
|
||
|
//!
|
||
|
//! ([`DandelionPool`](pool::DandelionPool) only)
|
||
|
//!
|
||
|
//! This service is a backing tx-pool, in memory or on disk.
|
||
|
//! The backing pool should have a request of [`TxStoreRequest`](traits::TxStoreRequest) and a response of
|
||
|
//! [`TxStoreResponse`](traits::TxStoreResponse), with an error of [`tower::BoxError`].
|
||
|
//!
|
||
|
//! Users should keep a handle to the backing pool to request data from it, when requesting data you _must_
|
||
|
//! make sure you only look in the public pool if you are going to be giving data to peers, as stem transactions
|
||
|
//! must stay private.
|
||
|
//!
|
||
|
//! When removing data, for example because of a new block, you can remove from both pools provided it doesn't leak
|
||
|
//! any data about stem transactions. You will probably want to set up a task that monitors the tx pool for stuck transactions,
|
||
|
//! transactions that slipped in just as one was removed etc, this crate does not handle that.
|
||
|
mod config;
|
||
|
#[cfg(feature = "txpool")]
|
||
|
pub mod pool;
|
||
|
mod router;
|
||
|
#[cfg(test)]
|
||
|
mod tests;
|
||
|
pub mod traits;
|
||
|
|
||
|
pub use config::*;
|
||
|
pub use router::*;
|