mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-11-16 15:58:17 +00:00
This commit is contained in:
parent
21f6287288
commit
e652c189e5
21 changed files with 247 additions and 224 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -558,7 +558,6 @@ dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"rand",
|
"rand",
|
||||||
"serde",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
@ -850,7 +849,6 @@ dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"rand_distr",
|
"rand_distr",
|
||||||
"rayon",
|
"rayon",
|
||||||
"serde",
|
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
|
|
|
@ -27,7 +27,7 @@ gray_peers_percent = 0.7
|
||||||
## The port to accept connections on, if left `0` no connections will be accepted.
|
## The port to accept connections on, if left `0` no connections will be accepted.
|
||||||
p2p_port = 0
|
p2p_port = 0
|
||||||
## The IP address to listen to connections on.
|
## The IP address to listen to connections on.
|
||||||
server.ip = "0.0.0.0"
|
listen_on = "0.0.0.0"
|
||||||
|
|
||||||
## The Clear-net addressbook config.
|
## The Clear-net addressbook config.
|
||||||
[p2p.clear_net.address_book_config]
|
[p2p.clear_net.address_book_config]
|
||||||
|
@ -35,10 +35,8 @@ server.ip = "0.0.0.0"
|
||||||
max_white_list_length = 1_000
|
max_white_list_length = 1_000
|
||||||
## The size of the gray peer list, which contains peers we have not made a connection to before.
|
## The size of the gray peer list, which contains peers we have not made a connection to before.
|
||||||
max_gray_list_length = 5_000
|
max_gray_list_length = 5_000
|
||||||
## The folder to store the address book.
|
|
||||||
peer_store_directory = {cache}
|
|
||||||
## The amount of time between address book saves.
|
## The amount of time between address book saves.
|
||||||
peer_save_period = {{ secs = 90, nanos = 0 }}
|
peer_save_period = { secs = 90, nanos = 0 }
|
||||||
|
|
||||||
## The block downloader config.
|
## The block downloader config.
|
||||||
[p2p.block_downloader]
|
[p2p.block_downloader]
|
||||||
|
@ -48,10 +46,8 @@ buffer_size = 50_000_000
|
||||||
in_progress_queue_size = 50_000_000
|
in_progress_queue_size = 50_000_000
|
||||||
## The target size of a batch of blocks (bytes), must not exceed 100MB.
|
## The target size of a batch of blocks (bytes), must not exceed 100MB.
|
||||||
target_batch_size = 5_000_000
|
target_batch_size = 5_000_000
|
||||||
## The number of blocks in the first batch (you probably shouldn't change this).
|
|
||||||
initial_batch_len = 1
|
|
||||||
## The amount of time between checking the pool of connected peers for free peers to download blocks.
|
## The amount of time between checking the pool of connected peers for free peers to download blocks.
|
||||||
check_client_pool_interval = {{ secs = 30, nanos = 0 }}
|
check_client_pool_interval = { secs = 30, nanos = 0 }
|
||||||
|
|
||||||
## Storage config
|
## Storage config
|
||||||
[storage]
|
[storage]
|
||||||
|
@ -60,8 +56,6 @@ reader_threads = "OnePerThread"
|
||||||
|
|
||||||
## Txpool storage config.
|
## Txpool storage config.
|
||||||
[storage.txpool]
|
[storage.txpool]
|
||||||
## The txpool storage location.
|
|
||||||
path = {txpool}
|
|
||||||
## The database sync mode for the txpool.
|
## The database sync mode for the txpool.
|
||||||
sync_mode = "Async"
|
sync_mode = "Async"
|
||||||
## The maximum size of all the txs in the pool (bytes).
|
## The maximum size of all the txs in the pool (bytes).
|
||||||
|
@ -69,7 +63,5 @@ max_txpool_byte_size = 100_000_000
|
||||||
|
|
||||||
## Blockchain storage config.
|
## Blockchain storage config.
|
||||||
[storage.blockchain]
|
[storage.blockchain]
|
||||||
## The blockchain storage location.
|
|
||||||
path = {blockchain}
|
|
||||||
## The database sync mode for the blockchain.
|
## The database sync mode for the blockchain.
|
||||||
sync_mode = "Async"
|
sync_mode = "Async"
|
|
@ -19,11 +19,11 @@ cuprate-epee-encoding = { workspace = true }
|
||||||
cuprate-fixed-bytes = { workspace = true }
|
cuprate-fixed-bytes = { workspace = true }
|
||||||
cuprate-levin = { workspace = true }
|
cuprate-levin = { workspace = true }
|
||||||
cuprate-wire = { workspace = true }
|
cuprate-wire = { workspace = true }
|
||||||
cuprate-p2p = { workspace = true, features = ["serde"] }
|
cuprate-p2p = { workspace = true }
|
||||||
cuprate-p2p-core = { workspace = true, features = ["serde"] }
|
cuprate-p2p-core = { workspace = true, features = ["serde"] }
|
||||||
cuprate-dandelion-tower = { workspace = true, features = ["txpool"] }
|
cuprate-dandelion-tower = { workspace = true, features = ["txpool"] }
|
||||||
cuprate-async-buffer = { workspace = true }
|
cuprate-async-buffer = { workspace = true }
|
||||||
cuprate-address-book = { workspace = true, features = ["serde_config"] }
|
cuprate-address-book = { workspace = true }
|
||||||
cuprate-blockchain = { workspace = true }
|
cuprate-blockchain = { workspace = true }
|
||||||
cuprate-database-service = { workspace = true, features = ["serde"] }
|
cuprate-database-service = { workspace = true, features = ["serde"] }
|
||||||
cuprate-txpool = { workspace = true }
|
cuprate-txpool = { workspace = true }
|
||||||
|
|
|
@ -15,14 +15,16 @@ use cuprate_helper::{
|
||||||
network::Network,
|
network::Network,
|
||||||
};
|
};
|
||||||
use cuprate_p2p::block_downloader::BlockDownloaderConfig;
|
use cuprate_p2p::block_downloader::BlockDownloaderConfig;
|
||||||
use cuprate_p2p_core::ClearNet;
|
use cuprate_p2p_core::{ClearNet, ClearNetServerCfg};
|
||||||
|
|
||||||
mod args;
|
mod args;
|
||||||
mod default;
|
mod default;
|
||||||
|
mod fs;
|
||||||
mod p2p;
|
mod p2p;
|
||||||
mod storage;
|
mod storage;
|
||||||
mod tracing_config;
|
mod tracing_config;
|
||||||
|
|
||||||
|
use crate::config::fs::FileSystemConfig;
|
||||||
use p2p::P2PConfig;
|
use p2p::P2PConfig;
|
||||||
use storage::StorageConfig;
|
use storage::StorageConfig;
|
||||||
use tracing_config::TracingConfig;
|
use tracing_config::TracingConfig;
|
||||||
|
@ -43,6 +45,7 @@ pub fn read_config_and_args() -> Config {
|
||||||
} else {
|
} else {
|
||||||
// First attempt to read the config file from the current directory.
|
// First attempt to read the config file from the current directory.
|
||||||
std::env::current_dir()
|
std::env::current_dir()
|
||||||
|
.map(|path| path.join(DEFAULT_CONFIG_FILE_NAME))
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
.and_then(Config::read_from_path)
|
.and_then(Config::read_from_path)
|
||||||
.inspect_err(|e| tracing::debug!("Failed to read config from current dir: {e}"))
|
.inspect_err(|e| tracing::debug!("Failed to read config from current dir: {e}"))
|
||||||
|
@ -53,7 +56,7 @@ pub fn read_config_and_args() -> Config {
|
||||||
})
|
})
|
||||||
.inspect_err(|e| {
|
.inspect_err(|e| {
|
||||||
tracing::debug!("Failed to read config from config dir: {e}");
|
tracing::debug!("Failed to read config from config dir: {e}");
|
||||||
tracing::warn!("Failed to find/read config file, using default config.");
|
println!("Failed to find/read config file, using default config.");
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
};
|
};
|
||||||
|
@ -76,6 +79,8 @@ pub struct Config {
|
||||||
|
|
||||||
/// The storage config.
|
/// The storage config.
|
||||||
storage: StorageConfig,
|
storage: StorageConfig,
|
||||||
|
|
||||||
|
fs: FileSystemConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
@ -87,10 +92,11 @@ impl Config {
|
||||||
fn read_from_path(file: impl AsRef<Path>) -> Result<Self, anyhow::Error> {
|
fn read_from_path(file: impl AsRef<Path>) -> Result<Self, anyhow::Error> {
|
||||||
let file_text = read_to_string(file.as_ref())?;
|
let file_text = read_to_string(file.as_ref())?;
|
||||||
|
|
||||||
Ok(toml::from_str(&file_text).inspect_err(|e| {
|
Ok(toml::from_str(&file_text)
|
||||||
tracing::warn!("Error: {e}");
|
.inspect(|_| println!("Using config at: {}", file.as_ref().to_string_lossy()))
|
||||||
|
.inspect_err(|e| {
|
||||||
tracing::warn!(
|
println!("{e}");
|
||||||
|
println!(
|
||||||
"Failed to parse config file at: {}",
|
"Failed to parse config file at: {}",
|
||||||
file.as_ref().to_string_lossy()
|
file.as_ref().to_string_lossy()
|
||||||
);
|
);
|
||||||
|
@ -111,11 +117,17 @@ impl Config {
|
||||||
extra_outbound_connections: self.p2p.clear_net.general.extra_outbound_connections,
|
extra_outbound_connections: self.p2p.clear_net.general.extra_outbound_connections,
|
||||||
max_inbound_connections: self.p2p.clear_net.general.max_inbound_connections,
|
max_inbound_connections: self.p2p.clear_net.general.max_inbound_connections,
|
||||||
gray_peers_percent: self.p2p.clear_net.general.gray_peers_percent,
|
gray_peers_percent: self.p2p.clear_net.general.gray_peers_percent,
|
||||||
server_config: Some(self.p2p.clear_net.server.clone()),
|
server_config: Some(ClearNetServerCfg {
|
||||||
|
ip: self.p2p.clear_net.listen_on,
|
||||||
|
}),
|
||||||
p2p_port: self.p2p.clear_net.general.p2p_port,
|
p2p_port: self.p2p.clear_net.general.p2p_port,
|
||||||
// TODO: set this if a public RPC server is set.
|
// TODO: set this if a public RPC server is set.
|
||||||
rpc_port: 0,
|
rpc_port: 0,
|
||||||
address_book_config: self.p2p.clear_net.general.address_book_config(self.network),
|
address_book_config: self
|
||||||
|
.p2p
|
||||||
|
.clear_net
|
||||||
|
.general
|
||||||
|
.address_book_config(&self.fs.cache_directory, self.network),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,13 +147,13 @@ impl Config {
|
||||||
// We don't set reader threads as we manually make the reader threadpool.
|
// We don't set reader threads as we manually make the reader threadpool.
|
||||||
cuprate_blockchain::config::ConfigBuilder::default()
|
cuprate_blockchain::config::ConfigBuilder::default()
|
||||||
.network(self.network)
|
.network(self.network)
|
||||||
.db_directory(blockchain.shared.path.clone())
|
.data_directory(self.fs.data_directory.clone())
|
||||||
.sync_mode(blockchain.shared.sync_mode)
|
.sync_mode(blockchain.shared.sync_mode)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The [`BlockDownloaderConfig`].
|
/// The [`BlockDownloaderConfig`].
|
||||||
pub const fn block_downloader_config(&self) -> BlockDownloaderConfig {
|
pub fn block_downloader_config(&self) -> BlockDownloaderConfig {
|
||||||
self.p2p.block_downloader
|
self.p2p.block_downloader.clone().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@ use std::{
|
||||||
str::from_utf8,
|
str::from_utf8,
|
||||||
};
|
};
|
||||||
|
|
||||||
use cuprate_helper::fs::{
|
use cuprate_helper::fs::{CUPRATE_CACHE_DIR, DEFAULT_CONFIG_FILE_NAME};
|
||||||
CUPRATE_BLOCKCHAIN_DIR, CUPRATE_CACHE_DIR, CUPRATE_TXPOOL_DIR, DEFAULT_CONFIG_FILE_NAME,
|
|
||||||
};
|
use crate::constants::EXAMPLE_CONFIG;
|
||||||
|
|
||||||
/// Creates a config file which will be named [`DEFAULT_CONFIG_FILE_NAME`] in the directory given in [`Path`].
|
/// Creates a config file which will be named [`DEFAULT_CONFIG_FILE_NAME`] in the directory given in [`Path`].
|
||||||
///
|
///
|
||||||
|
@ -28,50 +28,17 @@ pub fn create_default_config_file(path: &Path) -> ! {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let config = generate_config_text();
|
let config = EXAMPLE_CONFIG;
|
||||||
file.write_all(config.as_bytes()).unwrap();
|
file.write_all(config.as_bytes()).unwrap();
|
||||||
|
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates the text of the default config file.
|
|
||||||
fn generate_config_text() -> String {
|
|
||||||
let toml_value_str = |t: &PathBuf| {
|
|
||||||
let mut value = String::new();
|
|
||||||
|
|
||||||
serde::Serialize::serialize(t, toml::ser::ValueSerializer::new(&mut value)).unwrap();
|
|
||||||
|
|
||||||
value
|
|
||||||
};
|
|
||||||
|
|
||||||
format!(
|
|
||||||
include_str!("Cuprated.toml"),
|
|
||||||
cache = toml_value_str(&CUPRATE_CACHE_DIR),
|
|
||||||
txpool = toml_value_str(&CUPRATE_TXPOOL_DIR),
|
|
||||||
blockchain = toml_value_str(&CUPRATE_BLOCKCHAIN_DIR)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::config::{default::generate_config_text, Config};
|
use crate::{config::Config, constants::EXAMPLE_CONFIG};
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn generate_config_text_covers_all_values() {
|
|
||||||
let text = generate_config_text();
|
|
||||||
let table: toml::Table = toml::from_str(&text).unwrap();
|
|
||||||
|
|
||||||
let full_config = Config::default();
|
|
||||||
let full_config_table: toml::Table =
|
|
||||||
toml::from_str(&toml::to_string(&full_config).unwrap()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(full_config_table, table);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_config_text_is_valid() {
|
fn generate_config_text_is_valid() {
|
||||||
let text = generate_config_text();
|
let config: Config = toml::from_str(EXAMPLE_CONFIG).unwrap();
|
||||||
|
|
||||||
let config: Config = toml::from_str(&text).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
21
binaries/cuprated/src/config/fs.rs
Normal file
21
binaries/cuprated/src/config/fs.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use cuprate_helper::fs::{CUPRATE_CACHE_DIR, CUPRATE_DATA_DIR};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
#[serde(deny_unknown_fields, default)]
|
||||||
|
pub struct FileSystemConfig {
|
||||||
|
pub data_directory: PathBuf,
|
||||||
|
pub cache_directory: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FileSystemConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
data_directory: CUPRATE_DATA_DIR.to_path_buf(),
|
||||||
|
cache_directory: CUPRATE_CACHE_DIR.to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,9 @@
|
||||||
use std::net::SocketAddr;
|
use cuprate_helper::fs::addressbook_path;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use cuprate_address_book::AddressBookConfig;
|
|
||||||
use cuprate_helper::network::Network;
|
use cuprate_helper::network::Network;
|
||||||
use cuprate_p2p::block_downloader::BlockDownloaderConfig;
|
use serde::{Deserialize, Serialize};
|
||||||
use cuprate_p2p_core::ClearNetServerCfg;
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||||
|
use std::path::Path;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
/// P2P config.
|
/// P2P config.
|
||||||
#[derive(Default, Deserialize, Serialize)]
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
|
@ -17,16 +15,62 @@ pub struct P2PConfig {
|
||||||
pub block_downloader: BlockDownloaderConfig,
|
pub block_downloader: BlockDownloaderConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
#[serde(deny_unknown_fields, default)]
|
||||||
|
pub struct BlockDownloaderConfig {
|
||||||
|
/// The size in bytes of the buffer between the block downloader and the place which
|
||||||
|
/// is consuming the downloaded blocks.
|
||||||
|
pub buffer_size: usize,
|
||||||
|
/// The size of the in progress queue (in bytes) at which we stop requesting more blocks.
|
||||||
|
pub in_progress_queue_size: usize,
|
||||||
|
/// The [`Duration`] between checking the client pool for free peers.
|
||||||
|
pub check_client_pool_interval: Duration,
|
||||||
|
/// The target size of a single batch of blocks (in bytes).
|
||||||
|
pub target_batch_size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BlockDownloaderConfig> for cuprate_p2p::block_downloader::BlockDownloaderConfig {
|
||||||
|
fn from(value: BlockDownloaderConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
buffer_size: value.buffer_size,
|
||||||
|
in_progress_queue_size: value.in_progress_queue_size,
|
||||||
|
check_client_pool_interval: value.check_client_pool_interval,
|
||||||
|
target_batch_size: value.target_batch_size,
|
||||||
|
initial_batch_len: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BlockDownloaderConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
buffer_size: 50_000_000,
|
||||||
|
in_progress_queue_size: 50_000_000,
|
||||||
|
check_client_pool_interval: Duration::from_secs(30),
|
||||||
|
target_batch_size: 5_000_000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The config values for P2P clear-net.
|
/// The config values for P2P clear-net.
|
||||||
#[derive(Default, Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
#[serde(deny_unknown_fields, default)]
|
#[serde(deny_unknown_fields, default)]
|
||||||
pub struct ClearNetConfig {
|
pub struct ClearNetConfig {
|
||||||
/// The server config.
|
/// The server config.
|
||||||
pub server: ClearNetServerCfg,
|
pub listen_on: IpAddr,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub general: SharedNetConfig,
|
pub general: SharedNetConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ClearNetConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
listen_on: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
|
general: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Network config values shared between all network zones.
|
/// Network config values shared between all network zones.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
#[serde(deny_unknown_fields, default)]
|
#[serde(deny_unknown_fields, default)]
|
||||||
|
@ -47,14 +91,17 @@ pub struct SharedNetConfig {
|
||||||
|
|
||||||
impl SharedNetConfig {
|
impl SharedNetConfig {
|
||||||
/// Returns the [`AddressBookConfig`].
|
/// Returns the [`AddressBookConfig`].
|
||||||
pub fn address_book_config(&self, network: Network) -> AddressBookConfig {
|
pub fn address_book_config(
|
||||||
// HACK: we add the network here so we don't need to define another address book config.
|
&self,
|
||||||
let mut address_book_config = self.address_book_config.clone();
|
cache_dir: &Path,
|
||||||
address_book_config
|
network: Network,
|
||||||
.peer_store_directory
|
) -> cuprate_address_book::AddressBookConfig {
|
||||||
.push(network.to_string());
|
cuprate_address_book::AddressBookConfig {
|
||||||
|
max_white_list_length: self.address_book_config.max_white_list_length,
|
||||||
address_book_config
|
max_gray_list_length: self.address_book_config.max_gray_list_length,
|
||||||
|
peer_store_directory: addressbook_path(cache_dir, network),
|
||||||
|
peer_save_period: self.address_book_config.peer_save_period,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +118,24 @@ impl Default for SharedNetConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
#[serde(deny_unknown_fields, default)]
|
||||||
|
pub struct AddressBookConfig {
|
||||||
|
max_white_list_length: usize,
|
||||||
|
max_gray_list_length: usize,
|
||||||
|
peer_save_period: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AddressBookConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_white_list_length: 1_000,
|
||||||
|
max_gray_list_length: 5_000,
|
||||||
|
peer_save_period: Duration::from_secs(30),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Seed nodes for [`ClearNet`](cuprate_p2p_core::ClearNet).
|
/// Seed nodes for [`ClearNet`](cuprate_p2p_core::ClearNet).
|
||||||
pub fn clear_net_seed_nodes(network: Network) -> Vec<SocketAddr> {
|
pub fn clear_net_seed_nodes(network: Network) -> Vec<SocketAddr> {
|
||||||
let seeds = match network {
|
let seeds = match network {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use cuprate_database::config::SyncMode;
|
use cuprate_database::config::SyncMode;
|
||||||
use cuprate_database_service::ReaderThreads;
|
use cuprate_database_service::ReaderThreads;
|
||||||
use cuprate_helper::fs::{CUPRATE_BLOCKCHAIN_DIR, CUPRATE_TXPOOL_DIR};
|
use cuprate_helper::fs::CUPRATE_DATA_DIR;
|
||||||
|
|
||||||
/// The storage config.
|
/// The storage config.
|
||||||
#[derive(Default, Deserialize, Serialize)]
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
|
@ -28,7 +29,6 @@ impl Default for BlockchainConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
shared: SharedStorageConfig {
|
shared: SharedStorageConfig {
|
||||||
path: CUPRATE_BLOCKCHAIN_DIR.to_path_buf(),
|
|
||||||
sync_mode: SyncMode::Async,
|
sync_mode: SyncMode::Async,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ impl Default for TxpoolConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
shared: SharedStorageConfig {
|
shared: SharedStorageConfig {
|
||||||
path: CUPRATE_TXPOOL_DIR.to_path_buf(),
|
|
||||||
sync_mode: SyncMode::Async,
|
sync_mode: SyncMode::Async,
|
||||||
},
|
},
|
||||||
max_txpool_byte_size: 100_000_000,
|
max_txpool_byte_size: 100_000_000,
|
||||||
|
@ -59,12 +58,9 @@ impl Default for TxpoolConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Config values shared between the tx-pool and blockchain.
|
/// Config values shared between the tx-pool and blockchain.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Default, Deserialize, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields, default)]
|
||||||
pub struct SharedStorageConfig {
|
pub struct SharedStorageConfig {
|
||||||
/// The path to the database storage.
|
|
||||||
pub path: std::path::PathBuf,
|
|
||||||
/// The [`SyncMode`] of the database.
|
/// The [`SyncMode`] of the database.
|
||||||
#[serde(default)]
|
|
||||||
pub sync_mode: SyncMode,
|
pub sync_mode: SyncMode,
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ pub const VERSION_BUILD: &str = if cfg!(debug_assertions) {
|
||||||
pub const PANIC_CRITICAL_SERVICE_ERROR: &str =
|
pub const PANIC_CRITICAL_SERVICE_ERROR: &str =
|
||||||
"A service critical to Cuprate's function returned an unexpected error.";
|
"A service critical to Cuprate's function returned an unexpected error.";
|
||||||
|
|
||||||
|
pub const EXAMPLE_CONFIG: &str = include_str!("../../../Cuprated.toml");
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -158,37 +158,61 @@ impl_path_lazylock! {
|
||||||
CUPRATE_DATA_DIR,
|
CUPRATE_DATA_DIR,
|
||||||
data_dir,
|
data_dir,
|
||||||
"",
|
"",
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Joins the [`Network`] to the [`Path`].
|
||||||
|
///
|
||||||
|
/// This will keep the path the same for [`Network::Mainnet`].
|
||||||
|
fn path_with_network(path: &Path, network: Network) -> PathBuf {
|
||||||
|
match network {
|
||||||
|
Network::Mainnet => path.to_path_buf(),
|
||||||
|
network => path.join(network.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Cuprate's blockchain directory.
|
/// Cuprate's blockchain directory.
|
||||||
///
|
///
|
||||||
/// This is the PATH used for any Cuprate blockchain files.
|
/// This is the PATH used for any Cuprate blockchain files.
|
||||||
///
|
///
|
||||||
/// | OS | PATH |
|
/// ```rust
|
||||||
/// |---------|----------------------------------------------------------------|
|
/// use cuprate_helper::{network::Network, fs::{CUPRATE_DATA_DIR, blockchain_path}};
|
||||||
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\blockchain\` |
|
///
|
||||||
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/blockchain/` |
|
/// assert_eq!(blockchain_path(&**CUPRATE_DATA_DIR, Network::Mainnet).as_path(), CUPRATE_DATA_DIR.join("blockchain"));
|
||||||
/// | Linux | `/home/alice/.local/share/cuprate/blockchain/` |
|
/// assert_eq!(blockchain_path(&**CUPRATE_DATA_DIR, Network::Stagenet).as_path(), CUPRATE_DATA_DIR.join(Network::Stagenet.to_string()).join("blockchain"));
|
||||||
CUPRATE_BLOCKCHAIN_DIR,
|
/// assert_eq!(blockchain_path(&**CUPRATE_DATA_DIR, Network::Testnet).as_path(), CUPRATE_DATA_DIR.join(Network::Testnet.to_string()).join("blockchain"));
|
||||||
data_dir,
|
/// ```
|
||||||
"blockchain",
|
pub fn blockchain_path(data_dir: &Path, network: Network) -> PathBuf {
|
||||||
|
path_with_network(data_dir, network).join("blockchain")
|
||||||
|
}
|
||||||
|
|
||||||
/// Cuprate's transaction pool directory.
|
/// Cuprate's txpool directory.
|
||||||
///
|
///
|
||||||
/// This is the PATH used for any Cuprate txpool files.
|
/// This is the PATH used for any Cuprate txpool files.
|
||||||
///
|
///
|
||||||
/// | OS | PATH |
|
/// ```rust
|
||||||
/// |---------|------------------------------------------------------------|
|
/// use cuprate_helper::{network::Network, fs::{CUPRATE_DATA_DIR, txpool_path}};
|
||||||
/// | Windows | `C:\Users\Alice\AppData\Roaming\Cuprate\txpool\` |
|
///
|
||||||
/// | macOS | `/Users/Alice/Library/Application Support/Cuprate/txpool/` |
|
/// assert_eq!(txpool_path(&**CUPRATE_DATA_DIR, Network::Mainnet).as_path(), CUPRATE_DATA_DIR.join("txpool"));
|
||||||
/// | Linux | `/home/alice/.local/share/cuprate/txpool/` |
|
/// assert_eq!(txpool_path(&**CUPRATE_DATA_DIR, Network::Stagenet).as_path(), CUPRATE_DATA_DIR.join(Network::Stagenet.to_string()).join("txpool"));
|
||||||
CUPRATE_TXPOOL_DIR,
|
/// assert_eq!(txpool_path(&**CUPRATE_DATA_DIR, Network::Testnet).as_path(), CUPRATE_DATA_DIR.join(Network::Testnet.to_string()).join("txpool"));
|
||||||
data_dir,
|
/// ```
|
||||||
"txpool",
|
pub fn txpool_path(data_dir: &Path, network: Network) -> PathBuf {
|
||||||
|
path_with_network(data_dir, network).join("txpool")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Joins the [`Path`] with a folder for the given [`Network`].
|
/// Cuprate's address-book directory.
|
||||||
pub fn path_with_network(path: &Path, network: Network) -> PathBuf {
|
///
|
||||||
path.join(network.to_string())
|
/// This is the PATH used for any Cuprate address-book files.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use cuprate_helper::{network::Network, fs::{CUPRATE_CACHE_DIR, addressbook_path}};
|
||||||
|
///
|
||||||
|
/// assert_eq!(addressbook_path(&**CUPRATE_CACHE_DIR, Network::Mainnet).as_path(), CUPRATE_CACHE_DIR.join("addressbook"));
|
||||||
|
/// assert_eq!(addressbook_path(&**CUPRATE_CACHE_DIR, Network::Stagenet).as_path(), CUPRATE_CACHE_DIR.join(Network::Stagenet.to_string()).join("addressbook"));
|
||||||
|
/// assert_eq!(addressbook_path(&**CUPRATE_CACHE_DIR, Network::Testnet).as_path(), CUPRATE_CACHE_DIR.join(Network::Testnet.to_string()).join("addressbook"));
|
||||||
|
/// ```
|
||||||
|
pub fn addressbook_path(cache_dir: &Path, network: Network) -> PathBuf {
|
||||||
|
path_with_network(cache_dir, network).join("addressbook")
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Tests
|
//---------------------------------------------------------------------------------------------------- Tests
|
||||||
|
@ -210,29 +234,21 @@ mod test {
|
||||||
(&*CUPRATE_CACHE_DIR, ""),
|
(&*CUPRATE_CACHE_DIR, ""),
|
||||||
(&*CUPRATE_CONFIG_DIR, ""),
|
(&*CUPRATE_CONFIG_DIR, ""),
|
||||||
(&*CUPRATE_DATA_DIR, ""),
|
(&*CUPRATE_DATA_DIR, ""),
|
||||||
(&*CUPRATE_BLOCKCHAIN_DIR, ""),
|
|
||||||
(&*CUPRATE_TXPOOL_DIR, ""),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
array[0].1 = r"AppData\Local\Cuprate";
|
array[0].1 = r"AppData\Local\Cuprate";
|
||||||
array[1].1 = r"AppData\Roaming\Cuprate";
|
array[1].1 = r"AppData\Roaming\Cuprate";
|
||||||
array[2].1 = r"AppData\Roaming\Cuprate";
|
array[2].1 = r"AppData\Roaming\Cuprate";
|
||||||
array[3].1 = r"AppData\Roaming\Cuprate\blockchain";
|
|
||||||
array[4].1 = r"AppData\Roaming\Cuprate\txpool";
|
|
||||||
} else if cfg!(target_os = "macos") {
|
} else if cfg!(target_os = "macos") {
|
||||||
array[0].1 = "Library/Caches/Cuprate";
|
array[0].1 = "Library/Caches/Cuprate";
|
||||||
array[1].1 = "Library/Application Support/Cuprate";
|
array[1].1 = "Library/Application Support/Cuprate";
|
||||||
array[2].1 = "Library/Application Support/Cuprate";
|
array[2].1 = "Library/Application Support/Cuprate";
|
||||||
array[3].1 = "Library/Application Support/Cuprate/blockchain";
|
|
||||||
array[4].1 = "Library/Application Support/Cuprate/txpool";
|
|
||||||
} else {
|
} else {
|
||||||
// Assumes Linux.
|
// Assumes Linux.
|
||||||
array[0].1 = ".cache/cuprate";
|
array[0].1 = ".cache/cuprate";
|
||||||
array[1].1 = ".config/cuprate";
|
array[1].1 = ".config/cuprate";
|
||||||
array[2].1 = ".local/share/cuprate";
|
array[2].1 = ".local/share/cuprate";
|
||||||
array[3].1 = ".local/share/cuprate/blockchain";
|
|
||||||
array[4].1 = ".local/share/cuprate/txpool";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (path, expected) in array {
|
for (path, expected) in array {
|
||||||
|
|
|
@ -5,13 +5,10 @@ edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["Boog900"]
|
authors = ["Boog900"]
|
||||||
|
|
||||||
[features]
|
|
||||||
defualt = []
|
|
||||||
serde_config = ["dep:serde", "dep:cuprate-helper"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cuprate-constants = { workspace = true }
|
cuprate-constants = { workspace = true }
|
||||||
cuprate-helper = { workspace = true, features = ["std", "fs"], optional = true }
|
cuprate-helper = { workspace = true, features = ["std"], optional = true }
|
||||||
cuprate-pruning = { workspace = true }
|
cuprate-pruning = { workspace = true }
|
||||||
cuprate-p2p-core = { workspace = true, features = ["borsh"] }
|
cuprate-p2p-core = { workspace = true, features = ["borsh"] }
|
||||||
|
|
||||||
|
@ -28,7 +25,6 @@ indexmap = { workspace = true, features = ["std"] }
|
||||||
rand = { workspace = true, features = ["std", "std_rng"] }
|
rand = { workspace = true, features = ["std", "std_rng"] }
|
||||||
|
|
||||||
borsh = { workspace = true, features = ["derive", "std"] }
|
borsh = { workspace = true, features = ["derive", "std"] }
|
||||||
serde = { workspace = true, features = ["derive", "std"], optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cuprate-test-utils = { workspace = true }
|
cuprate-test-utils = { workspace = true }
|
||||||
|
|
|
@ -20,8 +20,6 @@ mod store;
|
||||||
|
|
||||||
/// The address book config.
|
/// The address book config.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "serde_config", derive(serde::Deserialize, serde::Serialize))]
|
|
||||||
#[cfg_attr(feature = "serde_config", serde(deny_unknown_fields, default))]
|
|
||||||
pub struct AddressBookConfig {
|
pub struct AddressBookConfig {
|
||||||
/// The maximum number of white peers in the peer list.
|
/// The maximum number of white peers in the peer list.
|
||||||
///
|
///
|
||||||
|
@ -37,18 +35,6 @@ pub struct AddressBookConfig {
|
||||||
pub peer_save_period: Duration,
|
pub peer_save_period: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde_config")]
|
|
||||||
impl Default for AddressBookConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
max_white_list_length: 1000,
|
|
||||||
max_gray_list_length: 5000,
|
|
||||||
peer_store_directory: cuprate_helper::fs::CUPRATE_CACHE_DIR.clone(),
|
|
||||||
peer_save_period: Duration::from_secs(90),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Possible errors when dealing with the address book.
|
/// Possible errors when dealing with the address book.
|
||||||
/// This is boxed when returning an error in the [`tower::Service`].
|
/// This is boxed when returning an error in the [`tower::Service`].
|
||||||
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
|
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
|
||||||
|
|
|
@ -34,8 +34,6 @@ rand_distr = { workspace = true, features = ["std"] }
|
||||||
tracing = { workspace = true, features = ["std", "attributes"] }
|
tracing = { workspace = true, features = ["std", "attributes"] }
|
||||||
borsh = { workspace = true, features = ["derive", "std"] }
|
borsh = { workspace = true, features = ["derive", "std"] }
|
||||||
|
|
||||||
serde = { workspace = true, features = ["std", "derive"], optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
cuprate-test-utils = { workspace = true }
|
cuprate-test-utils = { workspace = true }
|
||||||
indexmap = { workspace = true }
|
indexmap = { workspace = true }
|
||||||
|
|
|
@ -59,8 +59,6 @@ pub struct BlockBatch {
|
||||||
|
|
||||||
/// The block downloader config.
|
/// The block downloader config.
|
||||||
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq)]
|
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
|
||||||
#[cfg_attr(feature = "serde", serde(deny_unknown_fields, default))]
|
|
||||||
pub struct BlockDownloaderConfig {
|
pub struct BlockDownloaderConfig {
|
||||||
/// The size in bytes of the buffer between the block downloader and the place which
|
/// The size in bytes of the buffer between the block downloader and the place which
|
||||||
/// is consuming the downloaded blocks.
|
/// is consuming the downloaded blocks.
|
||||||
|
@ -75,18 +73,6 @@ pub struct BlockDownloaderConfig {
|
||||||
pub initial_batch_len: usize,
|
pub initial_batch_len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for BlockDownloaderConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
buffer_size: 50_000_000,
|
|
||||||
in_progress_queue_size: 50_000_000,
|
|
||||||
check_client_pool_interval: Duration::from_secs(30),
|
|
||||||
target_batch_size: 5_000_000,
|
|
||||||
initial_batch_len: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error that occurred in the [`BlockDownloader`].
|
/// An error that occurred in the [`BlockDownloader`].
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub(crate) enum BlockDownloadError {
|
pub(crate) enum BlockDownloadError {
|
||||||
|
|
|
@ -76,7 +76,7 @@ use cuprate_blockchain::{
|
||||||
let tmp_dir = tempfile::tempdir()?;
|
let tmp_dir = tempfile::tempdir()?;
|
||||||
let db_dir = tmp_dir.path().to_owned();
|
let db_dir = tmp_dir.path().to_owned();
|
||||||
let config = ConfigBuilder::new()
|
let config = ConfigBuilder::new()
|
||||||
.db_directory(db_dir.into())
|
.data_directory(db_dir.into())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Initialize the database environment.
|
// Initialize the database environment.
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
//!
|
//!
|
||||||
//! let config = ConfigBuilder::new()
|
//! let config = ConfigBuilder::new()
|
||||||
//! // Use a custom database directory.
|
//! // Use a custom database directory.
|
||||||
//! .db_directory(db_dir.into())
|
//! .data_directory(db_dir.into())
|
||||||
//! // Use as many reader threads as possible (when using `service`).
|
//! // Use as many reader threads as possible (when using `service`).
|
||||||
//! .reader_threads(ReaderThreads::OnePerThread)
|
//! .reader_threads(ReaderThreads::OnePerThread)
|
||||||
//! // Use the fastest sync mode.
|
//! // Use the fastest sync mode.
|
||||||
|
@ -48,7 +48,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use cuprate_database::{config::SyncMode, resize::ResizeAlgorithm};
|
use cuprate_database::{config::SyncMode, resize::ResizeAlgorithm};
|
||||||
use cuprate_helper::{
|
use cuprate_helper::{
|
||||||
fs::{path_with_network, CUPRATE_BLOCKCHAIN_DIR},
|
fs::{blockchain_path, CUPRATE_DATA_DIR},
|
||||||
network::Network,
|
network::Network,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,8 +64,7 @@ pub use cuprate_database_service::ReaderThreads;
|
||||||
pub struct ConfigBuilder {
|
pub struct ConfigBuilder {
|
||||||
network: Network,
|
network: Network,
|
||||||
|
|
||||||
/// [`Config::db_directory`].
|
data_dir: Option<PathBuf>,
|
||||||
db_directory: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// [`Config::cuprate_database_config`].
|
/// [`Config::cuprate_database_config`].
|
||||||
db_config: cuprate_database::config::ConfigBuilder,
|
db_config: cuprate_database::config::ConfigBuilder,
|
||||||
|
@ -82,10 +81,10 @@ impl ConfigBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
network: Network::default(),
|
network: Network::default(),
|
||||||
db_directory: None,
|
data_dir: None,
|
||||||
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(path_with_network(
|
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(blockchain_path(
|
||||||
&CUPRATE_BLOCKCHAIN_DIR,
|
&CUPRATE_DATA_DIR,
|
||||||
Network::default(),
|
Network::Mainnet,
|
||||||
))),
|
))),
|
||||||
reader_threads: None,
|
reader_threads: None,
|
||||||
}
|
}
|
||||||
|
@ -101,14 +100,14 @@ impl ConfigBuilder {
|
||||||
pub fn build(self) -> Config {
|
pub fn build(self) -> Config {
|
||||||
// INVARIANT: all PATH safety checks are done
|
// INVARIANT: all PATH safety checks are done
|
||||||
// in `helper::fs`. No need to do them here.
|
// in `helper::fs`. No need to do them here.
|
||||||
let db_directory = self
|
let data_dir = self
|
||||||
.db_directory
|
.data_dir
|
||||||
.unwrap_or_else(|| CUPRATE_BLOCKCHAIN_DIR.to_path_buf());
|
.unwrap_or_else(|| CUPRATE_DATA_DIR.to_path_buf());
|
||||||
|
|
||||||
let reader_threads = self.reader_threads.unwrap_or_default();
|
let reader_threads = self.reader_threads.unwrap_or_default();
|
||||||
let db_config = self
|
let db_config = self
|
||||||
.db_config
|
.db_config
|
||||||
.db_directory(Cow::Owned(path_with_network(&db_directory, self.network)))
|
.db_directory(Cow::Owned(blockchain_path(&data_dir, self.network)))
|
||||||
.reader_threads(reader_threads.as_threads())
|
.reader_threads(reader_threads.as_threads())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -127,8 +126,8 @@ impl ConfigBuilder {
|
||||||
|
|
||||||
/// Set a custom database directory (and file) [`PathBuf`].
|
/// Set a custom database directory (and file) [`PathBuf`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn db_directory(mut self, db_directory: PathBuf) -> Self {
|
pub fn data_directory(mut self, db_directory: PathBuf) -> Self {
|
||||||
self.db_directory = Some(db_directory);
|
self.data_dir = Some(db_directory);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,10 +158,7 @@ impl ConfigBuilder {
|
||||||
/// Good default for testing, and resource-available machines.
|
/// Good default for testing, and resource-available machines.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn fast(mut self) -> Self {
|
pub fn fast(mut self) -> Self {
|
||||||
self.db_config = cuprate_database::config::ConfigBuilder::new(Cow::Owned(
|
self.db_config = self.db_config.fast();
|
||||||
path_with_network(&CUPRATE_BLOCKCHAIN_DIR, self.network),
|
|
||||||
))
|
|
||||||
.fast();
|
|
||||||
|
|
||||||
self.reader_threads = Some(ReaderThreads::OnePerThread);
|
self.reader_threads = Some(ReaderThreads::OnePerThread);
|
||||||
self
|
self
|
||||||
|
@ -174,10 +170,7 @@ impl ConfigBuilder {
|
||||||
/// Good default for resource-limited machines, e.g. a cheap VPS.
|
/// Good default for resource-limited machines, e.g. a cheap VPS.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn low_power(mut self) -> Self {
|
pub fn low_power(mut self) -> Self {
|
||||||
self.db_config = cuprate_database::config::ConfigBuilder::new(Cow::Owned(
|
self.db_config = self.db_config.low_power();
|
||||||
path_with_network(&CUPRATE_BLOCKCHAIN_DIR, self.network),
|
|
||||||
))
|
|
||||||
.low_power();
|
|
||||||
|
|
||||||
self.reader_threads = Some(ReaderThreads::One);
|
self.reader_threads = Some(ReaderThreads::One);
|
||||||
self
|
self
|
||||||
|
@ -188,9 +181,9 @@ impl Default for ConfigBuilder {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
network: Network::default(),
|
network: Network::default(),
|
||||||
db_directory: Some(CUPRATE_BLOCKCHAIN_DIR.to_path_buf()),
|
data_dir: Some(CUPRATE_DATA_DIR.to_path_buf()),
|
||||||
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(path_with_network(
|
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(blockchain_path(
|
||||||
&CUPRATE_BLOCKCHAIN_DIR,
|
&CUPRATE_DATA_DIR,
|
||||||
Network::default(),
|
Network::default(),
|
||||||
))),
|
))),
|
||||||
reader_threads: Some(ReaderThreads::default()),
|
reader_threads: Some(ReaderThreads::default()),
|
||||||
|
@ -238,8 +231,8 @@ impl Config {
|
||||||
///
|
///
|
||||||
/// let config = Config::new();
|
/// let config = Config::new();
|
||||||
///
|
///
|
||||||
/// assert_eq!(config.db_config.db_directory().as_ref(), path_with_network(&CUPRATE_BLOCKCHAIN_DIR, Network::Mainnet).as_path());
|
/// assert_eq!(config.db_config.db_directory().as_ref(), blockchain_path(&CUPRATE_DATA_DIR, Network::Mainnet).as_path());
|
||||||
/// assert!(config.db_config.db_file().starts_with(&*CUPRATE_BLOCKCHAIN_DIR));
|
/// assert!(config.db_config.db_file().starts_with(&*CUPRATE_DATA_DIR));
|
||||||
/// assert!(config.db_config.db_file().ends_with(DATABASE_DATA_FILENAME));
|
/// assert!(config.db_config.db_file().ends_with(DATABASE_DATA_FILENAME));
|
||||||
/// assert_eq!(config.db_config.sync_mode, SyncMode::default());
|
/// assert_eq!(config.db_config.sync_mode, SyncMode::default());
|
||||||
/// assert_eq!(config.db_config.resize_algorithm, ResizeAlgorithm::default());
|
/// assert_eq!(config.db_config.resize_algorithm, ResizeAlgorithm::default());
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
//! let tmp_dir = tempfile::tempdir()?;
|
//! let tmp_dir = tempfile::tempdir()?;
|
||||||
//! let db_dir = tmp_dir.path().to_owned();
|
//! let db_dir = tmp_dir.path().to_owned();
|
||||||
//! let config = ConfigBuilder::new()
|
//! let config = ConfigBuilder::new()
|
||||||
//! .db_directory(db_dir.into())
|
//! .data_directory(db_dir.into())
|
||||||
//! .build();
|
//! .build();
|
||||||
//!
|
//!
|
||||||
//! // Initialize the database environment.
|
//! // Initialize the database environment.
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
//! let tmp_dir = tempfile::tempdir()?;
|
//! let tmp_dir = tempfile::tempdir()?;
|
||||||
//! let db_dir = tmp_dir.path().to_owned();
|
//! let db_dir = tmp_dir.path().to_owned();
|
||||||
//! let config = ConfigBuilder::new()
|
//! let config = ConfigBuilder::new()
|
||||||
//! .db_directory(db_dir.into())
|
//! .data_directory(db_dir.into())
|
||||||
//! .build();
|
//! .build();
|
||||||
//!
|
//!
|
||||||
//! // Initialize the database thread-pool.
|
//! // Initialize the database thread-pool.
|
||||||
|
|
|
@ -45,7 +45,7 @@ fn init_service() -> (
|
||||||
) {
|
) {
|
||||||
let tempdir = tempfile::tempdir().unwrap();
|
let tempdir = tempfile::tempdir().unwrap();
|
||||||
let config = ConfigBuilder::new()
|
let config = ConfigBuilder::new()
|
||||||
.db_directory(tempdir.path().into())
|
.data_directory(tempdir.path().into())
|
||||||
.low_power()
|
.low_power()
|
||||||
.build();
|
.build();
|
||||||
let (reader, writer, env) = init(config).unwrap();
|
let (reader, writer, env) = init(config).unwrap();
|
||||||
|
|
|
@ -74,7 +74,7 @@ impl AssertTableLen {
|
||||||
pub(crate) fn tmp_concrete_env() -> (impl Env, tempfile::TempDir) {
|
pub(crate) fn tmp_concrete_env() -> (impl Env, tempfile::TempDir) {
|
||||||
let tempdir = tempfile::tempdir().unwrap();
|
let tempdir = tempfile::tempdir().unwrap();
|
||||||
let config = ConfigBuilder::new()
|
let config = ConfigBuilder::new()
|
||||||
.db_directory(tempdir.path().into())
|
.data_directory(tempdir.path().into())
|
||||||
.low_power()
|
.low_power()
|
||||||
.build();
|
.build();
|
||||||
let env = crate::open(config).unwrap();
|
let env = crate::open(config).unwrap();
|
||||||
|
|
|
@ -10,7 +10,7 @@ use cuprate_database::{
|
||||||
};
|
};
|
||||||
use cuprate_database_service::ReaderThreads;
|
use cuprate_database_service::ReaderThreads;
|
||||||
use cuprate_helper::{
|
use cuprate_helper::{
|
||||||
fs::{path_with_network, CUPRATE_TXPOOL_DIR},
|
fs::{txpool_path, CUPRATE_DATA_DIR},
|
||||||
network::Network,
|
network::Network,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,8 +26,7 @@ const DEFAULT_TXPOOL_WEIGHT_LIMIT: usize = 600 * 1024 * 1024;
|
||||||
pub struct ConfigBuilder {
|
pub struct ConfigBuilder {
|
||||||
network: Network,
|
network: Network,
|
||||||
|
|
||||||
/// [`Config::db_directory`].
|
data_dir: Option<PathBuf>,
|
||||||
db_directory: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// [`Config::cuprate_database_config`].
|
/// [`Config::cuprate_database_config`].
|
||||||
db_config: cuprate_database::config::ConfigBuilder,
|
db_config: cuprate_database::config::ConfigBuilder,
|
||||||
|
@ -47,10 +46,10 @@ impl ConfigBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
network: Network::default(),
|
network: Network::default(),
|
||||||
db_directory: None,
|
data_dir: None,
|
||||||
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(path_with_network(
|
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(txpool_path(
|
||||||
&CUPRATE_TXPOOL_DIR,
|
&CUPRATE_DATA_DIR,
|
||||||
Network::default(),
|
Network::Mainnet,
|
||||||
))),
|
))),
|
||||||
reader_threads: None,
|
reader_threads: None,
|
||||||
max_txpool_weight: None,
|
max_txpool_weight: None,
|
||||||
|
@ -67,9 +66,9 @@ impl ConfigBuilder {
|
||||||
pub fn build(self) -> Config {
|
pub fn build(self) -> Config {
|
||||||
// INVARIANT: all PATH safety checks are done
|
// INVARIANT: all PATH safety checks are done
|
||||||
// in `helper::fs`. No need to do them here.
|
// in `helper::fs`. No need to do them here.
|
||||||
let db_directory = self
|
let data_dir = self
|
||||||
.db_directory
|
.data_dir
|
||||||
.unwrap_or_else(|| CUPRATE_TXPOOL_DIR.to_path_buf());
|
.unwrap_or_else(|| CUPRATE_DATA_DIR.to_path_buf());
|
||||||
|
|
||||||
let reader_threads = self.reader_threads.unwrap_or_default();
|
let reader_threads = self.reader_threads.unwrap_or_default();
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ impl ConfigBuilder {
|
||||||
|
|
||||||
let db_config = self
|
let db_config = self
|
||||||
.db_config
|
.db_config
|
||||||
.db_directory(Cow::Owned(path_with_network(&db_directory, self.network)))
|
.db_directory(Cow::Owned(txpool_path(&data_dir, self.network)))
|
||||||
.reader_threads(reader_threads.as_threads())
|
.reader_threads(reader_threads.as_threads())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -104,10 +103,10 @@ impl ConfigBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a custom database directory (and file) [`PathBuf`].
|
/// Set a custom data directory [`PathBuf`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn db_directory(mut self, db_directory: PathBuf) -> Self {
|
pub fn data_directory(mut self, db_directory: PathBuf) -> Self {
|
||||||
self.db_directory = Some(db_directory);
|
self.data_dir = Some(db_directory);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +137,7 @@ impl ConfigBuilder {
|
||||||
/// Good default for testing, and resource-available machines.
|
/// Good default for testing, and resource-available machines.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn fast(mut self) -> Self {
|
pub fn fast(mut self) -> Self {
|
||||||
self.db_config =
|
self.db_config = self.db_config.fast();
|
||||||
cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(&*CUPRATE_TXPOOL_DIR))
|
|
||||||
.fast();
|
|
||||||
|
|
||||||
self.reader_threads = Some(ReaderThreads::OnePerThread);
|
self.reader_threads = Some(ReaderThreads::OnePerThread);
|
||||||
self
|
self
|
||||||
|
@ -152,9 +149,7 @@ impl ConfigBuilder {
|
||||||
/// Good default for resource-limited machines, e.g. a cheap VPS.
|
/// Good default for resource-limited machines, e.g. a cheap VPS.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn low_power(mut self) -> Self {
|
pub fn low_power(mut self) -> Self {
|
||||||
self.db_config =
|
self.db_config = self.db_config.low_power();
|
||||||
cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(&*CUPRATE_TXPOOL_DIR))
|
|
||||||
.low_power();
|
|
||||||
|
|
||||||
self.reader_threads = Some(ReaderThreads::One);
|
self.reader_threads = Some(ReaderThreads::One);
|
||||||
self
|
self
|
||||||
|
@ -165,10 +160,10 @@ impl Default for ConfigBuilder {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
network: Network::default(),
|
network: Network::default(),
|
||||||
db_directory: Some(CUPRATE_TXPOOL_DIR.to_path_buf()),
|
data_dir: Some(CUPRATE_DATA_DIR.to_path_buf()),
|
||||||
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(path_with_network(
|
db_config: cuprate_database::config::ConfigBuilder::new(Cow::Owned(txpool_path(
|
||||||
&CUPRATE_TXPOOL_DIR,
|
&CUPRATE_DATA_DIR,
|
||||||
Network::default(),
|
Network::Mainnet,
|
||||||
))),
|
))),
|
||||||
reader_threads: Some(ReaderThreads::default()),
|
reader_threads: Some(ReaderThreads::default()),
|
||||||
max_txpool_weight: Some(DEFAULT_TXPOOL_WEIGHT_LIMIT),
|
max_txpool_weight: Some(DEFAULT_TXPOOL_WEIGHT_LIMIT),
|
||||||
|
@ -220,8 +215,8 @@ impl Config {
|
||||||
///
|
///
|
||||||
/// let config = Config::new();
|
/// let config = Config::new();
|
||||||
///
|
///
|
||||||
/// assert_eq!(config.db_config.db_directory(), path_with_network(&CUPRATE_TXPOOL_DIR, Network::Mainnet).as_path());
|
/// assert_eq!(config.db_config.db_directory(), txpool_path(&CUPRATE_DATA_DIR, Network::Mainnet).as_path());
|
||||||
/// assert!(config.db_config.db_file().starts_with(&*CUPRATE_TXPOOL_DIR));
|
/// assert!(config.db_config.db_file().starts_with(&*CUPRATE_DATA_DIR));
|
||||||
/// assert!(config.db_config.db_file().ends_with(DATABASE_DATA_FILENAME));
|
/// assert!(config.db_config.db_file().ends_with(DATABASE_DATA_FILENAME));
|
||||||
/// assert_eq!(config.db_config.sync_mode, SyncMode::default());
|
/// assert_eq!(config.db_config.sync_mode, SyncMode::default());
|
||||||
/// assert_eq!(config.db_config.resize_algorithm, ResizeAlgorithm::default());
|
/// assert_eq!(config.db_config.resize_algorithm, ResizeAlgorithm::default());
|
||||||
|
|
Loading…
Reference in a new issue