-
Notifications
You must be signed in to change notification settings - Fork 36
Configurable HumanReadableName resolver
#195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ use std::{fs, io}; | |
| use clap::Parser; | ||
| use ldk_node::bitcoin::secp256k1::PublicKey; | ||
| use ldk_node::bitcoin::Network; | ||
| use ldk_node::config::{HRNResolverConfig, HumanReadableNamesConfig}; | ||
| use ldk_node::lightning::ln::msgs::SocketAddress; | ||
| use ldk_node::lightning::routing::gossip::NodeAlias; | ||
| use ldk_node::liquidity::LSPS2ServiceConfig; | ||
|
|
@@ -61,6 +62,7 @@ pub struct Config { | |
| pub metrics_username: Option<String>, | ||
| pub metrics_password: Option<String>, | ||
| pub tor_config: Option<TorConfig>, | ||
| pub hrn_config: HumanReadableNamesConfig, | ||
| } | ||
|
|
||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
|
|
@@ -114,6 +116,7 @@ struct ConfigBuilder { | |
| metrics_username: Option<String>, | ||
| metrics_password: Option<String>, | ||
| tor_proxy_address: Option<String>, | ||
| hrn: Option<HrnTomlConfig>, | ||
| } | ||
|
|
||
| impl ConfigBuilder { | ||
|
|
@@ -180,6 +183,10 @@ impl ConfigBuilder { | |
| if let Some(tor) = toml.tor { | ||
| self.tor_proxy_address = Some(tor.proxy_address) | ||
| } | ||
|
|
||
| if let Some(hrn) = toml.hrn { | ||
| self.hrn = Some(hrn); | ||
| } | ||
| } | ||
|
|
||
| fn merge_args(&mut self, args: &ArgsConfig) { | ||
|
|
@@ -402,6 +409,11 @@ impl ConfigBuilder { | |
| }) | ||
| .transpose()?; | ||
|
|
||
| let hrn_config = match self.hrn { | ||
| Some(hrn) => HumanReadableNamesConfig::try_from(hrn)?, | ||
| None => HumanReadableNamesConfig::default(), | ||
| }; | ||
|
|
||
| Ok(Config { | ||
| network, | ||
| listening_addrs, | ||
|
|
@@ -422,6 +434,7 @@ impl ConfigBuilder { | |
| metrics_username, | ||
| metrics_password, | ||
| tor_config: tor_proxy_address.map(|proxy_address| TorConfig { proxy_address }), | ||
| hrn_config, | ||
| }) | ||
| } | ||
| } | ||
|
|
@@ -439,6 +452,7 @@ pub struct TomlConfig { | |
| tls: Option<TomlTlsConfig>, | ||
| metrics: Option<MetricsTomlConfig>, | ||
| tor: Option<TomlTorConfig>, | ||
| hrn: Option<HrnTomlConfig>, | ||
| } | ||
|
|
||
| #[derive(Deserialize, Serialize)] | ||
|
|
@@ -505,6 +519,52 @@ struct TomlTorConfig { | |
| proxy_address: String, | ||
| } | ||
|
|
||
| #[derive(Deserialize, Serialize)] | ||
| struct HrnTomlConfig { | ||
| mode: Option<String>, | ||
| dns_server_address: Option<String>, | ||
| enable_resolution_service: Option<bool>, | ||
| } | ||
|
|
||
| impl TryFrom<HrnTomlConfig> for HumanReadableNamesConfig { | ||
| type Error = io::Error; | ||
|
|
||
| fn try_from(value: HrnTomlConfig) -> Result<Self, Self::Error> { | ||
| let mut config = HumanReadableNamesConfig::default(); | ||
|
|
||
| match value.mode.as_deref() { | ||
| None | Some("dns") => {}, | ||
| Some("blip32") => { | ||
| config.resolution_config = HRNResolverConfig::Blip32; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be good to throw an error if |
||
| }, | ||
| Some(other) => { | ||
| return Err(io::Error::new( | ||
| io::ErrorKind::InvalidInput, | ||
| format!("Invalid HRN mode '{}' configured; expected 'dns' or 'blip32'", other), | ||
| )) | ||
| }, | ||
| } | ||
|
|
||
| if let HRNResolverConfig::Dns { dns_server_address, enable_hrn_resolution_service } = | ||
| &mut config.resolution_config | ||
| { | ||
| if let Some(addr) = value.dns_server_address.as_deref() { | ||
| *dns_server_address = SocketAddress::from_str(addr).map_err(|e| { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we do something here to assume port 53 if its not provided? |
||
| io::Error::new( | ||
| io::ErrorKind::InvalidInput, | ||
| format!("Invalid HRN DNS server address configured: {}", e), | ||
| ) | ||
| })?; | ||
| } | ||
| if let Some(enable) = value.enable_resolution_service { | ||
| *enable_hrn_resolution_service = enable; | ||
| } | ||
| } | ||
|
|
||
| Ok(config) | ||
| } | ||
| } | ||
|
|
||
| #[derive(Deserialize, Serialize)] | ||
| struct LiquidityConfig { | ||
| lsps2_client: Option<LSPSClientTomlConfig>, | ||
|
|
@@ -936,6 +996,7 @@ mod tests { | |
| tor_config: Some(TorConfig { | ||
| proxy_address: SocketAddress::from_str("127.0.0.1:9050").unwrap(), | ||
| }), | ||
| hrn_config: HumanReadableNamesConfig::default(), | ||
| }; | ||
|
|
||
| assert_eq!(config.listening_addrs, expected.listening_addrs); | ||
|
|
@@ -1241,6 +1302,7 @@ mod tests { | |
| metrics_username: None, | ||
| metrics_password: None, | ||
| tor_config: None, | ||
| hrn_config: HumanReadableNamesConfig::default(), | ||
| }; | ||
|
|
||
| assert_eq!(config.listening_addrs, expected.listening_addrs); | ||
|
|
@@ -1350,6 +1412,7 @@ mod tests { | |
| tor_config: Some(TorConfig { | ||
| proxy_address: SocketAddress::from_str("127.0.0.1:9050").unwrap(), | ||
| }), | ||
| hrn_config: HumanReadableNamesConfig::default(), | ||
| }; | ||
|
|
||
| assert_eq!(config.listening_addrs, expected.listening_addrs); | ||
|
|
@@ -1501,4 +1564,81 @@ mod tests { | |
| let err = result.unwrap_err(); | ||
| assert_eq!(err.kind(), io::ErrorKind::InvalidInput); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_hrn_config() { | ||
| let storage_path = std::env::temp_dir(); | ||
| let config_file_name = "test_hrn_config.toml"; | ||
|
|
||
| let base_config = r#" | ||
| [node] | ||
| network = "regtest" | ||
|
|
||
| [bitcoind] | ||
| rpc_address = "127.0.0.1:8332" | ||
| rpc_user = "bitcoind-testuser" | ||
| rpc_password = "bitcoind-testpassword" | ||
|
|
||
| [liquidity.lsps2_service] | ||
| advertise_service = false | ||
| channel_opening_fee_ppm = 1000 | ||
| channel_over_provisioning_ppm = 500000 | ||
| min_channel_opening_fee_msat = 10000000 | ||
| min_channel_lifetime = 4320 | ||
| max_client_to_self_delay = 1440 | ||
| min_payment_size_msat = 10000000 | ||
| max_payment_size_msat = 25000000000 | ||
| client_trusts_lsp = true | ||
| disable_client_reserve = false | ||
| "#; | ||
|
|
||
| let mut args_config = empty_args_config(); | ||
| args_config.config_file = | ||
| Some(storage_path.join(config_file_name).to_string_lossy().to_string()); | ||
|
|
||
| // Default: no `[hrn]` section -> DNS against 8.8.8.8:53, resolution service disabled. | ||
| fs::write(storage_path.join(config_file_name), base_config).unwrap(); | ||
| let config = load_config(&args_config).unwrap(); | ||
| match config.hrn_config.resolution_config { | ||
| HRNResolverConfig::Dns { dns_server_address, enable_hrn_resolution_service } => { | ||
| assert_eq!(dns_server_address, SocketAddress::from_str("8.8.8.8:53").unwrap()); | ||
| assert!(!enable_hrn_resolution_service); | ||
| }, | ||
| other => panic!("unexpected default HRN resolver config: {:?}", other), | ||
| } | ||
|
|
||
| // Custom DNS server address with resolution service enabled. | ||
| let toml_config = format!( | ||
| "{}\n[hrn]\ndns_server_address = \"1.1.1.1:53\"\nenable_resolution_service = true\n", | ||
| base_config | ||
| ); | ||
| fs::write(storage_path.join(config_file_name), &toml_config).unwrap(); | ||
| let config = load_config(&args_config).unwrap(); | ||
| match config.hrn_config.resolution_config { | ||
| HRNResolverConfig::Dns { dns_server_address, enable_hrn_resolution_service } => { | ||
| assert_eq!(dns_server_address, SocketAddress::from_str("1.1.1.1:53").unwrap()); | ||
| assert!(enable_hrn_resolution_service); | ||
| }, | ||
| other => panic!("unexpected HRN resolver config: {:?}", other), | ||
| } | ||
|
|
||
| // Blip32 mode. | ||
| let toml_config = format!("{}\n[hrn]\nmode = \"blip32\"\n", base_config); | ||
| fs::write(storage_path.join(config_file_name), &toml_config).unwrap(); | ||
| let config = load_config(&args_config).unwrap(); | ||
| assert!(matches!(config.hrn_config.resolution_config, HRNResolverConfig::Blip32)); | ||
|
|
||
| // Invalid mode is rejected. | ||
| let toml_config = format!("{}\n[hrn]\nmode = \"bogus\"\n", base_config); | ||
| fs::write(storage_path.join(config_file_name), &toml_config).unwrap(); | ||
| let err = load_config(&args_config).unwrap_err(); | ||
| assert_eq!(err.kind(), io::ErrorKind::InvalidInput); | ||
|
|
||
| // Invalid DNS server address is rejected. | ||
| let toml_config = | ||
| format!("{}\n[hrn]\ndns_server_address = \"not-a-socket-address\"\n", base_config); | ||
| fs::write(storage_path.join(config_file_name), &toml_config).unwrap(); | ||
| let err = load_config(&args_config).unwrap_err(); | ||
| assert_eq!(err.kind(), io::ErrorKind::InvalidInput); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here we assume that the default is
HRNResolverConfig::Dnsand then modify the settings below. Would be safer to have the logic of theif let HRNResolverConfig::Dns ...in this arm so if the default ever changed (say to http to support lnurl) then we could better handle it and not silently drop thedns_server_addressandenable_resolution_servicesettings.