cfxcore/pos/mempool/
mod.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8#![forbid(unsafe_code)]
9// Increase recursion limit to allow for use of select! macro.
10
11//! Mempool is used to hold transactions that have been submitted but not yet
12//! agreed upon and executed.
13//!
14//! **Flow**: AC sends transactions into mempool which holds them for a period
15//! of time before sending them into consensus.  When a new transaction is
16//! added, Mempool shares this transaction with other nodes in the system.  This
17//! is a form of “shared mempool” in that transactions between mempools are
18//! shared with other validators.  This helps maintain a pseudo global ordering
19//! since when a validator receives a transaction from another mempool, it will
20//! be ordered when added in the ordered queue of the recipient validator. To
21//! reduce network consumption, in “shared mempool” each validator is
22//! responsible for delivery of its own transactions (we don't rebroadcast
23//! transactions originated on a different peer). Also we only broadcast
24//! transactions that have some chance to be included in next block: their
25//! sequence number equals to the next sequence number of account or sequential
26//! to it. For example, if the current sequence number for an account is 2 and
27//! local mempool contains transactions with sequence numbers 2,3,4,7,8, then
28//! only transactions 2, 3 and 4 will be broadcast.
29//!
30//! Consensus pulls transactions from mempool rather than mempool pushing into
31//! consensus. This is done so that while consensus is not yet ready for
32//! transactions, we keep ordering based on gas and consensus can let
33//! transactions build up.  This allows for batching of transactions into a
34//! single consensus block as well as prioritizing by gas price. Mempool doesn't
35//! keep track of transactions that were sent to Consensus. On each get_block
36//! request, Consensus additionally sends a set of transactions that were pulled
37//! from Mempool so far but were not committed yet. This is done so Mempool can
38//! be agnostic about different Consensus proposal branches.  Once a transaction
39//! is fully executed and written to storage,  Consensus notifies Mempool about
40//! it which later drops it from its internal state.
41//!
42//! **Internals**: Internally Mempool is modeled as `HashMap<AccountAddress,
43//! AccountTransactions>` with various indexes built on top of it. The main
44//! index `PriorityIndex` is an ordered queue of transactions that are “ready”
45//! to be included in next block(i.e. have sequence number sequential to current
46//! for account). This queue is ordered by gas price so that if a client is
47//! willing to pay more (than other clients) per unit of execution, then they
48//! can enter consensus earlier. Note that although global ordering is
49//! maintained by gas price, for a single account, transactions are ordered by
50//! sequence number.
51//!
52//! All transactions that are not ready to be included in the next block are
53//! part of separate `ParkingLotIndex`. They will be moved to the ordered queue
54//! once some event unblocks them. For example, Mempool has transaction with
55//! sequence number 4, while current sequence number for that account is 3. Such
56//! transaction is considered to be “non-ready”. Then callback from Consensus
57//! notifies that transaction was committed(i.e. transaction 3 was submitted to
58//! different node). Such event “unblocks” local transaction and txn4 will be
59//! moved to OrderedQueue.
60//!
61//! Mempool only holds a limited number of transactions to prevent OOMing the
62//! system. Additionally there's a limit of number of transactions per account
63//! to prevent different abuses/attacks
64//!
65//! Transactions in Mempool have two types of expirations: systemTTL and
66//! client-specified expiration. Once we hit either of those, the transaction is
67//! removed from Mempool. SystemTTL is checked periodically in the background,
68//! while the client-specified expiration is checked on every Consensus commit
69//! request. We use a separate system TTL to ensure that a transaction won't
70//! remain stuck in Mempool forever, even if Consensus doesn't make progress
71
72//#[cfg(any(test, feature = "fuzzing"))]
73//mod tests;
74pub use shared_mempool::{
75    bootstrap, network,
76    types::{
77        gen_mempool_reconfig_subscription, CommitNotification, CommitResponse,
78        CommittedTransaction, ConsensusRequest, ConsensusResponse,
79        MempoolClientSender, SubmissionStatus, TransactionExclusion,
80    },
81};
82//#[cfg(any(test, feature = "fuzzing"))]
83//pub use tests::{fuzzing, mocks};
84
85mod core_mempool;
86mod counters;
87mod logging;
88mod shared_mempool;