mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
dep: rm confy as a dep (#10290)
Co-authored-by: Alexey Shekhirin <a.shekhirin@gmail.com>
This commit is contained in:
29
Cargo.lock
generated
29
Cargo.lock
generated
@ -1857,18 +1857,6 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "confy"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "45b1f4c00870f07dc34adcac82bb6a72cc5aabca8536ba1797e01df51d2ce9a0"
|
|
||||||
dependencies = [
|
|
||||||
"directories",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"toml",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console"
|
name = "console"
|
||||||
version = "0.15.8"
|
version = "0.15.8"
|
||||||
@ -2416,15 +2404,6 @@ dependencies = [
|
|||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "directories"
|
|
||||||
version = "5.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
|
||||||
dependencies = [
|
|
||||||
"dirs-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "5.0.1"
|
version = "5.0.1"
|
||||||
@ -6226,7 +6205,6 @@ dependencies = [
|
|||||||
"aquamarine",
|
"aquamarine",
|
||||||
"backon",
|
"backon",
|
||||||
"clap",
|
"clap",
|
||||||
"confy",
|
|
||||||
"discv5",
|
"discv5",
|
||||||
"eyre",
|
"eyre",
|
||||||
"fdlimit",
|
"fdlimit",
|
||||||
@ -6551,7 +6529,6 @@ dependencies = [
|
|||||||
"backon",
|
"backon",
|
||||||
"clap",
|
"clap",
|
||||||
"comfy-table",
|
"comfy-table",
|
||||||
"confy",
|
|
||||||
"crossterm",
|
"crossterm",
|
||||||
"eyre",
|
"eyre",
|
||||||
"fdlimit",
|
"fdlimit",
|
||||||
@ -6658,7 +6635,7 @@ dependencies = [
|
|||||||
name = "reth-config"
|
name = "reth-config"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"confy",
|
"eyre",
|
||||||
"humantime-serde",
|
"humantime-serde",
|
||||||
"reth-network-peers",
|
"reth-network-peers",
|
||||||
"reth-network-types",
|
"reth-network-types",
|
||||||
@ -7693,7 +7670,6 @@ name = "reth-node-builder"
|
|||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aquamarine",
|
"aquamarine",
|
||||||
"confy",
|
|
||||||
"eyre",
|
"eyre",
|
||||||
"fdlimit",
|
"fdlimit",
|
||||||
"futures",
|
"futures",
|
||||||
@ -7788,9 +7764,12 @@ dependencies = [
|
|||||||
"reth-tracing",
|
"reth-tracing",
|
||||||
"reth-transaction-pool",
|
"reth-transaction-pool",
|
||||||
"secp256k1",
|
"secp256k1",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"vergen",
|
"vergen",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -527,7 +527,6 @@ secp256k1 = { version = "0.29", default-features = false, features = [
|
|||||||
c-kzg = "1.0.0"
|
c-kzg = "1.0.0"
|
||||||
|
|
||||||
# config
|
# config
|
||||||
confy = "0.6"
|
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
|
|
||||||
# misc-testing
|
# misc-testing
|
||||||
|
|||||||
@ -83,7 +83,6 @@ tracing.workspace = true
|
|||||||
fdlimit.workspace = true
|
fdlimit.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
confy.workspace = true
|
|
||||||
toml = { workspace = true, features = ["display"] }
|
toml = { workspace = true, features = ["display"] }
|
||||||
|
|
||||||
# metrics
|
# metrics
|
||||||
|
|||||||
@ -58,7 +58,6 @@ secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recov
|
|||||||
|
|
||||||
# io
|
# io
|
||||||
fdlimit.workspace = true
|
fdlimit.workspace = true
|
||||||
confy.workspace = true
|
|
||||||
toml = { workspace = true, features = ["display"] }
|
toml = { workspace = true, features = ["display"] }
|
||||||
|
|
||||||
# tui
|
# tui
|
||||||
|
|||||||
@ -65,7 +65,8 @@ impl EnvironmentArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
|
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
|
||||||
let mut config: Config = confy::load_path(config_path)
|
|
||||||
|
let mut config = Config::from_path(config_path)
|
||||||
.inspect_err(
|
.inspect_err(
|
||||||
|err| warn!(target: "reth::cli", %err, "Failed to load config file, using default"),
|
|err| warn!(target: "reth::cli", %err, "Failed to load config file, using default"),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -25,11 +25,12 @@ impl Command {
|
|||||||
Config::default()
|
Config::default()
|
||||||
} else {
|
} else {
|
||||||
let path = self.config.clone().unwrap_or_default();
|
let path = self.config.clone().unwrap_or_default();
|
||||||
// confy will create the file if it doesn't exist; we don't want this
|
// Check if the file exists
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
bail!("Config file does not exist: {}", path.display());
|
bail!("Config file does not exist: {}", path.display());
|
||||||
}
|
}
|
||||||
confy::load_path::<Config>(&path)
|
// Read the configuration file
|
||||||
|
Config::from_path(&path)
|
||||||
.wrap_err_with(|| format!("Could not load config file: {}", path.display()))?
|
.wrap_err_with(|| format!("Could not load config file: {}", path.display()))?
|
||||||
};
|
};
|
||||||
println!("{}", toml::to_string_pretty(&config)?);
|
println!("{}", toml::to_string_pretty(&config)?);
|
||||||
|
|||||||
@ -74,13 +74,15 @@ pub enum Subcommands {
|
|||||||
// RLPx utilities
|
// RLPx utilities
|
||||||
Rlpx(rlpx::Command),
|
Rlpx(rlpx::Command),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
/// Execute `p2p` command
|
/// Execute `p2p` command
|
||||||
pub async fn execute(self) -> eyre::Result<()> {
|
pub async fn execute(self) -> eyre::Result<()> {
|
||||||
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain);
|
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain);
|
||||||
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
|
let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
|
||||||
|
|
||||||
let mut config: Config = confy::load_path(&config_path).unwrap_or_default();
|
// Load configuration
|
||||||
|
let mut config = Config::from_path(&config_path).unwrap_or_default();
|
||||||
|
|
||||||
config.peers.trusted_nodes.extend(self.network.trusted_peers.clone());
|
config.peers.trusted_nodes.extend(self.network.trusted_peers.clone());
|
||||||
|
|
||||||
|
|||||||
@ -21,9 +21,9 @@ serde.workspace = true
|
|||||||
humantime-serde.workspace = true
|
humantime-serde.workspace = true
|
||||||
|
|
||||||
# toml
|
# toml
|
||||||
confy.workspace = true
|
toml.workspace = true
|
||||||
|
eyre.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile.workspace = true
|
tempfile.workspace = true
|
||||||
toml.workspace = true
|
|
||||||
reth-network-peers.workspace = true
|
reth-network-peers.workspace = true
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
//! Configuration files.
|
//! Configuration files.
|
||||||
|
|
||||||
|
use eyre::eyre;
|
||||||
use reth_network_types::{PeersConfig, SessionsConfig};
|
use reth_network_types::{PeersConfig, SessionsConfig};
|
||||||
use reth_prune_types::PruneModes;
|
use reth_prune_types::PruneModes;
|
||||||
use reth_stages_types::ExecutionStageThresholds;
|
use reth_stages_types::ExecutionStageThresholds;
|
||||||
use serde::{Deserialize, Deserializer, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
|
fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@ -29,6 +31,31 @@ pub struct Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
/// Load a [`Config`] from a specified path.
|
||||||
|
///
|
||||||
|
/// A new configuration file is created with default values if none
|
||||||
|
/// exists.
|
||||||
|
pub fn from_path(path: impl AsRef<Path>) -> eyre::Result<Self> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
match fs::read_to_string(path) {
|
||||||
|
Ok(cfg_string) => {
|
||||||
|
toml::from_str(&cfg_string).map_err(|e| eyre!("Failed to parse TOML: {e}"))
|
||||||
|
}
|
||||||
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
fs::create_dir_all(parent)
|
||||||
|
.map_err(|e| eyre!("Failed to create directory: {e}"))?;
|
||||||
|
}
|
||||||
|
let cfg = Self::default();
|
||||||
|
let s = toml::to_string_pretty(&cfg)
|
||||||
|
.map_err(|e| eyre!("Failed to serialize to TOML: {e}"))?;
|
||||||
|
fs::write(path, s).map_err(|e| eyre!("Failed to write configuration file: {e}"))?;
|
||||||
|
Ok(cfg)
|
||||||
|
}
|
||||||
|
Err(e) => Err(eyre!("Failed to load configuration: {e}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the [`PeersConfig`] for the node.
|
/// Returns the [`PeersConfig`] for the node.
|
||||||
///
|
///
|
||||||
/// If a peers file is provided, the basic nodes from the file are added to the configuration.
|
/// If a peers file is provided, the basic nodes from the file are added to the configuration.
|
||||||
@ -48,9 +75,14 @@ impl Config {
|
|||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
std::io::ErrorKind::InvalidInput,
|
std::io::ErrorKind::InvalidInput,
|
||||||
format!("reth config file extension must be '{EXTENSION}'"),
|
format!("reth config file extension must be '{EXTENSION}'"),
|
||||||
))
|
));
|
||||||
}
|
}
|
||||||
confy::store_path(path, self).map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
|
|
||||||
|
std::fs::write(
|
||||||
|
path,
|
||||||
|
toml::to_string(self)
|
||||||
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the pruning configuration.
|
/// Sets the pruning configuration.
|
||||||
@ -384,7 +416,7 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::{Config, EXTENSION};
|
use super::{Config, EXTENSION};
|
||||||
use reth_network_peers::TrustedPeer;
|
use reth_network_peers::TrustedPeer;
|
||||||
use std::{str::FromStr, time::Duration};
|
use std::{path::Path, str::FromStr, time::Duration};
|
||||||
|
|
||||||
fn with_tempdir(filename: &str, proc: fn(&std::path::Path)) {
|
fn with_tempdir(filename: &str, proc: fn(&std::path::Path)) {
|
||||||
let temp_dir = tempfile::tempdir().unwrap();
|
let temp_dir = tempfile::tempdir().unwrap();
|
||||||
@ -395,11 +427,91 @@ mod tests {
|
|||||||
temp_dir.close().unwrap()
|
temp_dir.close().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Run a test function with a temporary config path as fixture.
|
||||||
|
fn with_config_path(test_fn: fn(&Path)) {
|
||||||
|
// Create a temporary directory for the config file
|
||||||
|
let config_dir = tempfile::tempdir().expect("creating test fixture failed");
|
||||||
|
// Create the config file path
|
||||||
|
let config_path =
|
||||||
|
config_dir.path().join("example-app").join("example-config").with_extension("toml");
|
||||||
|
// Run the test function with the config path
|
||||||
|
test_fn(&config_path);
|
||||||
|
config_dir.close().expect("removing test fixture failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_load_path_works() {
|
||||||
|
with_config_path(|path| {
|
||||||
|
let config = Config::from_path(path).expect("load_path failed");
|
||||||
|
assert_eq!(config, Config::default());
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_load_path_reads_existing_config() {
|
||||||
|
with_config_path(|path| {
|
||||||
|
let config = Config::default();
|
||||||
|
|
||||||
|
// Create the parent directory if it doesn't exist
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
std::fs::create_dir_all(parent).expect("Failed to create directories");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the config to the file
|
||||||
|
std::fs::write(path, toml::to_string(&config).unwrap())
|
||||||
|
.expect("Failed to write config");
|
||||||
|
|
||||||
|
// Load the config from the file and compare it
|
||||||
|
let loaded = Config::from_path(path).expect("load_path failed");
|
||||||
|
assert_eq!(config, loaded);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_load_path_fails_on_invalid_toml() {
|
||||||
|
with_config_path(|path| {
|
||||||
|
let invalid_toml = "invalid toml data";
|
||||||
|
|
||||||
|
// Create the parent directory if it doesn't exist
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
std::fs::create_dir_all(parent).expect("Failed to create directories");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write invalid TOML data to the file
|
||||||
|
std::fs::write(path, invalid_toml).expect("Failed to write invalid TOML");
|
||||||
|
|
||||||
|
// Attempt to load the config should fail
|
||||||
|
let result = Config::from_path(path);
|
||||||
|
assert!(result.is_err());
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_load_path_creates_directory_if_not_exists() {
|
||||||
|
with_config_path(|path| {
|
||||||
|
// Ensure the directory does not exist
|
||||||
|
let parent = path.parent().unwrap();
|
||||||
|
assert!(!parent.exists());
|
||||||
|
|
||||||
|
// Load the configuration, which should create the directory and a default config file
|
||||||
|
let config = Config::from_path(path).expect("load_path failed");
|
||||||
|
assert_eq!(config, Config::default());
|
||||||
|
|
||||||
|
// The directory and file should now exist
|
||||||
|
assert!(parent.exists());
|
||||||
|
assert!(path.exists());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_store_config() {
|
fn test_store_config() {
|
||||||
with_tempdir("config-store-test", |config_path| {
|
with_tempdir("config-store-test", |config_path| {
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
confy::store_path(config_path, config).expect("Failed to store config");
|
std::fs::write(
|
||||||
|
config_path,
|
||||||
|
toml::to_string(&config).expect("Failed to serialize config"),
|
||||||
|
)
|
||||||
|
.expect("Failed to write config file");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,9 +527,18 @@ mod tests {
|
|||||||
fn test_load_config() {
|
fn test_load_config() {
|
||||||
with_tempdir("config-load-test", |config_path| {
|
with_tempdir("config-load-test", |config_path| {
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
confy::store_path(config_path, &config).unwrap();
|
|
||||||
|
|
||||||
let loaded_config: Config = confy::load_path(config_path).unwrap();
|
// Write the config to a file
|
||||||
|
std::fs::write(
|
||||||
|
config_path,
|
||||||
|
toml::to_string(&config).expect("Failed to serialize config"),
|
||||||
|
)
|
||||||
|
.expect("Failed to write config file");
|
||||||
|
|
||||||
|
// Load the config from the file
|
||||||
|
let loaded_config = Config::from_path(config_path).unwrap();
|
||||||
|
|
||||||
|
// Compare the loaded config with the original config
|
||||||
assert_eq!(config, loaded_config);
|
assert_eq!(config, loaded_config);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -427,9 +548,18 @@ mod tests {
|
|||||||
with_tempdir("config-load-test", |config_path| {
|
with_tempdir("config-load-test", |config_path| {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.stages.execution.max_duration = Some(Duration::from_secs(10 * 60));
|
config.stages.execution.max_duration = Some(Duration::from_secs(10 * 60));
|
||||||
confy::store_path(config_path, &config).unwrap();
|
|
||||||
|
|
||||||
let loaded_config: Config = confy::load_path(config_path).unwrap();
|
// Write the config to a file
|
||||||
|
std::fs::write(
|
||||||
|
config_path,
|
||||||
|
toml::to_string(&config).expect("Failed to serialize config"),
|
||||||
|
)
|
||||||
|
.expect("Failed to write config file");
|
||||||
|
|
||||||
|
// Load the config from the file
|
||||||
|
let loaded_config = Config::from_path(config_path).unwrap();
|
||||||
|
|
||||||
|
// Compare the loaded config with the original config
|
||||||
assert_eq!(config, loaded_config);
|
assert_eq!(config, loaded_config);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,7 +76,6 @@ secp256k1 = { workspace = true, features = [
|
|||||||
aquamarine.workspace = true
|
aquamarine.workspace = true
|
||||||
eyre.workspace = true
|
eyre.workspace = true
|
||||||
fdlimit.workspace = true
|
fdlimit.workspace = true
|
||||||
confy.workspace = true
|
|
||||||
rayon.workspace = true
|
rayon.workspace = true
|
||||||
|
|
||||||
# tracing
|
# tracing
|
||||||
|
|||||||
@ -117,7 +117,7 @@ impl LaunchContext {
|
|||||||
pub fn load_toml_config(&self, config: &NodeConfig) -> eyre::Result<reth_config::Config> {
|
pub fn load_toml_config(&self, config: &NodeConfig) -> eyre::Result<reth_config::Config> {
|
||||||
let config_path = config.config.clone().unwrap_or_else(|| self.data_dir.config());
|
let config_path = config.config.clone().unwrap_or_else(|| self.data_dir.config());
|
||||||
|
|
||||||
let mut toml_config = confy::load_path::<reth_config::Config>(&config_path)
|
let mut toml_config = reth_config::Config::from_path(&config_path)
|
||||||
.wrap_err_with(|| format!("Could not load config file {config_path:?}"))?;
|
.wrap_err_with(|| format!("Could not load config file {config_path:?}"))?;
|
||||||
|
|
||||||
Self::save_pruning_config_if_full_node(&mut toml_config, config, &config_path)?;
|
Self::save_pruning_config_if_full_node(&mut toml_config, config, &config_path)?;
|
||||||
@ -970,12 +970,8 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
let loaded_config = Config::from_path(config_path).unwrap();
|
||||||
reth_config.prune.as_ref().map(|p| p.block_interval),
|
|
||||||
node_config.prune_config().map(|p| p.block_interval)
|
|
||||||
);
|
|
||||||
|
|
||||||
let loaded_config: Config = confy::load_path(config_path).unwrap();
|
|
||||||
assert_eq!(reth_config, loaded_config);
|
assert_eq!(reth_config, loaded_config);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,8 @@ humantime.workspace = true
|
|||||||
const_format.workspace = true
|
const_format.workspace = true
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
derive_more.workspace = true
|
derive_more.workspace = true
|
||||||
|
toml.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
|
||||||
# io
|
# io
|
||||||
dirs-next = "2.0.0"
|
dirs-next = "2.0.0"
|
||||||
@ -77,6 +79,7 @@ futures.workspace = true
|
|||||||
# test vectors generation
|
# test vectors generation
|
||||||
proptest.workspace = true
|
proptest.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
tempfile.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
optimism = [
|
optimism = [
|
||||||
|
|||||||
@ -8,10 +8,13 @@ use crate::{
|
|||||||
dirs::{ChainPath, DataDirPath},
|
dirs::{ChainPath, DataDirPath},
|
||||||
utils::get_single_header,
|
utils::get_single_header,
|
||||||
};
|
};
|
||||||
|
use eyre::eyre;
|
||||||
use reth_chainspec::{ChainSpec, MAINNET};
|
use reth_chainspec::{ChainSpec, MAINNET};
|
||||||
use reth_config::config::PruneConfig;
|
use reth_config::config::PruneConfig;
|
||||||
use reth_db_api::database::Database;
|
use reth_db_api::database::Database;
|
||||||
use reth_network_p2p::headers::client::HeadersClient;
|
use reth_network_p2p::headers::client::HeadersClient;
|
||||||
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
revm_primitives::EnvKzgSettings, BlockHashOrNumber, BlockNumber, Head, SealedHeader, B256,
|
revm_primitives::EnvKzgSettings, BlockHashOrNumber, BlockNumber, Head, SealedHeader, B256,
|
||||||
@ -365,6 +368,33 @@ impl NodeConfig {
|
|||||||
pub fn datadir(&self) -> ChainPath<DataDirPath> {
|
pub fn datadir(&self) -> ChainPath<DataDirPath> {
|
||||||
self.datadir.clone().resolve_datadir(self.chain.chain)
|
self.datadir.clone().resolve_datadir(self.chain.chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load an application configuration from a specified path.
|
||||||
|
///
|
||||||
|
/// A new configuration file is created with default values if none
|
||||||
|
/// exists.
|
||||||
|
pub fn load_path<T: Serialize + DeserializeOwned + Default>(
|
||||||
|
path: impl AsRef<Path>,
|
||||||
|
) -> eyre::Result<T> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
match fs::read_to_string(path) {
|
||||||
|
Ok(cfg_string) => {
|
||||||
|
toml::from_str(&cfg_string).map_err(|e| eyre!("Failed to parse TOML: {e}"))
|
||||||
|
}
|
||||||
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
fs::create_dir_all(parent)
|
||||||
|
.map_err(|e| eyre!("Failed to create directory: {e}"))?;
|
||||||
|
}
|
||||||
|
let cfg = T::default();
|
||||||
|
let s = toml::to_string_pretty(&cfg)
|
||||||
|
.map_err(|e| eyre!("Failed to serialize to TOML: {e}"))?;
|
||||||
|
fs::write(path, s).map_err(|e| eyre!("Failed to write configuration file: {e}"))?;
|
||||||
|
Ok(cfg)
|
||||||
|
}
|
||||||
|
Err(e) => Err(eyre!("Failed to load configuration: {e}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for NodeConfig {
|
impl Default for NodeConfig {
|
||||||
|
|||||||
Reference in New Issue
Block a user