zebra_node_services/
mempool.rs

1//! The Zebra mempool.
2//!
3//! A service that manages known unmined Zcash transactions.
4
5use std::collections::HashSet;
6
7use tokio::sync::oneshot;
8use zebra_chain::{
9    transaction::{self, UnminedTx, UnminedTxId, VerifiedUnminedTx},
10    transparent,
11};
12
13use crate::BoxError;
14
15mod gossip;
16mod transaction_dependencies;
17
18pub use self::{gossip::Gossip, transaction_dependencies::TransactionDependencies};
19
20/// A mempool service request.
21///
22/// Requests can query the current set of mempool transactions,
23/// queue transactions to be downloaded and verified, or
24/// run the mempool to check for newly verified transactions.
25///
26/// Requests can't modify the mempool directly,
27/// because all mempool transactions must be verified.
28#[derive(Debug, Eq, PartialEq)]
29pub enum Request {
30    /// Query all [`UnminedTxId`]s in the mempool.
31    TransactionIds,
32
33    /// Query matching [`UnminedTx`] in the mempool,
34    /// using a unique set of [`UnminedTxId`]s.
35    TransactionsById(HashSet<UnminedTxId>),
36
37    /// Query matching [`UnminedTx`] in the mempool,
38    /// using a unique set of [`transaction::Hash`]es. Pre-V5 transactions are matched
39    /// directly; V5 transaction are matched just by the Hash, disregarding
40    /// the [`AuthDigest`](zebra_chain::transaction::AuthDigest).
41    TransactionsByMinedId(HashSet<transaction::Hash>),
42
43    /// Request a [`transparent::Output`] identified by the given [`OutPoint`](transparent::OutPoint),
44    /// waiting until it becomes available if it is unknown.
45    ///
46    /// This request is purely informational, and there are no guarantees about
47    /// whether the UTXO remains unspent or is on the best chain, or any chain.
48    /// Its purpose is to allow orphaned mempool transaction verification.
49    ///
50    /// # Correctness
51    ///
52    /// Output requests should be wrapped in a timeout, so that
53    /// out-of-order and invalid requests do not hang indefinitely.
54    ///
55    /// Outdated requests are pruned on a regular basis.
56    AwaitOutput(transparent::OutPoint),
57
58    /// Request a [`VerifiedUnminedTx`] and its dependencies by its mined id.
59    TransactionWithDepsByMinedId(transaction::Hash),
60
61    /// Get all the [`VerifiedUnminedTx`] in the mempool.
62    ///
63    /// Equivalent to `TransactionsById(TransactionIds)`,
64    /// but each transaction also includes the `miner_fee` and `legacy_sigop_count` fields.
65    //
66    // TODO: make the Transactions response return VerifiedUnminedTx,
67    //       and remove the FullTransactions variant
68    FullTransactions,
69
70    /// Query matching cached rejected transaction IDs in the mempool,
71    /// using a unique set of [`UnminedTxId`]s.
72    RejectedTransactionIds(HashSet<UnminedTxId>),
73
74    /// Queue a list of gossiped transactions or transaction IDs, or
75    /// crawled transaction IDs.
76    ///
77    /// The transaction downloader checks for duplicates across IDs and transactions.
78    Queue(Vec<Gossip>),
79
80    /// Check for newly verified transactions.
81    ///
82    /// The transaction downloader does not push transactions into the mempool.
83    /// So a task should send this request regularly (every 5-10 seconds).
84    ///
85    /// These checks also happen for other request variants,
86    /// but we can't rely on peers to send queries regularly,
87    /// and crawler queue requests depend on peer responses.
88    /// Also, crawler requests aren't frequent enough for transaction propagation.
89    ///
90    /// # Correctness
91    ///
92    /// This request is required to avoid hangs in the mempool.
93    ///
94    /// The queue checker task can't call `poll_ready` directly on the mempool
95    /// service, because the service is wrapped in a `Buffer`. Calling
96    /// `Buffer::poll_ready` reserves a buffer slot, which can cause hangs
97    /// when too many slots are reserved but unused:
98    /// <https://docs.rs/tower/0.4.10/tower/buffer/struct.Buffer.html#a-note-on-choosing-a-bound>
99    CheckForVerifiedTransactions,
100}
101
102/// A response to a mempool service request.
103///
104/// Responses can read the current set of mempool transactions,
105/// check the queued status of transactions to be downloaded and verified, or
106/// confirm that the mempool has been checked for newly verified transactions.
107#[derive(Debug)]
108pub enum Response {
109    /// Returns all [`UnminedTxId`]s from the mempool.
110    TransactionIds(HashSet<UnminedTxId>),
111
112    /// Returns matching [`UnminedTx`] from the mempool.
113    ///
114    /// Since the [`Request::TransactionsById`] request is unique,
115    /// the response transactions are also unique. The same applies to
116    /// [`Request::TransactionsByMinedId`] requests, since the mempool does not allow
117    /// different transactions with different mined IDs.
118    Transactions(Vec<UnminedTx>),
119
120    /// Response to [`Request::AwaitOutput`] with the transparent output
121    UnspentOutput(transparent::Output),
122
123    /// Response to [`Request::TransactionWithDepsByMinedId`].
124    TransactionWithDeps {
125        /// The queried transaction
126        transaction: VerifiedUnminedTx,
127        /// A list of dependencies of the queried transaction.
128        dependencies: HashSet<transaction::Hash>,
129    },
130
131    /// Returns all [`VerifiedUnminedTx`] in the mempool.
132    //
133    // TODO: make the Transactions response return VerifiedUnminedTx,
134    //       and remove the FullTransactions variant
135    FullTransactions {
136        /// All [`VerifiedUnminedTx`]s in the mempool
137        transactions: Vec<VerifiedUnminedTx>,
138
139        /// All transaction dependencies in the mempool
140        transaction_dependencies: TransactionDependencies,
141
142        /// Last seen chain tip hash by mempool service
143        last_seen_tip_hash: zebra_chain::block::Hash,
144    },
145
146    /// Returns matching cached rejected [`UnminedTxId`]s from the mempool,
147    RejectedTransactionIds(HashSet<UnminedTxId>),
148
149    /// Returns a list of initial queue checks results and a oneshot receiver
150    /// for awaiting download and/or verification results.
151    ///
152    /// Each result matches the request at the corresponding vector index.
153    Queued(Vec<Result<oneshot::Receiver<Result<(), BoxError>>, BoxError>>),
154
155    /// Confirms that the mempool has checked for recently verified transactions.
156    CheckedForVerifiedTransactions,
157}