Skip to content

Commit

Permalink
feat: introduce topos-config crate (#443)
Browse files Browse the repository at this point in the history
Signed-off-by: Simon Paitrault <[email protected]>
  • Loading branch information
Freyskeyd committed Jan 31, 2024
1 parent fe062a5 commit 4ff2a23
Show file tree
Hide file tree
Showing 19 changed files with 265 additions and 158 deletions.
62 changes: 61 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 75 additions & 0 deletions crates/topos-config/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
[package]
name = "topos-config"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
topos-p2p = { path = "../topos-p2p" }
topos-tce-transport = { path = "../topos-tce-transport" }
topos-sequencer = { path = "../topos-sequencer" }
topos-core = { workspace = true, features = ["api"] }
topos-certificate-spammer = { path = "../topos-certificate-spammer" }
topos-tce-broadcast = { path = "../topos-tce-broadcast", optional = true }
topos-wallet = { path = "../topos-wallet" }

async-stream.workspace = true
async-trait.workspace = true
clap.workspace = true
hex.workspace = true
futures.workspace = true
opentelemetry.workspace = true
serde.workspace = true
serde_json.workspace = true
tokio = { workspace = true, features = ["full"] }
tokio-util.workspace = true
tonic.workspace = true
tower.workspace = true
tracing = { workspace = true, features = ["log"] }
tracing-opentelemetry.workspace = true
tracing-subscriber = { workspace = true, features = ["env-filter", "json", "ansi", "fmt"] }
uuid.workspace = true
rand.workspace = true
reqwest.workspace = true
thiserror.workspace = true
opentelemetry-otlp = { workspace = true, features = ["grpc-tonic", "metrics", "tls-roots"] }
figment = { version = "0.10", features = ["yaml", "toml", "env"] }
dirs = "5.0"
tracing-log = { version = "0.1.3", features = ["env_logger"] }
tar = "0.4.38"
flate2 ="1.0.26"
url = "2.3.1"
once_cell = "1.17.1"
toml = "0.7.4"
regex = "1"
rlp = "0.5.1"
openssl = { version = "0.10.61", features = ["vendored"] }

[dev-dependencies]
topos-tce-broadcast = { path = "../topos-tce-broadcast" }
topos-tce-transport = { path = "../topos-tce-transport" }
topos-tce-synchronizer = { path = "../topos-tce-synchronizer" }
topos-tce-gatekeeper = { path = "../topos-tce-gatekeeper" }
topos-tce-api = { path = "../topos-tce-api" }
topos-tce-storage = { path = "../topos-tce-storage" }
topos-test-sdk = { path = "../topos-test-sdk" }
serde.workspace = true
serde_json.workspace = true
test-log.workspace = true
env_logger.workspace = true
rand.workspace = true
futures.workspace = true
libp2p = { workspace = true, features = ["identify"] }
assert_cmd = "2.0.6"
insta = { version = "1.21", features = ["json", "redactions"] }
rstest = { workspace = true, features = ["async-timeout"] }
tempfile = "3.8.0"
predicates = "3.0.3"
sysinfo = "0.29.11"
serial_test = {version = "0.9.0"}



[lints]
workspace = true
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use figment::{
};
use serde::{Deserialize, Serialize};

use crate::config::node::NodeRole;
use crate::config::Config;
use crate::node::NodeRole;
use crate::Config;

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "kebab-case")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::config::Config;
use crate::Config;
use figment::{
providers::{Format, Toml},
Figment,
Expand Down
File renamed without changes.
File renamed without changes.
53 changes: 23 additions & 30 deletions crates/topos/src/config/mod.rs → crates/topos-config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
pub(crate) mod base;
pub(crate) mod edge;
pub(crate) mod node;
pub(crate) mod sequencer;
pub mod genesis;
pub mod node;
pub mod sequencer;
pub mod tce;

pub(crate) mod genesis;
use crate::components::node::commands::NodeCommands;

use std::path::Path;

use figment::providers::Serialized;
use figment::{error::Kind, Figment};
use serde::Serialize;

pub(crate) trait Config: Serialize {
pub trait Config: Serialize {
/// The configuration type returned (should be Self).
type Output;

Expand All @@ -32,36 +30,40 @@ pub(crate) trait Config: Serialize {

/// Convert the configuration to a TOML table.
fn to_toml(&self) -> Result<toml::Table, toml::ser::Error> {
toml::Table::try_from(self)
let mut config_toml = toml::Table::new();

let config = toml::Table::try_from(self)?;

// Flatten the top level
for (profile, content) in config {
config_toml.insert(profile, content);
}

Ok(config_toml)
}

/// Main function to load the configuration.
/// It will load the configuration from the file and the command line (if any)
/// It will load the configuration from the file and an optional existing struct (if any)
/// and then extract the configuration from the context in order to build the Config.
/// The Config is then returned or an error if the configuration is not valid.
fn load(home: &Path, command: Option<NodeCommands>) -> Result<Self::Output, figment::Error> {
fn load<S: Serialize>(home: &Path, config: Option<S>) -> Result<Self::Output, figment::Error> {
let mut figment = Figment::new();

figment = Self::load_from_file(figment, home);

if let Some(command) = command {
match command {
NodeCommands::Up(up) => {
figment = figment.merge(Serialized::from(up, Self::profile()))
}
NodeCommands::Init(init) => {
figment = figment.merge(Serialized::from(init, Self::profile()))
}
_ => (),
}
if let Some(config) = config {
figment = figment.merge(Serialized::from(config, Self::profile()))
}

Self::load_context(figment)
}
}

pub(crate) fn load_config<T: Config>(node_path: &Path, command: Option<NodeCommands>) -> T::Output {
match T::load(node_path, command) {
pub(crate) fn load_config<T: Config, S: Serialize>(
node_path: &Path,
config: Option<S>,
) -> T::Output {
match T::load(node_path, config) {
Ok(config) => config,
Err(figment::Error {
kind: Kind::MissingField(name),
Expand All @@ -76,12 +78,3 @@ pub(crate) fn load_config<T: Config>(node_path: &Path, command: Option<NodeComma
}
}
}

pub(crate) fn insert_into_toml<T: Config>(config_toml: &mut toml::Table, config: T) {
let full = config.to_toml().expect("failed to convert config to toml");

// Flatten the top level
for (profile, content) in full {
config_toml.insert(profile, content);
}
}
25 changes: 12 additions & 13 deletions crates/topos/src/config/node.rs → crates/topos-config/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ use figment::{
Figment,
};

use crate::components::node::commands::NodeCommands;
use serde::{Deserialize, Serialize};

use crate::config::{
use crate::{
base::BaseConfig, edge::EdgeConfig, load_config, sequencer::SequencerConfig, tce::TceConfig,
Config,
};
Expand All @@ -21,29 +20,29 @@ pub enum NodeRole {
FullNode,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub(crate) struct NodeConfig {
pub(crate) base: BaseConfig,
pub(crate) tce: Option<TceConfig>,
pub(crate) sequencer: Option<SequencerConfig>,
pub(crate) edge: Option<EdgeConfig>,
#[derive(Serialize, Deserialize, Debug)]
pub struct NodeConfig {
pub base: BaseConfig,
pub tce: Option<TceConfig>,
pub sequencer: Option<SequencerConfig>,
pub edge: Option<EdgeConfig>,
}

impl NodeConfig {
pub fn new(home: &Path, cmd: Option<NodeCommands>) -> Self {
let base = load_config::<BaseConfig>(home, cmd);
pub fn new<S: Serialize>(home: &Path, config: Option<S>) -> Self {
let base = load_config::<BaseConfig, _>(home, config);

let mut config = NodeConfig {
base: base.clone(),
sequencer: base
.need_sequencer()
.then(|| load_config::<SequencerConfig>(home, None)),
.then(|| load_config::<SequencerConfig, ()>(home, None)),
tce: base
.need_tce()
.then(|| load_config::<TceConfig>(home, None)),
.then(|| load_config::<TceConfig, ()>(home, None)),
edge: base
.need_edge()
.then(|| load_config::<EdgeConfig>(home, None)),
.then(|| load_config::<EdgeConfig, ()>(home, None)),
};

// Make the TCE DB path relative to the folder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::Path;

use crate::config::Config;
use crate::Config;
use figment::{
providers::{Format, Toml},
Figment,
Expand Down
Loading

0 comments on commit 4ff2a23

Please sign in to comment.