Pass the mempool config to the mempool (#2861)
* Split mempool config into its own module Also: - expand config docs - clean up mempool imports * Pass the mempool config to the mempool * Create the transaction sender channel inside the mempool 1/2 This simplifies all the code that calls the mempool. Also: - update the mempool enabled state before returning the new mempool - add some test module doc comments * Refactor a setup function out of the mempool unit tests 2/2 Also: - update the setup function to handle the latest mempool changes * Clarify a comment Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
This commit is contained in:
parent
09f23cb2e0
commit
b274ee4066
|
@ -26,10 +26,8 @@
|
||||||
use abscissa_core::{config, Command, FrameworkError, Options, Runnable};
|
use abscissa_core::{config, Command, FrameworkError, Options, Runnable};
|
||||||
use color_eyre::eyre::{eyre, Report};
|
use color_eyre::eyre::{eyre, Report};
|
||||||
use futures::{select, FutureExt};
|
use futures::{select, FutureExt};
|
||||||
use std::collections::HashSet;
|
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tower::builder::ServiceBuilder;
|
use tower::{builder::ServiceBuilder, util::BoxService};
|
||||||
use tower::util::BoxService;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::{
|
components::{
|
||||||
|
@ -92,20 +90,17 @@ impl StartCmd {
|
||||||
ChainSync::new(&config, peer_set.clone(), state.clone(), chain_verifier);
|
ChainSync::new(&config, peer_set.clone(), state.clone(), chain_verifier);
|
||||||
|
|
||||||
info!("initializing mempool");
|
info!("initializing mempool");
|
||||||
|
let (mempool, mempool_transaction_receiver) = Mempool::new(
|
||||||
let (mempool_transaction_sender, mempool_transaction_receiver) =
|
&config.mempool,
|
||||||
tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mempool_service = BoxService::new(Mempool::new(
|
|
||||||
peer_set.clone(),
|
peer_set.clone(),
|
||||||
state,
|
state,
|
||||||
tx_verifier,
|
tx_verifier,
|
||||||
sync_status.clone(),
|
sync_status.clone(),
|
||||||
latest_chain_tip,
|
latest_chain_tip,
|
||||||
chain_tip_change.clone(),
|
chain_tip_change.clone(),
|
||||||
mempool_transaction_sender,
|
);
|
||||||
));
|
let mempool = BoxService::new(mempool);
|
||||||
let mempool = ServiceBuilder::new().buffer(20).service(mempool_service);
|
let mempool = ServiceBuilder::new().buffer(20).service(mempool);
|
||||||
|
|
||||||
setup_tx
|
setup_tx
|
||||||
.send((peer_set.clone(), address_book, mempool.clone()))
|
.send((peer_set.clone(), address_book, mempool.clone()))
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Inbound service tests.
|
||||||
|
|
||||||
use std::{collections::HashSet, iter::FromIterator, net::SocketAddr, str::FromStr, sync::Arc};
|
use std::{collections::HashSet, iter::FromIterator, net::SocketAddr, str::FromStr, sync::Arc};
|
||||||
|
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
|
@ -576,16 +578,14 @@ async fn setup(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
committed_blocks.push(block_one);
|
committed_blocks.push(block_one);
|
||||||
|
|
||||||
let (transaction_sender, transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
let (mut mempool_service, transaction_receiver) = Mempool::new(
|
||||||
|
&mempool::Config::default(),
|
||||||
let mut mempool_service = Mempool::new(
|
|
||||||
buffered_peer_set.clone(),
|
buffered_peer_set.clone(),
|
||||||
state_service.clone(),
|
state_service.clone(),
|
||||||
buffered_tx_verifier.clone(),
|
buffered_tx_verifier.clone(),
|
||||||
sync_status.clone(),
|
sync_status.clone(),
|
||||||
latest_chain_tip,
|
latest_chain_tip,
|
||||||
chain_tip_change.clone(),
|
chain_tip_change.clone(),
|
||||||
transaction_sender,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Enable the mempool
|
// Enable the mempool
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
//! Zebra mempool.
|
//! Zebra mempool.
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
future::Future,
|
future::Future,
|
||||||
iter,
|
iter,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
time::Duration,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures::{future::FutureExt, stream::Stream};
|
use futures::{future::FutureExt, stream::Stream};
|
||||||
|
@ -24,8 +21,9 @@ use zebra_network as zn;
|
||||||
use zebra_state as zs;
|
use zebra_state as zs;
|
||||||
use zebra_state::{ChainTipChange, TipAction};
|
use zebra_state::{ChainTipChange, TipAction};
|
||||||
|
|
||||||
pub use crate::BoxError;
|
use crate::components::sync::SyncStatus;
|
||||||
|
|
||||||
|
mod config;
|
||||||
mod crawler;
|
mod crawler;
|
||||||
pub mod downloads;
|
pub mod downloads;
|
||||||
mod error;
|
mod error;
|
||||||
|
@ -35,23 +33,24 @@ mod storage;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub use self::crawler::Crawler;
|
pub use crate::BoxError;
|
||||||
pub use self::error::MempoolError;
|
|
||||||
pub use self::storage::{
|
pub use config::Config;
|
||||||
|
pub use crawler::Crawler;
|
||||||
|
pub use error::MempoolError;
|
||||||
|
pub use gossip::gossip_mempool_transaction_id;
|
||||||
|
pub use storage::{
|
||||||
ExactTipRejectionError, SameEffectsChainRejectionError, SameEffectsTipRejectionError,
|
ExactTipRejectionError, SameEffectsChainRejectionError, SameEffectsTipRejectionError,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use self::storage::tests::unmined_transactions_in_blocks;
|
pub use storage::tests::unmined_transactions_in_blocks;
|
||||||
pub use gossip::gossip_mempool_transaction_id;
|
|
||||||
|
|
||||||
use self::downloads::{
|
use downloads::{
|
||||||
Downloads as TxDownloads, Gossip, TransactionDownloadVerifyError, TRANSACTION_DOWNLOAD_TIMEOUT,
|
Downloads as TxDownloads, Gossip, TransactionDownloadVerifyError, TRANSACTION_DOWNLOAD_TIMEOUT,
|
||||||
TRANSACTION_VERIFY_TIMEOUT,
|
TRANSACTION_VERIFY_TIMEOUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::sync::SyncStatus;
|
|
||||||
|
|
||||||
type Outbound = Buffer<BoxService<zn::Request, zn::Response, zn::BoxError>, zn::Request>;
|
type Outbound = Buffer<BoxService<zn::Request, zn::Response, zn::BoxError>, zn::Request>;
|
||||||
type State = Buffer<BoxService<zs::Request, zs::Response, zs::BoxError>, zs::Request>;
|
type State = Buffer<BoxService<zs::Request, zs::Response, zs::BoxError>, zs::Request>;
|
||||||
type TxVerifier = Buffer<
|
type TxVerifier = Buffer<
|
||||||
|
@ -97,30 +96,6 @@ enum ActiveState {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mempool configuration section.
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Config {
|
|
||||||
/// The transaction cost limit
|
|
||||||
pub tx_cost_limit: u32,
|
|
||||||
/// Max amount of minutes for transactions to be in recently evicted
|
|
||||||
pub eviction_memory_time: Duration,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consensus rules:
|
|
||||||
///
|
|
||||||
/// - There MUST be a configuration option mempooltxcostlimit, which SHOULD default to 80000000.
|
|
||||||
/// - There MUST be a configuration option mempoolevictionmemoryminutes, which SHOULD default to 60.
|
|
||||||
///
|
|
||||||
/// https://zips.z.cash/zip-0401#specification
|
|
||||||
impl Default for Config {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
tx_cost_limit: 80_000_000,
|
|
||||||
eviction_memory_time: Duration::from_secs(60 * 60),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Mempool async management and query service.
|
/// Mempool async management and query service.
|
||||||
///
|
///
|
||||||
/// The mempool is the set of all verified transactions that this node is aware
|
/// The mempool is the set of all verified transactions that this node is aware
|
||||||
|
@ -157,15 +132,18 @@ pub struct Mempool {
|
||||||
|
|
||||||
impl Mempool {
|
impl Mempool {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
|
_config: &Config,
|
||||||
outbound: Outbound,
|
outbound: Outbound,
|
||||||
state: State,
|
state: State,
|
||||||
tx_verifier: TxVerifier,
|
tx_verifier: TxVerifier,
|
||||||
sync_status: SyncStatus,
|
sync_status: SyncStatus,
|
||||||
latest_chain_tip: zs::LatestChainTip,
|
latest_chain_tip: zs::LatestChainTip,
|
||||||
chain_tip_change: ChainTipChange,
|
chain_tip_change: ChainTipChange,
|
||||||
transaction_sender: watch::Sender<HashSet<UnminedTxId>>,
|
) -> (Self, watch::Receiver<HashSet<UnminedTxId>>) {
|
||||||
) -> Self {
|
let (transaction_sender, transaction_receiver) =
|
||||||
Mempool {
|
tokio::sync::watch::channel(HashSet::new());
|
||||||
|
|
||||||
|
let mut service = Mempool {
|
||||||
active_state: ActiveState::Disabled,
|
active_state: ActiveState::Disabled,
|
||||||
sync_status,
|
sync_status,
|
||||||
latest_chain_tip,
|
latest_chain_tip,
|
||||||
|
@ -174,7 +152,13 @@ impl Mempool {
|
||||||
state,
|
state,
|
||||||
tx_verifier,
|
tx_verifier,
|
||||||
transaction_sender,
|
transaction_sender,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// Make sure `is_enabled` is accurate.
|
||||||
|
// Otherwise, it is only updated in `poll_ready`, right before each service call.
|
||||||
|
service.update_state();
|
||||||
|
|
||||||
|
(service, transaction_receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the mempool state (enabled / disabled) depending on how close to
|
/// Update the mempool state (enabled / disabled) depending on how close to
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
//! User-configurable mempool parameters.
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Mempool configuration section.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Config {
|
||||||
|
/// The mempool transaction cost limit.
|
||||||
|
///
|
||||||
|
/// This limits the total serialized byte size of all transactions in the mempool.
|
||||||
|
///
|
||||||
|
/// This corresponds to `mempooltxcostlimit` from [ZIP-401](https://zips.z.cash/zip-0401#specification).
|
||||||
|
pub tx_cost_limit: u32,
|
||||||
|
|
||||||
|
/// The mempool transaction eviction age limit.
|
||||||
|
///
|
||||||
|
/// This limits the maximum amount of time evicted transaction IDs stay in the mempool rejection list.
|
||||||
|
/// Transactions are randomly evicted from the mempool when the mempool reaches [`tx_cost_limit`].
|
||||||
|
///
|
||||||
|
/// (Transactions can also be rejected by the mempool for other reasons.
|
||||||
|
/// Different rejection reasons can have different age limits.)
|
||||||
|
///
|
||||||
|
/// This corresponds to `mempoolevictionmemoryminutes` from
|
||||||
|
/// [ZIP-401](https://zips.z.cash/zip-0401#specification).
|
||||||
|
pub eviction_memory_time: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Consensus rules:
|
||||||
|
///
|
||||||
|
/// > There MUST be a configuration option mempooltxcostlimit,
|
||||||
|
/// > which SHOULD default to 80000000.
|
||||||
|
/// >
|
||||||
|
/// > There MUST be a configuration option mempoolevictionmemoryminutes,
|
||||||
|
/// > which SHOULD default to 60 [minutes].
|
||||||
|
///
|
||||||
|
/// https://zips.z.cash/zip-0401#specification
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
tx_cost_limit: 80_000_000,
|
||||||
|
eviction_memory_time: Duration::from_secs(60 * 60),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
|
//! Randomised property tests for the mempool.
|
||||||
|
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
use std::collections::HashSet;
|
|
||||||
use tokio::time;
|
use tokio::time;
|
||||||
use tower::{buffer::Buffer, util::BoxService};
|
use tower::{buffer::Buffer, util::BoxService};
|
||||||
|
|
||||||
|
@ -9,8 +10,10 @@ use zebra_network as zn;
|
||||||
use zebra_state::{self as zs, ChainTipBlock, ChainTipSender};
|
use zebra_state::{self as zs, ChainTipBlock, ChainTipSender};
|
||||||
use zebra_test::mock_service::{MockService, PropTestAssertion};
|
use zebra_test::mock_service::{MockService, PropTestAssertion};
|
||||||
|
|
||||||
use super::super::Mempool;
|
use crate::components::{
|
||||||
use crate::components::sync::{RecentSyncLengths, SyncStatus};
|
mempool::{self, Mempool},
|
||||||
|
sync::{RecentSyncLengths, SyncStatus},
|
||||||
|
};
|
||||||
|
|
||||||
/// A [`MockService`] representing the network service.
|
/// A [`MockService`] representing the network service.
|
||||||
type MockPeerSet = MockService<zn::Request, zn::Response, PropTestAssertion>;
|
type MockPeerSet = MockService<zn::Request, zn::Response, PropTestAssertion>;
|
||||||
|
@ -151,16 +154,14 @@ fn setup(
|
||||||
let (sync_status, recent_syncs) = SyncStatus::new();
|
let (sync_status, recent_syncs) = SyncStatus::new();
|
||||||
let (chain_tip_sender, latest_chain_tip, chain_tip_change) = ChainTipSender::new(None, network);
|
let (chain_tip_sender, latest_chain_tip, chain_tip_change) = ChainTipSender::new(None, network);
|
||||||
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
let (mempool, _transaction_receiver) = Mempool::new(
|
||||||
|
&mempool::Config::default(),
|
||||||
let mempool = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set.clone()), 1),
|
Buffer::new(BoxService::new(peer_set.clone()), 1),
|
||||||
Buffer::new(BoxService::new(state_service.clone()), 1),
|
Buffer::new(BoxService::new(state_service.clone()), 1),
|
||||||
Buffer::new(BoxService::new(tx_verifier.clone()), 1),
|
Buffer::new(BoxService::new(tx_verifier.clone()), 1),
|
||||||
sync_status,
|
sync_status,
|
||||||
latest_chain_tip,
|
latest_chain_tip,
|
||||||
chain_tip_change,
|
chain_tip_change,
|
||||||
transaction_sender,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Fixed test vectors for the mempool.
|
||||||
|
|
||||||
use std::{collections::HashSet, sync::Arc};
|
use std::{collections::HashSet, sync::Arc};
|
||||||
|
|
||||||
use color_eyre::Report;
|
use color_eyre::Report;
|
||||||
|
@ -5,27 +7,31 @@ use tokio::time;
|
||||||
use tower::{ServiceBuilder, ServiceExt};
|
use tower::{ServiceBuilder, ServiceExt};
|
||||||
|
|
||||||
use zebra_chain::{block::Block, parameters::Network, serialization::ZcashDeserializeInto};
|
use zebra_chain::{block::Block, parameters::Network, serialization::ZcashDeserializeInto};
|
||||||
use zebra_consensus::Config as ConsensusConfig;
|
use zebra_consensus::transaction as tx;
|
||||||
use zebra_state::Config as StateConfig;
|
use zebra_state::Config as StateConfig;
|
||||||
use zebra_test::mock_service::MockService;
|
use zebra_test::mock_service::{MockService, PanicAssertion};
|
||||||
|
|
||||||
use super::super::{storage::tests::unmined_transactions_in_blocks, *};
|
use crate::components::{
|
||||||
|
mempool::{self, storage::tests::unmined_transactions_in_blocks, *},
|
||||||
|
sync::RecentSyncLengths,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A [`MockService`] representing the network service.
|
||||||
|
type MockPeerSet = MockService<zn::Request, zn::Response, PanicAssertion>;
|
||||||
|
|
||||||
|
/// The unmocked Zebra state service's type.
|
||||||
|
type StateService = Buffer<BoxService<zs::Request, zs::Response, zs::BoxError>, zs::Request>;
|
||||||
|
|
||||||
|
/// A [`MockService`] representing the Zebra transaction verifier service.
|
||||||
|
type MockTxVerifier = MockService<tx::Request, tx::Response, PanicAssertion, TransactionError>;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn mempool_service_basic() -> Result<(), Report> {
|
async fn mempool_service_basic() -> Result<(), Report> {
|
||||||
// Using the mainnet for now
|
// Using the mainnet for now
|
||||||
let network = Network::Mainnet;
|
let network = Network::Mainnet;
|
||||||
let consensus_config = ConsensusConfig::default();
|
|
||||||
let state_config = StateConfig::ephemeral();
|
|
||||||
let peer_set = MockService::build().for_unit_tests();
|
|
||||||
let (sync_status, mut recent_syncs) = SyncStatus::new();
|
|
||||||
let (state, latest_chain_tip, chain_tip_change) =
|
|
||||||
zebra_state::init(state_config.clone(), network);
|
|
||||||
|
|
||||||
let state_service = ServiceBuilder::new().buffer(1).service(state);
|
let (mut service, _peer_set, _state_service, _tx_verifier, mut recent_syncs) =
|
||||||
let (_chain_verifier, tx_verifier) =
|
setup(network).await;
|
||||||
zebra_consensus::chain::init(consensus_config.clone(), network, state_service.clone())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// get the genesis block transactions from the Zcash blockchain.
|
// get the genesis block transactions from the Zcash blockchain.
|
||||||
let mut unmined_transactions = unmined_transactions_in_blocks(..=10, network);
|
let mut unmined_transactions = unmined_transactions_in_blocks(..=10, network);
|
||||||
|
@ -35,19 +41,6 @@ async fn mempool_service_basic() -> Result<(), Report> {
|
||||||
let last_transaction = unmined_transactions.next_back().unwrap();
|
let last_transaction = unmined_transactions.next_back().unwrap();
|
||||||
let more_transactions = unmined_transactions;
|
let more_transactions = unmined_transactions;
|
||||||
|
|
||||||
// Start the mempool service
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mut service = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set), 1),
|
|
||||||
state_service.clone(),
|
|
||||||
tx_verifier,
|
|
||||||
sync_status,
|
|
||||||
latest_chain_tip,
|
|
||||||
chain_tip_change,
|
|
||||||
transaction_sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable the mempool
|
// Enable the mempool
|
||||||
let _ = service.enable(&mut recent_syncs).await;
|
let _ = service.enable(&mut recent_syncs).await;
|
||||||
|
|
||||||
|
@ -138,17 +131,9 @@ async fn mempool_service_basic() -> Result<(), Report> {
|
||||||
async fn mempool_queue() -> Result<(), Report> {
|
async fn mempool_queue() -> Result<(), Report> {
|
||||||
// Using the mainnet for now
|
// Using the mainnet for now
|
||||||
let network = Network::Mainnet;
|
let network = Network::Mainnet;
|
||||||
let consensus_config = ConsensusConfig::default();
|
|
||||||
let state_config = StateConfig::ephemeral();
|
|
||||||
let peer_set = MockService::build().for_unit_tests();
|
|
||||||
let (sync_status, mut recent_syncs) = SyncStatus::new();
|
|
||||||
let (state, latest_chain_tip, chain_tip_change) =
|
|
||||||
zebra_state::init(state_config.clone(), network);
|
|
||||||
|
|
||||||
let state_service = ServiceBuilder::new().buffer(1).service(state);
|
let (mut service, _peer_set, _state_service, _tx_verifier, mut recent_syncs) =
|
||||||
let (_chain_verifier, tx_verifier) =
|
setup(network).await;
|
||||||
zebra_consensus::chain::init(consensus_config.clone(), network, state_service.clone())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// Get transactions to use in the test
|
// Get transactions to use in the test
|
||||||
let unmined_transactions = unmined_transactions_in_blocks(..=10, network);
|
let unmined_transactions = unmined_transactions_in_blocks(..=10, network);
|
||||||
|
@ -164,19 +149,6 @@ async fn mempool_queue() -> Result<(), Report> {
|
||||||
// The last transaction that will be added in the mempool (and thus not rejected)
|
// The last transaction that will be added in the mempool (and thus not rejected)
|
||||||
let stored_tx = transactions.next_back().unwrap().clone();
|
let stored_tx = transactions.next_back().unwrap().clone();
|
||||||
|
|
||||||
// Start the mempool service
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mut service = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set), 1),
|
|
||||||
state_service.clone(),
|
|
||||||
tx_verifier,
|
|
||||||
sync_status,
|
|
||||||
latest_chain_tip,
|
|
||||||
chain_tip_change,
|
|
||||||
transaction_sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable the mempool
|
// Enable the mempool
|
||||||
let _ = service.enable(&mut recent_syncs).await;
|
let _ = service.enable(&mut recent_syncs).await;
|
||||||
|
|
||||||
|
@ -247,16 +219,9 @@ async fn mempool_queue() -> Result<(), Report> {
|
||||||
async fn mempool_service_disabled() -> Result<(), Report> {
|
async fn mempool_service_disabled() -> Result<(), Report> {
|
||||||
// Using the mainnet for now
|
// Using the mainnet for now
|
||||||
let network = Network::Mainnet;
|
let network = Network::Mainnet;
|
||||||
let consensus_config = ConsensusConfig::default();
|
|
||||||
let state_config = StateConfig::ephemeral();
|
|
||||||
let peer_set = MockService::build().for_unit_tests();
|
|
||||||
let (sync_status, mut recent_syncs) = SyncStatus::new();
|
|
||||||
|
|
||||||
let (state, latest_chain_tip, chain_tip_change) = zebra_state::init(state_config, network);
|
let (mut service, _peer_set, _state_service, _tx_verifier, mut recent_syncs) =
|
||||||
let state_service = ServiceBuilder::new().buffer(1).service(state);
|
setup(network).await;
|
||||||
let (_chain_verifier, tx_verifier) =
|
|
||||||
zebra_consensus::chain::init(consensus_config.clone(), network, state_service.clone())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// get the genesis block transactions from the Zcash blockchain.
|
// get the genesis block transactions from the Zcash blockchain.
|
||||||
let mut unmined_transactions = unmined_transactions_in_blocks(..=10, network);
|
let mut unmined_transactions = unmined_transactions_in_blocks(..=10, network);
|
||||||
|
@ -265,19 +230,6 @@ async fn mempool_service_disabled() -> Result<(), Report> {
|
||||||
.expect("Missing genesis transaction");
|
.expect("Missing genesis transaction");
|
||||||
let more_transactions = unmined_transactions;
|
let more_transactions = unmined_transactions;
|
||||||
|
|
||||||
// Start the mempool service
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mut service = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set), 1),
|
|
||||||
state_service.clone(),
|
|
||||||
tx_verifier,
|
|
||||||
sync_status,
|
|
||||||
latest_chain_tip,
|
|
||||||
chain_tip_change,
|
|
||||||
transaction_sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test if mempool is disabled (it should start disabled)
|
// Test if mempool is disabled (it should start disabled)
|
||||||
assert!(!service.is_enabled());
|
assert!(!service.is_enabled());
|
||||||
|
|
||||||
|
@ -374,33 +326,12 @@ async fn mempool_cancel_mined() -> Result<(), Report> {
|
||||||
|
|
||||||
// Using the mainnet for now
|
// Using the mainnet for now
|
||||||
let network = Network::Mainnet;
|
let network = Network::Mainnet;
|
||||||
let consensus_config = ConsensusConfig::default();
|
|
||||||
let state_config = StateConfig::ephemeral();
|
|
||||||
let peer_set = MockService::build().for_unit_tests();
|
|
||||||
let (sync_status, mut recent_syncs) = SyncStatus::new();
|
|
||||||
let (state, latest_chain_tip, chain_tip_change) =
|
|
||||||
zebra_state::init(state_config.clone(), network);
|
|
||||||
|
|
||||||
let mut state_service = ServiceBuilder::new().buffer(1).service(state);
|
let (mut mempool, _peer_set, mut state_service, _tx_verifier, mut recent_syncs) =
|
||||||
let (_chain_verifier, tx_verifier) =
|
setup(network).await;
|
||||||
zebra_consensus::chain::init(consensus_config.clone(), network, state_service.clone())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
time::pause();
|
time::pause();
|
||||||
|
|
||||||
// Start the mempool service
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mut mempool = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set), 1),
|
|
||||||
state_service.clone(),
|
|
||||||
tx_verifier,
|
|
||||||
sync_status,
|
|
||||||
latest_chain_tip,
|
|
||||||
chain_tip_change,
|
|
||||||
transaction_sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable the mempool
|
// Enable the mempool
|
||||||
let _ = mempool.enable(&mut recent_syncs).await;
|
let _ = mempool.enable(&mut recent_syncs).await;
|
||||||
assert!(mempool.is_enabled());
|
assert!(mempool.is_enabled());
|
||||||
|
@ -490,30 +421,9 @@ async fn mempool_cancel_downloads_after_network_upgrade() -> Result<(), Report>
|
||||||
|
|
||||||
// Using the mainnet for now
|
// Using the mainnet for now
|
||||||
let network = Network::Mainnet;
|
let network = Network::Mainnet;
|
||||||
let consensus_config = ConsensusConfig::default();
|
|
||||||
let state_config = StateConfig::ephemeral();
|
|
||||||
let peer_set = MockService::build().for_unit_tests();
|
|
||||||
let (sync_status, mut recent_syncs) = SyncStatus::new();
|
|
||||||
let (state, latest_chain_tip, chain_tip_change) =
|
|
||||||
zebra_state::init(state_config.clone(), network);
|
|
||||||
|
|
||||||
let mut state_service = ServiceBuilder::new().buffer(1).service(state);
|
let (mut mempool, _peer_set, mut state_service, _tx_verifier, mut recent_syncs) =
|
||||||
let (_chain_verifier, tx_verifier) =
|
setup(network).await;
|
||||||
zebra_consensus::chain::init(consensus_config.clone(), network, state_service.clone())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// Start the mempool service
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mut mempool = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set), 1),
|
|
||||||
state_service.clone(),
|
|
||||||
tx_verifier,
|
|
||||||
sync_status,
|
|
||||||
latest_chain_tip,
|
|
||||||
chain_tip_change,
|
|
||||||
transaction_sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable the mempool
|
// Enable the mempool
|
||||||
let _ = mempool.enable(&mut recent_syncs).await;
|
let _ = mempool.enable(&mut recent_syncs).await;
|
||||||
|
@ -579,18 +489,9 @@ async fn mempool_cancel_downloads_after_network_upgrade() -> Result<(), Report>
|
||||||
async fn mempool_failed_verification_is_rejected() -> Result<(), Report> {
|
async fn mempool_failed_verification_is_rejected() -> Result<(), Report> {
|
||||||
// Using the mainnet for now
|
// Using the mainnet for now
|
||||||
let network = Network::Mainnet;
|
let network = Network::Mainnet;
|
||||||
let consensus_config = ConsensusConfig::default();
|
|
||||||
let state_config = StateConfig::ephemeral();
|
|
||||||
let peer_set = MockService::build().for_unit_tests();
|
|
||||||
let (sync_status, mut recent_syncs) = SyncStatus::new();
|
|
||||||
let (state, latest_chain_tip, chain_tip_change) =
|
|
||||||
zebra_state::init(state_config.clone(), network);
|
|
||||||
|
|
||||||
let mut state_service = ServiceBuilder::new().buffer(1).service(state);
|
let (mut mempool, _peer_set, mut state_service, mut tx_verifier, mut recent_syncs) =
|
||||||
let (_chain_verifier, _tx_verifier) =
|
setup(network).await;
|
||||||
zebra_consensus::chain::init(consensus_config.clone(), network, state_service.clone())
|
|
||||||
.await;
|
|
||||||
let mut tx_verifier = MockService::build().for_unit_tests();
|
|
||||||
|
|
||||||
// Get transactions to use in the test
|
// Get transactions to use in the test
|
||||||
let mut unmined_transactions = unmined_transactions_in_blocks(1..=2, network);
|
let mut unmined_transactions = unmined_transactions_in_blocks(1..=2, network);
|
||||||
|
@ -598,19 +499,6 @@ async fn mempool_failed_verification_is_rejected() -> Result<(), Report> {
|
||||||
|
|
||||||
time::pause();
|
time::pause();
|
||||||
|
|
||||||
// Start the mempool service
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mut mempool = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set.clone()), 1),
|
|
||||||
state_service.clone(),
|
|
||||||
Buffer::new(BoxService::new(tx_verifier.clone()), 1),
|
|
||||||
sync_status,
|
|
||||||
latest_chain_tip,
|
|
||||||
chain_tip_change,
|
|
||||||
transaction_sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable the mempool
|
// Enable the mempool
|
||||||
let _ = mempool.enable(&mut recent_syncs).await;
|
let _ = mempool.enable(&mut recent_syncs).await;
|
||||||
|
|
||||||
|
@ -684,17 +572,9 @@ async fn mempool_failed_verification_is_rejected() -> Result<(), Report> {
|
||||||
async fn mempool_failed_download_is_not_rejected() -> Result<(), Report> {
|
async fn mempool_failed_download_is_not_rejected() -> Result<(), Report> {
|
||||||
// Using the mainnet for now
|
// Using the mainnet for now
|
||||||
let network = Network::Mainnet;
|
let network = Network::Mainnet;
|
||||||
let consensus_config = ConsensusConfig::default();
|
|
||||||
let state_config = StateConfig::ephemeral();
|
|
||||||
let mut peer_set = MockService::build().for_unit_tests();
|
|
||||||
let (sync_status, mut recent_syncs) = SyncStatus::new();
|
|
||||||
let (state, latest_chain_tip, chain_tip_change) =
|
|
||||||
zebra_state::init(state_config.clone(), network);
|
|
||||||
|
|
||||||
let mut state_service = ServiceBuilder::new().buffer(1).service(state);
|
let (mut mempool, mut peer_set, mut state_service, _tx_verifier, mut recent_syncs) =
|
||||||
let (_chain_verifier, tx_verifier) =
|
setup(network).await;
|
||||||
zebra_consensus::chain::init(consensus_config.clone(), network, state_service.clone())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// Get transactions to use in the test
|
// Get transactions to use in the test
|
||||||
let mut unmined_transactions = unmined_transactions_in_blocks(1..=2, network);
|
let mut unmined_transactions = unmined_transactions_in_blocks(1..=2, network);
|
||||||
|
@ -702,19 +582,6 @@ async fn mempool_failed_download_is_not_rejected() -> Result<(), Report> {
|
||||||
|
|
||||||
time::pause();
|
time::pause();
|
||||||
|
|
||||||
// Start the mempool service
|
|
||||||
let (transaction_sender, _transaction_receiver) = tokio::sync::watch::channel(HashSet::new());
|
|
||||||
|
|
||||||
let mut mempool = Mempool::new(
|
|
||||||
Buffer::new(BoxService::new(peer_set.clone()), 1),
|
|
||||||
state_service.clone(),
|
|
||||||
tx_verifier,
|
|
||||||
sync_status,
|
|
||||||
latest_chain_tip,
|
|
||||||
chain_tip_change,
|
|
||||||
transaction_sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Enable the mempool
|
// Enable the mempool
|
||||||
let _ = mempool.enable(&mut recent_syncs).await;
|
let _ = mempool.enable(&mut recent_syncs).await;
|
||||||
|
|
||||||
|
@ -778,3 +645,36 @@ async fn mempool_failed_download_is_not_rejected() -> Result<(), Report> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new [`Mempool`] instance using mocked services.
|
||||||
|
async fn setup(
|
||||||
|
network: Network,
|
||||||
|
) -> (
|
||||||
|
Mempool,
|
||||||
|
MockPeerSet,
|
||||||
|
StateService,
|
||||||
|
MockTxVerifier,
|
||||||
|
RecentSyncLengths,
|
||||||
|
) {
|
||||||
|
let peer_set = MockService::build().for_unit_tests();
|
||||||
|
|
||||||
|
let state_config = StateConfig::ephemeral();
|
||||||
|
let (state, latest_chain_tip, chain_tip_change) = zebra_state::init(state_config, network);
|
||||||
|
let state_service = ServiceBuilder::new().buffer(1).service(state);
|
||||||
|
|
||||||
|
let tx_verifier = MockService::build().for_unit_tests();
|
||||||
|
|
||||||
|
let (sync_status, recent_syncs) = SyncStatus::new();
|
||||||
|
|
||||||
|
let (mempool, _mempool_transaction_receiver) = Mempool::new(
|
||||||
|
&mempool::Config::default(),
|
||||||
|
Buffer::new(BoxService::new(peer_set.clone()), 1),
|
||||||
|
state_service.clone(),
|
||||||
|
Buffer::new(BoxService::new(tx_verifier.clone()), 1),
|
||||||
|
sync_status,
|
||||||
|
latest_chain_tip,
|
||||||
|
chain_tip_change,
|
||||||
|
);
|
||||||
|
|
||||||
|
(mempool, peer_set, state_service, tx_verifier, recent_syncs)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue