Skip to content

Commit 64b57ab

Browse files
frolvanyakobayurii
authored andcommitted
feat: added config checks (#310)
* feat: added checks for config variables * refactor: used `validator` crate for config validation * chore: simplified formatting * chore: reordered imports * feat: panic on error instead of logging * chore: provided better message error
1 parent d56bcaf commit 64b57ab

File tree

7 files changed

+73
-7
lines changed

7 files changed

+73
-7
lines changed

Cargo.lock

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ redis_url = "${REDIS_URL}"
1111
[general.rpc_server]
1212
server_port = "${SERVER_PORT}"
1313
max_gas_burnt = "${MAX_GAS_BURNT}"
14-
contract_code_cache_size = "${CONTRACT_CODE_CAHCE_SIZE}"
14+
contract_code_cache_size = "${CONTRACT_CODE_CACHE_SIZE}"
1515
block_cache_size = "${BLOCK_CACHE_SIZE}"
1616
shadow_data_consistency_rate = "${SHADOW_DATA_CONSISTENCY_RATE}"
1717
prefetch_state_size_limit = "${PREFETCH_STATE_SIZE_LIMIT}"

configuration/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ regex = "1.10.2"
1919
serde = "1.0.145"
2020
serde_derive = "1.0.145"
2121
serde_json = "1.0.108"
22+
validator = { version = "0.18.1", features = ["derive"] }
2223
opentelemetry = { version = "0.19", features = ["rt-tokio-current-thread"] }
2324
opentelemetry-jaeger = { version = "0.18", features = [
2425
"rt-tokio-current-thread",

configuration/src/configs/database.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
use crate::configs::deserialize_data_or_env;
21
use near_lake_framework::near_indexer_primitives::near_primitives;
2+
use validator::Validate;
3+
4+
use crate::configs::deserialize_data_or_env;
35

46
// Database connection URL
57
// Example: "postgres://user:password@localhost:5432/dbname"
68
type DatabaseConnectUrl = String;
79

8-
#[derive(serde_derive::Deserialize, Debug, Clone, Default)]
10+
#[derive(Validate, serde_derive::Deserialize, Debug, Clone, Default)]
911
pub struct ShardDatabaseConfig {
1012
#[serde(deserialize_with = "deserialize_data_or_env")]
1113
pub shard_id: u64,
14+
#[validate(url(message = "Invalid database shard URL"))]
1215
#[serde(deserialize_with = "deserialize_data_or_env")]
1316
pub database_url: DatabaseConnectUrl,
1417
}
@@ -33,10 +36,12 @@ impl DatabaseConfig {
3336
}
3437
}
3538

36-
#[derive(serde_derive::Deserialize, Debug, Clone, Default)]
39+
#[derive(Validate, serde_derive::Deserialize, Debug, Clone, Default)]
3740
pub struct CommonDatabaseConfig {
41+
#[validate(url(message = "Invalid database URL"))]
3842
#[serde(deserialize_with = "deserialize_data_or_env")]
3943
pub database_url: DatabaseConnectUrl,
44+
#[validate(nested)]
4045
#[serde(default)]
4146
pub shards: Vec<ShardDatabaseConfig>,
4247
}

configuration/src/configs/general.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::str::FromStr;
22

33
use serde_derive::Deserialize;
4+
use validator::Validate;
45

56
use crate::configs::{
67
deserialize_data_or_env, deserialize_optional_data_or_env, required_value_or_panic,
@@ -49,18 +50,23 @@ pub struct GeneralNearStateIndexerConfig {
4950
pub concurrency: usize,
5051
}
5152

52-
#[derive(Deserialize, Debug, Clone, Default)]
53+
#[derive(Validate, Deserialize, Debug, Clone, Default)]
5354
pub struct CommonGeneralConfig {
5455
#[serde(deserialize_with = "deserialize_data_or_env")]
5556
pub chain_id: ChainId,
57+
#[validate(url(message = "Invalid NEAR RPC URL"))]
5658
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
5759
pub near_rpc_url: Option<String>,
60+
#[validate(url(message = "Invalid NEAR Archival RPC URL"))]
5861
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
5962
pub near_archival_rpc_url: Option<String>,
63+
#[validate(url(message = "Invalid referer header value"))]
6064
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
6165
pub referer_header_value: Option<String>,
66+
#[validate(url(message = "Invalid Redis URL"))]
6267
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
6368
pub redis_url: Option<String>,
69+
#[validate(nested)]
6470
#[serde(default)]
6571
pub rpc_server: CommonGeneralRpcServerConfig,
6672
#[serde(default)]
@@ -95,16 +101,29 @@ impl FromStr for ChainId {
95101
}
96102
}
97103

98-
#[derive(Deserialize, Debug, Clone)]
104+
#[derive(Validate, Deserialize, Debug, Clone)]
99105
pub struct CommonGeneralRpcServerConfig {
100106
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
101107
pub server_port: Option<u16>,
102108
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
103109
pub max_gas_burnt: Option<u64>,
110+
#[validate(range(
111+
min = 0.0,
112+
message = "Contract code cache size must be greater than or equal to 0"
113+
))]
104114
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
105115
pub contract_code_cache_size: Option<f64>,
116+
#[validate(range(
117+
min = 0.0,
118+
message = "Block cache size must be greater than or equal to 0"
119+
))]
106120
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
107121
pub block_cache_size: Option<f64>,
122+
#[validate(range(
123+
min = 0.0,
124+
max = 100.0,
125+
message = "Shadow data consistency rate must be between 0 and 100"
126+
))]
108127
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]
109128
pub shadow_data_consistency_rate: Option<f64>,
110129
#[serde(deserialize_with = "deserialize_optional_data_or_env", default)]

configuration/src/configs/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use near_lake_framework::{
44
near_indexer_primitives, near_indexer_primitives::views::StateChangeValueView,
55
};
66
use serde::Deserialize;
7+
use validator::Validate;
78

89
pub(crate) mod database;
910
pub(crate) mod general;
@@ -74,12 +75,14 @@ where
7475
})
7576
}
7677

77-
#[derive(Deserialize, Debug, Clone, Default)]
78+
#[derive(Validate, Deserialize, Debug, Clone, Default)]
7879
pub struct CommonConfig {
80+
#[validate(nested)]
7981
pub general: general::CommonGeneralConfig,
8082
#[serde(default)]
8183
pub rightsizing: rightsizing::CommonRightsizingConfig,
8284
pub lake_config: lake::CommonLakeConfig,
85+
#[validate(nested)]
8386
pub database: database::CommonDatabaseConfig,
8487
// Set as default to avoid breaking changes
8588
// This options needs only for tx_indexer and rpc_server

configuration/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use std::path::PathBuf;
22
use tracing_subscriber::layer::SubscriberExt;
33
use tracing_subscriber::util::SubscriberInitExt;
44

5+
use validator::Validate;
6+
57
mod configs;
68

79
pub use crate::configs::database::DatabaseConfig;
@@ -18,6 +20,11 @@ where
1820
let path_root = find_configs_root().await?;
1921
load_env(path_root.clone()).await?;
2022
let common_config = read_toml_file(path_root).await?;
23+
24+
if let Err(validation_errors) = common_config.validate() {
25+
panic!("Failed to validate config: {validation_errors}");
26+
}
27+
2128
Ok(T::from_common_config(common_config))
2229
}
2330

0 commit comments

Comments
 (0)