Skip to content

Commit b21ccff

Browse files
authored
Merge pull request #173 from vincenzopalazzo/claude/recursing-dirac
2 parents a8b67fc + caf35e1 commit b21ccff

4 files changed

Lines changed: 97 additions & 12 deletions

File tree

ldk-server-cli/src/config.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use serde::{Deserialize, Serialize};
1414
const DEFAULT_CONFIG_FILE: &str = "config.toml";
1515
const DEFAULT_CERT_FILE: &str = "tls.crt";
1616
const API_KEY_FILE: &str = "api_key";
17+
pub const DEFAULT_REST_SERVICE_ADDRESS: &str = "127.0.0.1:3536";
1718

1819
pub fn get_default_data_dir() -> Option<PathBuf> {
1920
#[cfg(target_os = "macos")]
@@ -66,6 +67,7 @@ pub struct TlsConfig {
6667

6768
#[derive(Debug, Deserialize)]
6869
pub struct NodeConfig {
70+
#[serde(default = "default_rest_service_address")]
6971
pub rest_service_address: String,
7072
network: String,
7173
}
@@ -99,3 +101,53 @@ pub fn load_config(path: &PathBuf) -> Result<Config, String> {
99101
toml::from_str(&contents)
100102
.map_err(|e| format!("Failed to parse config file '{}': {}", path.display(), e))
101103
}
104+
105+
pub fn resolve_base_url(cli_base_url: Option<String>, config: Option<&Config>) -> String {
106+
cli_base_url
107+
.or_else(|| config.map(|config| config.node.rest_service_address.clone()))
108+
.unwrap_or_else(default_rest_service_address)
109+
}
110+
111+
fn default_rest_service_address() -> String {
112+
DEFAULT_REST_SERVICE_ADDRESS.to_string()
113+
}
114+
115+
#[cfg(test)]
116+
mod tests {
117+
use super::{resolve_base_url, Config, DEFAULT_REST_SERVICE_ADDRESS};
118+
119+
#[test]
120+
fn config_defaults_rest_service_address() {
121+
let config: Config = toml::from_str(
122+
r#"
123+
[node]
124+
network = "regtest"
125+
"#,
126+
)
127+
.unwrap();
128+
129+
assert_eq!(config.node.rest_service_address, DEFAULT_REST_SERVICE_ADDRESS);
130+
}
131+
132+
#[test]
133+
fn resolve_base_url_uses_cli_arg_first() {
134+
let config: Config = toml::from_str(
135+
r#"
136+
[node]
137+
network = "regtest"
138+
rest_service_address = "127.0.0.1:3002"
139+
"#,
140+
)
141+
.unwrap();
142+
143+
assert_eq!(
144+
resolve_base_url(Some("127.0.0.1:4000".to_string()), Some(&config)),
145+
"127.0.0.1:4000"
146+
);
147+
}
148+
149+
#[test]
150+
fn resolve_base_url_falls_back_to_default() {
151+
assert_eq!(resolve_base_url(None, None), DEFAULT_REST_SERVICE_ADDRESS);
152+
}
153+
}

ldk-server-cli/src/main.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use clap::{CommandFactory, Parser, Subcommand};
1313
use clap_complete::{generate, Shell};
1414
use config::{
1515
api_key_path_for_storage_dir, cert_path_for_storage_dir, get_default_api_key_path,
16-
get_default_cert_path, get_default_config_path, load_config,
16+
get_default_cert_path, get_default_config_path, load_config, resolve_base_url,
17+
DEFAULT_REST_SERVICE_ADDRESS,
1718
};
1819
use hex_conservative::DisplayHex;
1920
use ldk_server_client::client::LdkServerClient;
@@ -79,7 +80,13 @@ const DEFAULT_DIR: &str = if cfg!(target_os = "macos") {
7980
override_usage = "ldk-server-cli [OPTIONS] <COMMAND>"
8081
)]
8182
struct Cli {
82-
#[arg(short, long, help = "Base URL of the server. If not provided, reads from config file")]
83+
#[arg(
84+
short,
85+
long,
86+
help = format!(
87+
"Base URL of the server. Defaults to config file or {DEFAULT_REST_SERVICE_ADDRESS}"
88+
)
89+
)]
8390
base_url: Option<String>,
8491

8592
#[arg(short, long, help = format!("API key for authentication. Defaults by reading {DEFAULT_DIR}/[network]/api_key"))]
@@ -570,12 +577,7 @@ async fn main() {
570577
});
571578

572579
// Get base URL from argument then from config file
573-
let base_url =
574-
cli.base_url.or_else(|| config.as_ref().map(|c| c.node.rest_service_address.clone()))
575-
.unwrap_or_else(|| {
576-
eprintln!("Base URL not provided. Use --base-url or ensure config file exists at {DEFAULT_DIR}/config.toml");
577-
std::process::exit(1);
578-
});
580+
let base_url = resolve_base_url(cli.base_url, config.as_ref());
579581

580582
// Get TLS cert path from argument, then from config tls.cert_path, then from storage dir,
581583
// then try default location.

ldk-server/ldk-server-config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
network = "regtest" # Bitcoin network to use
44
listening_addresses = ["localhost:3001"] # Lightning node listening addresses
55
announcement_addresses = ["54.3.7.81:3001"] # Lightning node announcement addresses
6-
rest_service_address = "127.0.0.1:3002" # LDK Server REST address
6+
#rest_service_address = "127.0.0.1:3536" # LDK Server REST address (optional, defaults to 127.0.0.1:3536)
77
alias = "ldk_server" # Lightning node alias
88
#pathfinding_scores_source_url = "" # External Pathfinding Scores Source
99
#rgs_server_url = "https://rapidsync.lightningdevkit.org/snapshot/v2/" # Optional: RGS URL for rapid gossip sync

ldk-server/src/util/config.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use ldk_node::liquidity::LSPS2ServiceConfig;
2121
use log::LevelFilter;
2222
use serde::{Deserialize, Serialize};
2323

24+
const DEFAULT_REST_SERVICE_ADDRESS: &str = "127.0.0.1:3536";
25+
2426
#[cfg(not(test))]
2527
const DEFAULT_CONFIG_FILE: &str = "config.toml";
2628

@@ -211,7 +213,7 @@ impl ConfigBuilder {
211213

212214
let rest_service_addr = self
213215
.rest_service_address
214-
.ok_or_else(|| missing_field_err("rest_service_address"))?
216+
.unwrap_or_else(|| DEFAULT_REST_SERVICE_ADDRESS.to_string())
215217
.parse::<SocketAddr>()
216218
.map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
217219

@@ -1109,7 +1111,6 @@ mod tests {
11091111
validate_missing!("rpc_password", missing_field_msg("bitcoind_rpc_password"));
11101112
validate_missing!("rpc_user", missing_field_msg("bitcoind_rpc_user"));
11111113
validate_missing!("rpc_address", missing_field_msg("bitcoind_rpc_address"));
1112-
validate_missing!("rest_service_address =", missing_field_msg("rest_service_address"));
11131114
validate_missing!("network =", missing_field_msg("network"));
11141115
}
11151116

@@ -1196,7 +1197,6 @@ mod tests {
11961197
validate_missing!(bitcoind_rpc_user, missing_field_msg("bitcoind_rpc_user"));
11971198
validate_missing!(bitcoind_rpc_address, missing_field_msg("bitcoind_rpc_address"));
11981199
validate_missing!(node_network, missing_field_msg("network"));
1199-
validate_missing!(node_rest_service_address, missing_field_msg("rest_service_address"));
12001200
}
12011201

12021202
#[test]
@@ -1309,4 +1309,35 @@ mod tests {
13091309
let err = result.unwrap_err();
13101310
assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
13111311
}
1312+
1313+
#[test]
1314+
#[cfg(not(feature = "experimental-lsps2-support"))]
1315+
#[cfg(not(feature = "events-rabbitmq"))]
1316+
fn test_default_rest_service_address() {
1317+
let storage_path = std::env::temp_dir();
1318+
let config_file_name = "test_default_rest_service_address.toml";
1319+
1320+
// Config without rest_service_address
1321+
let toml_config = r#"
1322+
[node]
1323+
network = "regtest"
1324+
1325+
[bitcoind]
1326+
rpc_address = "127.0.0.1:8332"
1327+
rpc_user = "bitcoind-testuser"
1328+
rpc_password = "bitcoind-testpassword"
1329+
"#;
1330+
1331+
fs::write(storage_path.join(config_file_name), toml_config).unwrap();
1332+
1333+
let mut args_config = empty_args_config();
1334+
args_config.config_file =
1335+
Some(storage_path.join(config_file_name).to_string_lossy().to_string());
1336+
1337+
let config = load_config(&args_config).unwrap();
1338+
assert_eq!(
1339+
config.rest_service_addr,
1340+
SocketAddr::from_str(DEFAULT_REST_SERVICE_ADDRESS).unwrap()
1341+
);
1342+
}
13121343
}

0 commit comments

Comments
 (0)