1#![doc = include_str!("../README.md")]
2
3use near_chain_configs::UpdatableClientConfig;
4use near_o11y::log_config::LogConfig;
5use near_primitives::validator_signer::ValidatorSigner;
6use near_time::Clock;
7use std::path::PathBuf;
8use std::sync::Arc;
9use tokio::sync::broadcast::Sender;
10
11mod metrics;
12
13#[derive(Clone, Default)]
14pub enum UpdatableValidatorSigner {
15 #[default]
17 KeyExistenceNotDetermined,
18 MaybeKey(Option<Arc<ValidatorSigner>>),
20}
21
22#[derive(Clone, Default)]
23pub struct UpdatableConfigs {
25 pub log_config: Option<LogConfig>,
27 pub client_config: Option<UpdatableClientConfig>,
29 pub validator_signer: UpdatableValidatorSigner,
31}
32
33#[derive(Default)]
35pub struct UpdatableConfigLoader {
36 tx: Option<Sender<Result<UpdatableConfigs, Arc<UpdatableConfigLoaderError>>>>,
38}
39
40#[derive(thiserror::Error, Debug)]
41#[non_exhaustive]
42pub enum UpdatableConfigLoaderError {
43 #[error("Failed to parse a dynamic config file {file:?}: {err:?}")]
44 Parse { file: PathBuf, err: serde_json::Error },
45 #[error("Can't open or read a dynamic config file {file:?}: {err:?}")]
46 OpenAndRead { file: PathBuf, err: std::io::Error },
47 #[error("Can't open or read the config file {file:?}: {err:?}")]
48 ConfigFileError { file: PathBuf, err: anyhow::Error },
49 #[error("Can't open or read the validator key file {file:?}: {err:?}")]
50 ValidatorKeyFileError { file: PathBuf, err: anyhow::Error },
51 #[error("One or multiple dynamic config files reload errors {0:?}")]
52 Errors(Vec<UpdatableConfigLoaderError>),
53 #[error("No home dir set")]
54 NoHomeDir(),
55}
56
57impl UpdatableConfigLoader {
58 pub fn new(
59 updatable_configs: UpdatableConfigs,
60 tx: Sender<Result<UpdatableConfigs, Arc<UpdatableConfigLoaderError>>>,
61 ) -> Self {
62 let mut result = Self { tx: Some(tx) };
63 result.reload(Ok(updatable_configs));
64 result
65 }
66
67 pub fn reload(
68 &mut self,
69 updatable_configs: Result<UpdatableConfigs, UpdatableConfigLoaderError>,
70 ) {
71 match updatable_configs {
72 Ok(updatable_configs) => {
73 near_o11y::reload_log_config(updatable_configs.log_config.as_ref());
74 self.tx.as_ref().map(|tx| tx.send(Ok(updatable_configs.clone())));
75 Self::update_metrics();
76 }
77 Err(err) => {
78 self.tx.as_ref().map(|tx| tx.send(Err(Arc::new(err))));
79 }
80 }
81 }
82
83 fn update_metrics() {
84 metrics::CONFIG_RELOAD_TIMESTAMP.set(Clock::real().now_utc().unix_timestamp());
85 metrics::CONFIG_RELOADS.inc();
86 }
87}