From 9fa56862b9df0e8b4049c2b6b46522f9c42cbde2 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Fri, 1 Aug 2025 14:16:24 +0200 Subject: [PATCH] Ensure we always startup with a `rustls` `CryptoProvider` The `rustls` library recently introduced this weird behavior where they expect users to, apart from configuring the respective feature, also explictly call `CryptoProvider::install_default`. Otherwise they'd simply panic at runtime whenever the first network call requiring TLS would be made. While we already made a change upstream at `rust-electrum-client`, we also make sure here that we definitely, always, absolutley are sure that we have a `CryptoProvider` set on startup. --- Cargo.toml | 1 + src/builder.rs | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 730165b59..9ba6d3e64 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,7 @@ bdk_electrum = { version = "0.23.0", default-features = false, features = ["use- bdk_wallet = { version = "2.0.0", default-features = false, features = ["std", "keys-bip39"]} reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } +rustls = { version = "0.23", default-features = false } rusqlite = { version = "0.31.0", features = ["bundled"] } bitcoin = "0.32.4" bip39 = "2.0.0" diff --git a/src/builder.rs b/src/builder.rs index 31a0fee45..79982b4e3 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -74,7 +74,7 @@ use std::fmt; use std::fs; use std::path::PathBuf; use std::sync::atomic::AtomicBool; -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::{Arc, Mutex, Once, RwLock}; use std::time::SystemTime; use vss_client::headers::{FixedHeaders, LnurlAuthToJwtProvider, VssHeaderProvider}; @@ -936,6 +936,8 @@ fn build_with_store_internal( liquidity_source_config: Option<&LiquiditySourceConfig>, seed_bytes: [u8; 64], logger: Arc, kv_store: Arc, ) -> Result { + optionally_install_rustls_cryptoprovider(); + if let Err(err) = may_announce_channel(&config) { if config.announcement_addresses.is_some() { log_error!(logger, "Announcement addresses were set but some required configuration options for node announcement are missing: {}", err); @@ -1525,6 +1527,25 @@ fn build_with_store_internal( }) } +fn optionally_install_rustls_cryptoprovider() { + // Acquire a global Mutex, ensuring that only one process at a time install the provider. This + // is mostly required for running tests concurrently. + static INIT_CRYPTO: Once = Once::new(); + + INIT_CRYPTO.call_once(|| { + // Ensure we always install a `CryptoProvider` for `rustls` if it was somehow not previously installed by now. + if rustls::crypto::CryptoProvider::get_default().is_none() { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + } + + // Refuse to startup without TLS support. Better to catch it now than even later at runtime. + assert!( + rustls::crypto::CryptoProvider::get_default().is_some(), + "We need to have a CryptoProvider" + ); + }); +} + /// Sets up the node logger. fn setup_logger( log_writer_config: &Option, config: &Config,