Skip to content

Commit 874e098

Browse files
committed
Do not error on startup for optional values
Do not error on startup if storage path, listening addresses or announcement addresses fields were not specified in the config as these are optional values.
1 parent 98d209f commit 874e098

1 file changed

Lines changed: 97 additions & 80 deletions

File tree

ldk-server/src/util/config.rs

Lines changed: 97 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -185,36 +185,39 @@ impl ConfigBuilder {
185185
.parse::<SocketAddr>()
186186
.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
187187

188-
let storage_dir_path =
189-
self.storage_dir_path.ok_or_else(|| missing_field_err("storage_dir_path"))?;
190-
191-
let listening_addrs = self
188+
let listening_addrs: Option<Vec<SocketAddress>> = self
192189
.listening_addresses
193-
.ok_or_else(|| missing_field_err("node_listening_addresses"))?
194-
.into_iter()
195-
.map(|addr| {
196-
SocketAddress::from_str(&addr).map_err(|e| {
197-
io::Error::new(
198-
io::ErrorKind::InvalidInput,
199-
format!("Invalid listening addresses configured: {}", e),
200-
)
201-
})
190+
.map(|addrs| {
191+
addrs
192+
.into_iter()
193+
.map(|addr| {
194+
SocketAddress::from_str(&addr).map_err(|e| {
195+
io::Error::new(
196+
io::ErrorKind::InvalidInput,
197+
format!("Invalid listening addresses configured: {}", e),
198+
)
199+
})
200+
})
201+
.collect::<Result<Vec<_>, _>>()
202202
})
203-
.collect::<Result<Vec<_>, _>>()?;
203+
.transpose()?;
204204

205-
let announcement_addrs = self
205+
let announcement_addrs: Option<Vec<SocketAddress>> = self
206206
.announcement_addresses
207-
.ok_or_else(|| missing_field_err("node_announcement_addresses"))?
208-
.into_iter()
209-
.map(|addr| {
210-
SocketAddress::from_str(&addr).map_err(|e| {
211-
io::Error::new(
212-
io::ErrorKind::InvalidInput,
213-
format!("Invalid announcement addresses configured: {}", e),
214-
)
215-
})
207+
.map(|addrs| {
208+
addrs
209+
.into_iter()
210+
.map(|addr| {
211+
SocketAddress::from_str(&addr).map_err(|e| {
212+
io::Error::new(
213+
io::ErrorKind::InvalidInput,
214+
format!("Invalid announcement addresses configured: {}", e),
215+
)
216+
})
217+
})
218+
.collect::<Result<Vec<_>, _>>()
216219
})
217-
.collect::<Result<Vec<_>, _>>()?;
220+
.transpose()?;
218221

219222
let alias = self
220223
.alias
@@ -325,12 +328,12 @@ impl ConfigBuilder {
325328

326329
Ok(Config {
327330
network,
328-
listening_addrs: Some(listening_addrs),
329-
announcement_addrs: Some(announcement_addrs),
331+
listening_addrs,
332+
announcement_addrs,
330333
alias,
331334
tls_config: self.tls_config,
332335
rest_service_addr,
333-
storage_dir_path: Some(storage_dir_path),
336+
storage_dir_path: self.storage_dir_path,
334337
chain_source,
335338
rabbitmq_connection_string,
336339
rabbitmq_exchange_name,
@@ -650,6 +653,21 @@ mod tests {
650653
}
651654
}
652655

656+
fn empty_args_config() -> ArgsConfig {
657+
ArgsConfig {
658+
config_file: None,
659+
node_network: None,
660+
node_listening_addresses: None,
661+
node_announcement_addresses: None,
662+
node_rest_service_address: None,
663+
node_alias: None,
664+
bitcoind_rpc_address: None,
665+
bitcoind_rpc_user: None,
666+
bitcoind_rpc_password: None,
667+
storage_dir_path: None,
668+
}
669+
}
670+
653671
fn missing_field_msg(field: &str) -> String {
654672
format!(
655673
"Missing `{}`. Please provide it via config file, CLI argument, or environment variable.",
@@ -663,18 +681,10 @@ mod tests {
663681
let config_file_name = "test_config_from_file.toml";
664682

665683
fs::write(storage_path.join(config_file_name), DEFAULT_CONFIG).unwrap();
666-
let args_config = ArgsConfig {
667-
config_file: Some(storage_path.join(config_file_name).to_string_lossy().to_string()),
668-
node_network: None,
669-
node_listening_addresses: None,
670-
node_announcement_addresses: None,
671-
node_rest_service_address: None,
672-
bitcoind_rpc_address: None,
673-
bitcoind_rpc_user: None,
674-
bitcoind_rpc_password: None,
675-
storage_dir_path: None,
676-
node_alias: None,
677-
};
684+
685+
let mut args_config = empty_args_config();
686+
args_config.config_file =
687+
Some(storage_path.join(config_file_name).to_string_lossy().to_string());
678688

679689
let config = load_config(&args_config).unwrap();
680690

@@ -891,22 +901,55 @@ mod tests {
891901
assert_eq!(error.to_string(), "Must set a single chain source, multiple were configured");
892902
}
893903

904+
#[test]
905+
fn test_config_optional_values() {
906+
let storage_path = std::env::temp_dir();
907+
let config_file_name = "test_only_required_config.toml";
908+
909+
let mut args_config = empty_args_config();
910+
args_config.config_file =
911+
Some(storage_path.join(config_file_name).to_string_lossy().to_string());
912+
913+
// Test with optional values not specified in the config file
914+
#[cfg(not(any()))]
915+
let toml_config = r#"
916+
[node]
917+
network = "regtest"
918+
rest_service_address = "127.0.0.1:3002"
919+
920+
[bitcoind]
921+
rpc_address = "127.0.0.1:8332" # RPC endpoint
922+
rpc_user = "bitcoind-testuser"
923+
rpc_password = "bitcoind-testpassword"
924+
925+
[rabbitmq]
926+
connection_string = "rabbitmq_connection_string"
927+
exchange_name = "rabbitmq_exchange_name"
928+
929+
[liquidity.lsps2_service]
930+
advertise_service = false
931+
channel_opening_fee_ppm = 1000 # 0.1% fee
932+
channel_over_provisioning_ppm = 500000 # 50% extra capacity
933+
min_channel_opening_fee_msat = 10000000 # 10,000 satoshis
934+
min_channel_lifetime = 4320 # ~30 days
935+
max_client_to_self_delay = 1440 # ~10 days
936+
min_payment_size_msat = 10000000 # 10,000 satoshis
937+
max_payment_size_msat = 25000000000 # 0.25 BTC
938+
client_trusts_lsp = true
939+
"#;
940+
941+
fs::write(storage_path.join(config_file_name), toml_config).unwrap();
942+
assert!(load_config(&args_config).is_ok());
943+
}
944+
894945
#[test]
895946
fn test_config_missing_fields_in_file() {
896947
let storage_path = std::env::temp_dir();
897948
let config_file_name = "test_config_missing_fields_in_file.toml";
898-
let args_config = ArgsConfig {
899-
config_file: Some(storage_path.join(config_file_name).to_string_lossy().to_string()),
900-
node_network: None,
901-
node_listening_addresses: None,
902-
node_announcement_addresses: None,
903-
node_rest_service_address: None,
904-
bitcoind_rpc_address: None,
905-
bitcoind_rpc_user: None,
906-
bitcoind_rpc_password: None,
907-
storage_dir_path: None,
908-
node_alias: None,
909-
};
949+
950+
let mut args_config = empty_args_config();
951+
args_config.config_file =
952+
Some(storage_path.join(config_file_name).to_string_lossy().to_string());
910953

911954
macro_rules! validate_missing {
912955
($field:expr, $err_msg:expr) => {
@@ -940,9 +983,7 @@ mod tests {
940983
validate_missing!("rpc_password", missing_field_msg("bitcoind_rpc_password"));
941984
validate_missing!("rpc_user", missing_field_msg("bitcoind_rpc_user"));
942985
validate_missing!("rpc_address", missing_field_msg("bitcoind_rpc_address"));
943-
validate_missing!("dir_path =", missing_field_msg("storage_dir_path"));
944986
validate_missing!("rest_service_address =", missing_field_msg("rest_service_address"));
945-
validate_missing!("listening_addresses =", missing_field_msg("node_listening_addresses"));
946987
validate_missing!("network =", missing_field_msg("network"));
947988
}
948989

@@ -1025,8 +1066,6 @@ mod tests {
10251066
validate_missing!(bitcoind_rpc_address, missing_field_msg("bitcoind_rpc_address"));
10261067
validate_missing!(node_network, missing_field_msg("network"));
10271068
validate_missing!(node_rest_service_address, missing_field_msg("rest_service_address"));
1028-
validate_missing!(storage_dir_path, missing_field_msg("storage_dir_path"));
1029-
validate_missing!(node_listening_addresses, missing_field_msg("node_listening_addresses"));
10301069
}
10311070

10321071
#[test]
@@ -1109,18 +1148,7 @@ mod tests {
11091148
#[test]
11101149
#[cfg(feature = "events-rabbitmq")]
11111150
fn test_error_if_rabbitmq_feature_without_valid_config_file() {
1112-
let args_config = ArgsConfig {
1113-
config_file: None,
1114-
node_network: None,
1115-
node_listening_addresses: None,
1116-
node_announcement_addresses: None,
1117-
node_rest_service_address: None,
1118-
node_alias: None,
1119-
bitcoind_rpc_address: None,
1120-
bitcoind_rpc_user: None,
1121-
bitcoind_rpc_password: None,
1122-
storage_dir_path: None,
1123-
};
1151+
let args_config = empty_args_config();
11241152
let result = load_config(&args_config);
11251153
assert!(result.is_err());
11261154
let err = result.unwrap_err();
@@ -1130,18 +1158,7 @@ mod tests {
11301158
#[test]
11311159
#[cfg(feature = "experimental-lsps2-support")]
11321160
fn test_error_if_lsps2_feature_without_valid_config_file() {
1133-
let args_config = ArgsConfig {
1134-
config_file: None,
1135-
node_network: None,
1136-
node_listening_addresses: None,
1137-
node_announcement_addresses: None,
1138-
node_rest_service_address: None,
1139-
node_alias: None,
1140-
bitcoind_rpc_address: None,
1141-
bitcoind_rpc_user: None,
1142-
bitcoind_rpc_password: None,
1143-
storage_dir_path: None,
1144-
};
1161+
let args_config = empty_args_config();
11451162
let result = load_config(&args_config);
11461163
assert!(result.is_err());
11471164
let err = result.unwrap_err();

0 commit comments

Comments
 (0)