cuprated: auto config docs ()

* auto config docs

* fmt & change arg

* fix clippy

* add comment_out functionality

* remove config files + gen in mdbook build

* review fixes

* Update books/user/src/config.md

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

---------

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>
This commit is contained in:
Boog900 2025-04-05 15:33:56 +01:00 committed by GitHub
parent 57cd96ed6c
commit 03363e393d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 444 additions and 242 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@ target/
monerod
books/*/book
fast_sync_hashes.bin
/books/user/Cuprated.toml

1
Cargo.lock generated
View file

@ -1118,6 +1118,7 @@ dependencies = [
"tokio-stream",
"tokio-util",
"toml",
"toml_edit",
"tower 0.5.1",
"tracing",
"tracing-appender",

View file

@ -140,6 +140,7 @@ tokio-stream = { version = "0.1", default-features = false }
tokio = { version = "1", default-features = false }
tower = { git = "https://github.com/Cuprate/tower.git", rev = "6c7faf0", default-features = false } # <https://github.com/tower-rs/tower/pull/796>
toml = { version = "0.8", default-features = false }
toml_edit = { version = "0.22", default-features = false }
tracing-appender = { version = "0.2", default-features = false }
tracing-subscriber = { version = "0.3", default-features = false }
tracing = { version = "0.1", default-features = false }

View file

@ -73,6 +73,7 @@ tokio-util = { workspace = true, features = ["rt"] }
tokio-stream = { workspace = true }
tokio = { workspace = true }
toml = { workspace = true, features = ["parse", "display"]}
toml_edit = { workspace = true }
tower = { workspace = true }
tracing-appender = { workspace = true }
tracing-subscriber = { workspace = true, features = ["std", "fmt", "default"] }

View file

@ -1,64 +0,0 @@
# ____ _
# / ___| _ _ __ _ __ __ _| |_ ___
# | | | | | | '_ \| '__/ _` | __/ _ \
# | |__| |_| | |_) | | | (_| | || __/
# \____\__,_| .__/|_| \__,_|\__\___|
# |_|
#
## The network to run on, valid values: "Mainnet", "Testnet", "Stagenet".
network = "Mainnet"
## Tracing config.
[tracing]
## The stdout logging config.
stdout = { level = "info" }
## The file output logging config.
file = { level = "debug", max_log_files = 7 }
## Clear-net config.
[p2p.clear_net]
## The number of outbound connections we should make and maintain.
outbound_connections = 64
## The number of extra connections we should make under load from the rest of Cuprate, i.e. when syncing.
extra_outbound_connections = 8
## The maximum number of incoming we should allow.
max_inbound_connections = 128
## The percent of outbound connections that should be to nodes we have not connected to before.
gray_peers_percent = 0.7
## The port to accept connections on, if left `0` no connections will be accepted.
p2p_port = 0
## The IP address to listen to connections on.
listen_on = "0.0.0.0"
## The Clear-net addressbook config.
[p2p.clear_net.address_book_config]
## The size of the white peer list, which contains peers we have made a connection to before.
max_white_list_length = 1_000
## The size of the gray peer list, which contains peers we have not made a connection to before.
max_gray_list_length = 5_000
## The amount of time between address book saves.
peer_save_period = { secs = 90, nanos = 0 }
## The block downloader config.
[p2p.block_downloader]
## The size of the buffer of sequential blocks waiting to be verified and added to the chain (bytes).
buffer_bytes = 1_000_000_000
## The size of the queue of blocks which are waiting for a parent block to be downloaded (bytes).
in_progress_queue_bytes = 500_000_000
## The target size of a batch of blocks (bytes), must not exceed 100MB.
target_batch_bytes = 10_000_000
## 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 }
## Txpool storage config.
[storage.txpool]
## The database sync mode for the txpool.
sync_mode = "Fast"
## The maximum size of all the txs in the pool (bytes).
max_txpool_byte_size = 100_000_000
## Blockchain storage config.
[storage.blockchain]
## The database sync mode for the blockchain.
sync_mode = "Fast"

View file

@ -1 +0,0 @@
0.0.1.toml

View file

@ -1,6 +0,0 @@
# `cuprated` configs
This directory holds configuration files for all `cuprated` versions.
For example, `0.0.1.toml` is the config file for `cuprated v0.0.1`.
`Cuprated.toml` is a symlink to the latest config file.

View file

@ -3,6 +3,7 @@ use std::{
fs::{read_to_string, File},
io,
path::Path,
str::FromStr,
time::Duration,
};
@ -30,6 +31,9 @@ mod storage;
mod tokio;
mod tracing_config;
#[macro_use]
mod macros;
use fs::FileSystemConfig;
use p2p::P2PConfig;
use rayon::RayonConfig;
@ -37,6 +41,19 @@ use storage::StorageConfig;
use tokio::TokioConfig;
use tracing_config::TracingConfig;
/// Header to put at the start of the generated config file.
const HEADER: &str = r"## ____ _
## / ___| _ _ __ _ __ __ _| |_ ___
## | | | | | | '_ \| '__/ _` | __/ _ \
## | |__| |_| | |_) | | | (_| | || __/
## \____\__,_| .__/|_| \__,_|\__\___|
## |_|
##
## All these config values can be set to their default by commenting them out with #.
## Some values are already commented out, to set the value remove the # at the start of the line.
";
/// Reads the args & config file, returning a [`Config`].
pub fn read_config_and_args() -> Config {
let args = args::Args::parse();
@ -76,32 +93,76 @@ pub fn read_config_and_args() -> Config {
args.apply_args(config)
}
/// The config for all of Cuprate.
#[derive(Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct Config {
/// The network we should run on.
network: Network,
config_struct! {
/// The config for all of Cuprate.
#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct Config {
/// The network we should run on.
///
/// Valid values: ["Mainnet", "Testnet" and "Stagenet"]
pub network: Network,
pub no_fast_sync: bool,
/// Enable/disable fast sync.
///
/// Fast sync skips verification of old blocks by comparing block hashes to a built-in hash file,
/// disabling this will significantly increase sync time. New blocks are still fully validated.
pub fast_sync: bool,
/// [`tracing`] config.
pub tracing: TracingConfig,
#[child = true]
/// The tracing/log output config.
pub tracing: TracingConfig,
pub tokio: TokioConfig,
#[child = true]
/// The tokio config.
///
/// Tokio is the async threadpool, used for network operations and the major service inside `cuprated`.
pub rayon: RayonConfig,
pub tokio: TokioConfig,
#[child = true]
/// The rayon config.
///
/// Rayon is the CPU threadpool, used for CPU intensive tasks.
pub rayon: RayonConfig,
/// The P2P network config.
p2p: P2PConfig,
#[child = true]
/// The P2P network config.
pub p2p: P2PConfig,
/// The storage config.
pub storage: StorageConfig,
#[child = true]
/// The storage config.
pub storage: StorageConfig,
pub fs: FileSystemConfig,
#[child = true]
/// The filesystem config.
pub fs: FileSystemConfig,
}
}
impl Default for Config {
fn default() -> Self {
Self {
network: Default::default(),
fast_sync: true,
tracing: Default::default(),
tokio: Default::default(),
rayon: Default::default(),
p2p: Default::default(),
storage: Default::default(),
fs: Default::default(),
}
}
}
impl Config {
/// Returns a default [`Config`], with doc comments.
pub fn documented_config() -> String {
let str = toml::ser::to_string_pretty(&Self::default()).unwrap();
let mut doc = toml_edit::DocumentMut::from_str(&str).unwrap();
Self::write_docs(doc.as_table_mut());
format!("{HEADER}{doc}")
}
/// Attempts to read a config file in [`toml`] format from the given [`Path`].
///
/// # Errors
@ -193,30 +254,13 @@ impl Config {
mod test {
use toml::from_str;
use crate::constants::EXAMPLE_CONFIG;
use super::*;
/// Tests the latest config is the `Default`.
#[test]
fn config_latest() {
let config: Config = from_str(EXAMPLE_CONFIG).unwrap();
assert_eq!(config, Config::default());
}
fn documented_config() {
let str = Config::documented_config();
let conf: Config = from_str(&str).unwrap();
/// Tests backwards compatibility.
#[test]
fn config_backwards_compat() {
// (De)serialization tests.
#[expect(
clippy::single_element_loop,
reason = "Remove after adding other versions"
)]
for version in ["0.0.1"] {
let path = format!("config/{version}.toml");
println!("Testing config serde backwards compat: {path}");
let string = read_to_string(path).unwrap();
from_str::<Config>(&string).unwrap();
}
assert_eq!(conf, Config::default());
}
}

View file

@ -5,7 +5,7 @@ use serde_json::Value;
use cuprate_helper::network::Network;
use crate::{config::Config, constants::EXAMPLE_CONFIG, version::CupratedVersionInfo};
use crate::{config::Config, version::CupratedVersionInfo};
/// Cuprate Args.
#[derive(clap::Parser, Debug)]
@ -61,7 +61,7 @@ impl Args {
}
if self.generate_config {
println!("{EXAMPLE_CONFIG}");
println!("{}", Config::documented_config());
exit(0);
}
}
@ -71,7 +71,7 @@ impl Args {
/// This may exit the program if a config value was set that requires an early exit.
pub const fn apply_args(&self, mut config: Config) -> Config {
config.network = self.network;
config.no_fast_sync = config.no_fast_sync || self.no_fast_sync;
config.fast_sync = config.fast_sync && !self.no_fast_sync;
if let Some(outbound_connections) = self.outbound_connections {
config.p2p.clear_net.general.outbound_connections = outbound_connections;

View file

@ -4,11 +4,21 @@ use serde::{Deserialize, Serialize};
use cuprate_helper::fs::{CUPRATE_CACHE_DIR, CUPRATE_DATA_DIR};
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct FileSystemConfig {
pub data_directory: PathBuf,
pub cache_directory: PathBuf,
use super::macros::config_struct;
config_struct! {
/// The file system config.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct FileSystemConfig {
#[comment_out = true]
/// The data directory.
pub data_directory: PathBuf,
#[comment_out = true]
/// The cache directory.
pub cache_directory: PathBuf,
}
}
impl Default for FileSystemConfig {

View file

@ -0,0 +1,86 @@
use toml_edit::TableLike;
/// A macro for config structs defined in `cuprated`. This macro generates a function that
/// can insert toml comments created from doc comments on fields.
///
/// # Attributes
/// - `#[flatten = true]`: lets the writer know that the field is flattened into the parent struct.
/// - `#[child = true]`: writes the doc comments for all fields in the child struct.
/// - `#[inline = true]`: inlines the struct into `{}` instead of having a separate `[]` header.
/// - `#[comment_out = true]`: comments out the field.
macro_rules! config_struct {
(
$(#[$meta:meta])*
pub struct $name:ident {
$(
$(#[flatten = $flat:literal])?
$(#[child = $child:literal])?
$(#[inline = $inline:literal])?
$(#[comment_out = $comment_out:literal])?
$(#[doc = $doc:expr])*
$(##[$field_meta:meta])*
pub $field:ident: $field_ty:ty,
)*
}
) => {
$(#[$meta])*
pub struct $name {
$(
$(#[doc = $doc])*
$(#[$field_meta])*
pub $field: $field_ty,
)*
}
impl $name {
#[allow(unused_labels, clippy::allow_attributes)]
pub fn write_docs(doc: &mut dyn ::toml_edit::TableLike) {
$(
'write_field: {
let key_str = &stringify!($field);
let mut field_prefix = [ $(
format!("##{}\n", $doc),
)*].concat();
$(
if $comment_out {
field_prefix.push('#');
}
)?
$(
if $flat {
<$field_ty>::write_docs(doc);
break 'write_field;
}
)?
$(
if $child {
<$field_ty>::write_docs(doc.get_key_value_mut(&key_str).unwrap().1.as_table_like_mut().unwrap());
}
)?
if let Some(table) = doc.entry(&key_str).or_insert_with(|| panic!()).as_table_mut() {
$(
if $inline {
let mut table = table.clone().into_inline_table();
doc.insert(&key_str, ::toml_edit::Item::Value(::toml_edit::Value::InlineTable(table)));
doc.key_mut(&key_str).unwrap().leaf_decor_mut().set_prefix(field_prefix);
break 'write_field;
}
)?
table.decor_mut().set_prefix(format!("\n{}", field_prefix));
}else {
doc.key_mut(&key_str).unwrap().leaf_decor_mut().set_prefix(field_prefix);
}
}
)*
}
}
};
}
pub(crate) use config_struct;

View file

@ -8,28 +8,54 @@ use serde::{Deserialize, Serialize};
use cuprate_helper::{fs::address_book_path, network::Network};
/// P2P config.
#[derive(Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct P2PConfig {
/// Clear-net config.
pub clear_net: ClearNetConfig,
/// Block downloader config.
pub block_downloader: BlockDownloaderConfig,
use super::macros::config_struct;
config_struct! {
/// P2P config.
#[derive(Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct P2PConfig {
#[child = true]
/// The clear-net P2P config.
pub clear_net: ClearNetConfig,
#[child = true]
/// Block downloader config.
///
/// The block downloader handles downloading old blocks from peers when we are behind.
pub block_downloader: BlockDownloaderConfig,
}
}
#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)]
#[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_bytes: usize,
/// The size of the in progress queue (in bytes) at which we stop requesting more blocks.
pub in_progress_queue_bytes: 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_bytes: usize,
config_struct! {
#[derive(Debug, Clone, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct BlockDownloaderConfig {
#[comment_out = true]
/// The size in bytes of the buffer between the block downloader and the place which
/// is consuming the downloaded blocks (`cuprated`).
///
/// This value is an absolute maximum, once this is reached the block downloader will pause.
pub buffer_bytes: usize,
#[comment_out = true]
/// The size of the in progress queue (in bytes) at which we stop requesting more blocks.
///
/// The value is _NOT_ an absolute maximum, the in progress queue could get much larger. This value
/// is only the value we stop requesting more blocks, if we still have requests in progress we will
/// still accept the response and add the blocks to the queue.
pub in_progress_queue_bytes: usize,
#[inline = true]
/// The [`Duration`] between checking the client pool for free peers.
pub check_client_pool_interval: Duration,
#[comment_out = true]
/// The target size of a single batch of blocks (in bytes).
///
/// This value must be below 100_000_000, it is not recommended to set it above 30_000_000.
pub target_batch_bytes: usize,
}
}
impl From<BlockDownloaderConfig> for cuprate_p2p::block_downloader::BlockDownloaderConfig {
@ -50,19 +76,24 @@ impl Default for BlockDownloaderConfig {
buffer_bytes: 1_000_000_000,
in_progress_queue_bytes: 500_000_000,
check_client_pool_interval: Duration::from_secs(30),
target_batch_bytes: 10_000_000,
target_batch_bytes: 15_000_000,
}
}
}
/// The config values for P2P clear-net.
#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct ClearNetConfig {
/// The server config.
pub listen_on: IpAddr,
#[serde(flatten)]
pub general: SharedNetConfig,
config_struct! {
/// The config values for P2P clear-net.
#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct ClearNetConfig {
/// The IP address we should bind to to listen to connections on.
pub listen_on: IpAddr,
#[flatten = true]
/// Shared config values.
##[serde(flatten)]
pub general: SharedNetConfig,
}
}
impl Default for ClearNetConfig {
@ -74,26 +105,42 @@ impl Default for ClearNetConfig {
}
}
/// Network config values shared between all network zones.
#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct SharedNetConfig {
/// The number of outbound connections to make and try keep.
pub outbound_connections: usize,
/// The amount of extra connections we can make if we are under load from the rest of Cuprate.
pub extra_outbound_connections: usize,
/// The maximum amount of inbound connections
pub max_inbound_connections: usize,
/// The percent of connections that should be to peers we haven't connected to before.
pub gray_peers_percent: f64,
/// port to use to accept p2p connections.
pub p2p_port: u16,
/// The address book config.
address_book_config: AddressBookConfig,
config_struct! {
/// Network config values shared between all network zones.
#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct SharedNetConfig {
#[comment_out = true]
/// The number of outbound connections to make and try keep.
///
/// Recommended to keep this value above 12.
pub outbound_connections: usize,
#[comment_out = true]
/// The amount of extra connections we can make if we are under load from the rest of Cuprate.
pub extra_outbound_connections: usize,
#[comment_out = true]
/// The maximum amount of inbound connections we should allow.
pub max_inbound_connections: usize,
#[comment_out = true]
/// The percent of connections that should be to peers we haven't connected to before.
pub gray_peers_percent: f64,
/// port to use to accept p2p connections.
///
/// Set to 0 if you do not want to accept P2P connections.
pub p2p_port: u16,
#[child = true]
/// The address book config.
pub address_book_config: AddressBookConfig,
}
}
impl SharedNetConfig {
/// Returns the [`AddressBookConfig`].
/// Returns the [`cuprate_address_book::AddressBookConfig`].
pub fn address_book_config(
&self,
cache_dir: &Path,
@ -111,22 +158,35 @@ impl SharedNetConfig {
impl Default for SharedNetConfig {
fn default() -> Self {
Self {
outbound_connections: 64,
outbound_connections: 32,
extra_outbound_connections: 8,
max_inbound_connections: 128,
gray_peers_percent: 0.7,
p2p_port: 0,
p2p_port: 18080,
address_book_config: AddressBookConfig::default(),
}
}
}
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct AddressBookConfig {
max_white_list_length: usize,
max_gray_list_length: usize,
peer_save_period: Duration,
config_struct! {
/// The addressbook config exposed to users.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct AddressBookConfig {
/// The size of the white peer list.
///
/// The white list holds peers we have connected to before.
pub max_white_list_length: usize,
/// The size of the gray peer list.
///
/// The gray peer list holds peers we have been told about but not connected to ourself.
pub max_gray_list_length: usize,
#[inline = true]
/// The time period between address book saves.
pub peer_save_period: Duration,
}
}
impl Default for AddressBookConfig {

View file

@ -1,11 +1,16 @@
use serde::{Deserialize, Serialize};
/// The [`rayon`] config.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct RayonConfig {
/// The number of threads to use for the [`rayon::ThreadPool`].
pub threads: usize,
use super::macros::config_struct;
config_struct! {
/// The [`rayon`] config.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct RayonConfig {
#[comment_out = true]
/// The number of threads to use for the rayon thread pool.
pub threads: usize,
}
}
impl Default for RayonConfig {

View file

@ -6,16 +6,27 @@ use cuprate_database::config::SyncMode;
use cuprate_database_service::ReaderThreads;
use cuprate_helper::fs::CUPRATE_DATA_DIR;
/// The storage config.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct StorageConfig {
/// The amount of reader threads to spawn between the tx-pool and blockchain.
pub reader_threads: usize,
/// The tx-pool config.
pub txpool: TxpoolConfig,
/// The blockchain config.
pub blockchain: BlockchainConfig,
use super::macros::config_struct;
config_struct! {
/// The storage config.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct StorageConfig {
#[comment_out = true]
/// The amount of reader threads to spawn for the tx-pool and blockchain.
///
/// The tx-pool and blockchain both share a single threadpool.
pub reader_threads: usize,
#[child = true]
/// The tx-pool config.
pub txpool: TxpoolConfig,
#[child = true]
/// The blockchain config.
pub blockchain: BlockchainConfig,
}
}
impl Default for StorageConfig {
@ -28,23 +39,31 @@ impl Default for StorageConfig {
}
}
/// The blockchain config.
#[derive(Default, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct BlockchainConfig {
#[serde(flatten)]
pub shared: SharedStorageConfig,
config_struct! {
/// The blockchain config.
#[derive(Default, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct BlockchainConfig {
#[flatten = true]
/// Shared config.
##[serde(flatten)]
pub shared: SharedStorageConfig,
}
}
/// The tx-pool config.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct TxpoolConfig {
#[serde(flatten)]
pub shared: SharedStorageConfig,
config_struct! {
/// The tx-pool config.
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct TxpoolConfig {
#[flatten = true]
/// Shared config.
##[serde(flatten)]
pub shared: SharedStorageConfig,
/// The maximum size of the tx-pool.
pub max_txpool_byte_size: usize,
/// The maximum size of the tx-pool.
pub max_txpool_byte_size: usize,
}
}
impl Default for TxpoolConfig {
@ -56,10 +75,18 @@ impl Default for TxpoolConfig {
}
}
/// Config values shared between the tx-pool and blockchain.
#[derive(Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct SharedStorageConfig {
/// The [`SyncMode`] of the database.
pub sync_mode: SyncMode,
config_struct! {
/// Config values shared between the tx-pool and blockchain.
#[derive(Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields, default)]
pub struct SharedStorageConfig {
#[comment_out = true]
/// The sync mode of the database.
///
/// Changing this value could make the DB a lot slower when writing data, although
/// using "Safe" makes the DB more durable if there was an unexpected crash.
///
/// Valid values: ["Fast", "Safe"].
pub sync_mode: SyncMode,
}
}

View file

@ -1,11 +1,16 @@
use serde::{Deserialize, Serialize};
/// [`tokio`] config.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct TokioConfig {
/// The amount of threads to spawn for the async thread-pool
pub threads: usize,
use super::macros::config_struct;
config_struct! {
/// [`tokio`] config.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct TokioConfig {
#[comment_out = true]
/// The amount of threads to spawn for the async thread-pool
pub threads: usize,
}
}
impl Default for TokioConfig {

View file

@ -1,20 +1,31 @@
use serde::{Deserialize, Serialize};
use tracing::level_filters::LevelFilter;
/// [`tracing`] config.
#[derive(Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct TracingConfig {
pub stdout: StdoutTracingConfig,
pub file: FileTracingConfig,
use super::macros::config_struct;
config_struct! {
/// [`tracing`] config.
#[derive(Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct TracingConfig {
#[child = true]
/// The stdout logging config.
pub stdout: StdoutTracingConfig,
#[child = true]
/// The file logging config.
pub file: FileTracingConfig,
}
}
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct StdoutTracingConfig {
/// The default minimum log level.
#[serde(with = "level_filter_serde")]
pub level: LevelFilter,
config_struct! {
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct StdoutTracingConfig {
/// The default minimum log level.
##[serde(with = "level_filter_serde")]
pub level: LevelFilter,
}
}
impl Default for StdoutTracingConfig {
@ -25,15 +36,18 @@ impl Default for StdoutTracingConfig {
}
}
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct FileTracingConfig {
/// The default minimum log level.
#[serde(with = "level_filter_serde")]
pub level: LevelFilter,
/// The maximum amount of log files to keep, once this number is passed the oldest file
/// will be deleted.
pub max_log_files: usize,
config_struct! {
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, default)]
pub struct FileTracingConfig {
/// The default minimum log level.
##[serde(with = "level_filter_serde")]
pub level: LevelFilter,
/// The maximum amount of log files to keep, once this number is passed the oldest file
/// will be deleted.
pub max_log_files: usize,
}
}
impl Default for FileTracingConfig {

View file

@ -34,8 +34,6 @@ pub const DEFAULT_CONFIG_WARNING: &str = formatcp!(
pub const DEFAULT_CONFIG_STARTUP_DELAY: Duration = Duration::from_secs(15);
pub const EXAMPLE_CONFIG: &str = include_str!("../config/Cuprated.toml");
#[cfg(test)]
mod test {
use super::*;

View file

@ -55,7 +55,7 @@ fn main() {
let config = config::read_config_and_args();
blockchain::set_fast_sync_hashes(!config.no_fast_sync, config.network());
blockchain::set_fast_sync_hashes(config.fast_sync, config.network());
// Initialize logging.
logging::init_logging(&config);

View file

@ -21,17 +21,16 @@ cargo install mdbook
## Building
To build a book, go into a book's directory and build:
To build a book, from the root of Cuprate:
```bash
# This build Cuprate's user book.
cd user/
mdbook build
mdbook build ./books/user
```
The output will be in the `book` subdirectory (`user/book` for the above example). To open the book, you can open it in
your web browser like so:
```bash
mdbook build --open
mdbook build ./books/user --open
```

View file

@ -10,3 +10,6 @@ git-repository-url = "https://github.com/Cuprate/cuprate/books/user"
default-theme = "ayu"
preferred-dark-theme = "ayu"
no-section-label = true
[preprocessor.gen_config]
command = "bash ./books/user/gen_config.sh"

16
books/user/gen_config.sh Normal file
View file

@ -0,0 +1,16 @@
#!/bin/bash
# https://rust-lang.github.io/mdBook/for_developers/preprocessors.html
# This script is called twice, the first is just to check support.
if [ "$1" == "supports" ]; then
# return 0 - we support everything.
exit 0;
fi
# Second call - generate config.
cargo run --bin cuprated -- --generate-config > ./books/user/Cuprated.toml
# This looks weird but mdbook hands us 2 JSON maps, we need to return the second with any edits we want to make.
# We don't want to make any edits, so we can just read & return the second JSON map straight away.
jq '.[1]'

View file

@ -7,10 +7,12 @@
- [OS specific directory](./resources/disk.md)
## `Cuprated.toml`
This is the default configuration file `cuprated` creates and uses, sourced from [here](https://github.com/Cuprate/cuprate/blob/main/binaries/cuprated/config/Cuprated.toml).
This is the default configuration file `cuprated` creates and uses.
If `cuprated` is started with no [`--options`](./cli.md), then the configuration used will be equivalent to this config file.
> Some values may be different for your exact system, generate the config with `cuprated --generate-config` to see the defaults for your system.
```toml
{{#include ../../../binaries/cuprated/config/Cuprated.toml}}
{{#include ../Cuprated.toml}}
```