diem_config/config/
mod.rs1use serde::{de::DeserializeOwned, Deserialize, Serialize};
9use std::{
10 collections::HashMap,
11 fs::File,
12 io::{Read, Write},
13 path::{Path, PathBuf},
14};
15
16mod consensus_config;
17pub use consensus_config::*;
18mod error;
19pub use error::*;
20mod logger_config;
21pub use logger_config::*;
22mod mempool_config;
23pub use mempool_config::*;
24mod secure_backend_config;
25pub use secure_backend_config::*;
26mod storage_config;
27pub use storage_config::*;
28mod safety_rules_config;
29pub use safety_rules_config::*;
30
31#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
36#[serde(deny_unknown_fields)]
37pub struct NodeConfig {
38 #[serde(default)]
39 pub base: BaseConfig,
40 #[serde(default)]
41 pub consensus: ConsensusConfig,
42 #[serde(default)]
43 pub logger: LoggerConfig,
44 #[serde(default)]
45 pub mempool: MempoolConfig,
46 #[serde(default)]
47 pub storage: StorageConfig,
48 #[serde(default)]
49 pub failpoints: Option<HashMap<String, String>>,
50}
51
52#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
53#[serde(default, deny_unknown_fields)]
54pub struct BaseConfig {
55 data_dir: PathBuf,
56}
57
58impl Default for BaseConfig {
59 fn default() -> BaseConfig {
60 BaseConfig {
61 data_dir: PathBuf::from("./pos_db"),
62 }
63 }
64}
65
66impl NodeConfig {
67 pub fn data_dir(&self) -> &Path { &self.base.data_dir }
68
69 pub fn set_data_dir(&mut self, data_dir: PathBuf) {
70 self.base.data_dir = data_dir.clone();
71 self.consensus.set_data_dir(data_dir.clone());
72 self.storage.set_data_dir(data_dir);
73 }
74
75 pub fn load<P: AsRef<Path>>(input_path: P) -> Result<Self, Error> {
80 let config = Self::load_config(&input_path)?;
81 Ok(config)
82 }
83
84 pub fn save<P: AsRef<Path>>(
85 &mut self, output_path: P,
86 ) -> Result<(), Error> {
87 self.save_config(&output_path)?;
88 Ok(())
89 }
90}
91
92pub trait PersistableConfig: Serialize + DeserializeOwned {
93 fn load_config<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
94 let mut file = File::open(&path).map_err(|e| {
95 Error::IO(path.as_ref().to_str().unwrap().to_string(), e)
96 })?;
97 let mut contents = String::new();
98 file.read_to_string(&mut contents).map_err(|e| {
99 Error::IO(path.as_ref().to_str().unwrap().to_string(), e)
100 })?;
101 Self::parse(&contents)
102 }
103
104 fn save_config<P: AsRef<Path>>(&self, output_file: P) -> Result<(), Error> {
105 let contents = yaml_serde::to_string(&self)
106 .map_err(|e| {
107 Error::Yaml(
108 output_file.as_ref().to_str().unwrap().to_string(),
109 e,
110 )
111 })?
112 .into_bytes();
113 let mut file = File::create(output_file.as_ref()).map_err(|e| {
114 Error::IO(output_file.as_ref().to_str().unwrap().to_string(), e)
115 })?;
116 file.write_all(&contents).map_err(|e| {
117 Error::IO(output_file.as_ref().to_str().unwrap().to_string(), e)
118 })?;
119 Ok(())
120 }
121
122 fn parse(serialized: &str) -> Result<Self, Error> {
123 yaml_serde::from_str(&serialized)
124 .map_err(|e| Error::Yaml("config".to_string(), e))
125 }
126}
127
128impl<T: ?Sized> PersistableConfig for T where T: Serialize + DeserializeOwned {}
129
130#[derive(Debug)]
131pub struct RootPath {
132 root_path: PathBuf,
133}
134
135impl RootPath {
136 pub fn new<P: AsRef<Path>>(path: P) -> Self {
137 let root_path = if let Some(parent) = path.as_ref().parent() {
138 parent.to_path_buf()
139 } else {
140 PathBuf::from("")
141 };
142
143 Self { root_path }
144 }
145
146 pub fn new_path<P: AsRef<Path>>(path: P) -> Self {
148 let root_path = path.as_ref().to_path_buf();
149 Self { root_path }
150 }
151
152 pub fn full_path(&self, file_path: &Path) -> PathBuf {
154 if file_path.is_relative() {
155 self.root_path.join(file_path)
156 } else {
157 file_path.to_path_buf()
158 }
159 }
160}