diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0dcf350ac..63bf1cf60 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -41,14 +41,6 @@ jobs: toolchain: ${{ matrix.toolchain }} override: true profile: minimal - - name: Install OpenSSL (windows) - if: matrix.os == 'windows-latest' - run: | - choco install openssl.light --no-progress - echo "C:\Program Files\OpenSSL" >> $env:GITHUB_PATH - echo "C:\Program Files\OpenSSL\bin" >> $env::GITHUB_PATH - echo "OPENSSL_DIR=C:\Program Files\OpenSSL" >> $env:GITHUB_ENV - - name: Test on Rust ${{ matrix.toolchain }} (only Windows) if: matrix.os == 'windows-latest' run: cargo test --verbose --no-default-features diff --git a/Cargo.lock b/Cargo.lock index 4ac8abdc2..ecb52ad53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1143,7 +1143,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", "core-graphics-types 0.1.3", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -1156,7 +1156,7 @@ dependencies = [ "bitflags 2.6.0", "core-foundation 0.10.0", "core-graphics-types 0.2.0", - "foreign-types 0.5.0", + "foreign-types", "libc", ] @@ -1537,7 +1537,6 @@ dependencies = [ "byteorder", "libc", "log", - "openssl", "rustls", "serde", "serde_json", @@ -1825,15 +1824,6 @@ dependencies = [ "ttf-parser 0.19.2", ] -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared 0.1.1", -] - [[package]] name = "foreign-types" version = "0.5.0" @@ -1841,7 +1831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared 0.3.1", + "foreign-types-shared", ] [[package]] @@ -1855,12 +1845,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -3128,7 +3112,6 @@ dependencies = [ "backtrace", "bdk_electrum", "dirs 5.0.1", - "electrum-client", "fern", "jsonrpc 0.17.0", "liana", @@ -3389,7 +3372,7 @@ dependencies = [ "bitflags 2.6.0", "block", "core-graphics-types 0.1.3", - "foreign-types 0.5.0", + "foreign-types", "log", "objc", "paste", @@ -3815,44 +3798,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "foreign-types 0.3.2", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - -[[package]] -name = "openssl-sys" -version = "0.9.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" @@ -5173,7 +5118,7 @@ dependencies = [ "core-graphics 0.24.0", "drm", "fastrand", - "foreign-types 0.5.0", + "foreign-types", "js-sys", "log", "memmap2 0.9.5", diff --git a/contrib/lianad_config_example.toml b/contrib/lianad_config_example.toml index ba23b56e8..35b4b2560 100644 --- a/contrib/lianad_config_example.toml +++ b/contrib/lianad_config_example.toml @@ -50,13 +50,8 @@ poll_interval_secs = 30 # In order to connect, it needs the address as a string, which can be # optionally prefixed with "ssl://" or "tcp://". If omitted, "tcp://" # will be assumed. -# `validate_domain` field is optional: used in case of SSL connection, -# if set to `false`, internal electrum client will not try to validate -# the domain associated to the certificate: it's useful in case of -# self-signed certificate. Its default value is `true`. # [electrum_config] # addr = "127.0.0.1:50001" -# validate_domain = false # # [bitcoind_config] diff --git a/liana-gui/src/app/state/settings/bitcoind.rs b/liana-gui/src/app/state/settings/bitcoind.rs index 5b40de2dc..16d92953b 100644 --- a/liana-gui/src/app/state/settings/bitcoind.rs +++ b/liana-gui/src/app/state/settings/bitcoind.rs @@ -323,7 +323,6 @@ impl BitcoindSettings { } } } - view::SettingsEditMessage::ValidateDomainEdited(_) => {} view::SettingsEditMessage::BitcoindRpcAuthTypeSelected(auth_type) => { if !self.processing { self.selected_auth_type = auth_type; @@ -463,7 +462,6 @@ impl ElectrumSettings { daemon_config.bitcoin_backend = Some(lianad::config::BitcoinBackend::Electrum(ElectrumConfig { addr: self.addr.value.clone(), - validate_domain: self.electrum_config.validate_domain, })); self.processing = true; return Command::perform(async move { daemon_config }, |cfg| { @@ -472,11 +470,6 @@ impl ElectrumSettings { } } view::SettingsEditMessage::Clipboard(text) => return clipboard::write(text), - view::SettingsEditMessage::ValidateDomainEdited(b) => { - if !self.processing { - self.electrum_config.validate_domain = b; - } - } _ => {} }; Command::none() @@ -491,7 +484,6 @@ impl ElectrumSettings { cache.blockheight, &self.addr, self.processing, - self.electrum_config.validate_domain, ) } else { view::settings::electrum( diff --git a/liana-gui/src/app/view/message.rs b/liana-gui/src/app/view/message.rs index b75e2d409..345dd1dd0 100644 --- a/liana-gui/src/app/view/message.rs +++ b/liana-gui/src/app/view/message.rs @@ -89,7 +89,6 @@ pub enum RemoteBackendSettingsMessage { pub enum SettingsEditMessage { Select, FieldEdited(&'static str, String), - ValidateDomainEdited(bool), BitcoindRpcAuthTypeSelected(RpcAuthType), Cancel, Confirm, diff --git a/liana-gui/src/app/view/settings.rs b/liana-gui/src/app/view/settings.rs index fe4bef6e2..39be3cf6d 100644 --- a/liana-gui/src/app/view/settings.rs +++ b/liana-gui/src/app/view/settings.rs @@ -32,7 +32,7 @@ use crate::{ hw::HardwareWallet, node::{ bitcoind::{RpcAuthType, RpcAuthValues}, - electrum::{self, validate_domain_checkbox}, + electrum, }, }; @@ -563,7 +563,6 @@ pub fn electrum_edit<'a>( blockheight: i32, addr: &form::Value, processing: bool, - validate_domain: bool, ) -> Element<'a, SettingsEditMessage> { let mut col = Column::new().spacing(20); if is_configured_node_type && blockheight != 0 { @@ -596,9 +595,6 @@ pub fn electrum_edit<'a>( .push(separation().width(Length::Fill)); } - let checkbox = validate_domain_checkbox(addr, validate_domain, |b| { - SettingsEditMessage::ValidateDomainEdited(b) - }); col = col.push( Column::new() .push(text("Address:").bold().small()) @@ -610,7 +606,6 @@ pub fn electrum_edit<'a>( .size(P1_SIZE) .padding(5), ) - .push_maybe(checkbox) .push(text(electrum::ADDRESS_NOTES).size(P2_SIZE)) .spacing(5), ); diff --git a/liana-gui/src/installer/message.rs b/liana-gui/src/installer/message.rs index 3d093f933..96f5acd15 100644 --- a/liana-gui/src/installer/message.rs +++ b/liana-gui/src/installer/message.rs @@ -81,7 +81,6 @@ pub enum DefineBitcoind { #[derive(Debug, Clone)] pub enum DefineElectrum { ConfigFieldEdited(electrum::ConfigField, String), - ValidDomainChanged(bool), } #[derive(Debug, Clone)] diff --git a/liana-gui/src/installer/step/node/electrum.rs b/liana-gui/src/installer/step/node/electrum.rs index 5aeb8bf9d..f594e6a22 100644 --- a/liana-gui/src/installer/step/node/electrum.rs +++ b/liana-gui/src/installer/step/node/electrum.rs @@ -14,19 +14,9 @@ use crate::{ node::electrum::ConfigField, }; -#[derive(Clone)] +#[derive(Clone, Default)] pub struct DefineElectrum { address: form::Value, - validate_domain: bool, -} - -impl Default for DefineElectrum { - fn default() -> Self { - Self { - address: Default::default(), - validate_domain: true, - } - } } impl DefineElectrum { @@ -48,7 +38,6 @@ impl DefineElectrum { crate::node::electrum::is_electrum_address_valid(&value); } }, - message::DefineElectrum::ValidDomainChanged(v) => self.validate_domain = v, }; }; Command::none() @@ -58,7 +47,6 @@ impl DefineElectrum { if self.can_try_ping() { ctx.bitcoin_backend = Some(lianad::config::BitcoinBackend::Electrum(ElectrumConfig { addr: self.address.value.clone(), - validate_domain: self.validate_domain, })); return true; } @@ -66,15 +54,12 @@ impl DefineElectrum { } pub fn view(&self) -> Element { - view::define_electrum(&self.address, self.validate_domain) + view::define_electrum(&self.address) } pub fn ping(&self) -> Result<(), Error> { let builder = electrum_client::Config::builder(); - let config = builder - .timeout(Some(3)) - .validate_domain(self.validate_domain) - .build(); + let config = builder.timeout(Some(3)).build(); let client = electrum_client::Client::from_config(&self.address.value, config) .map_err(|e| Error::Electrum(e.to_string()))?; client diff --git a/liana-gui/src/installer/view/mod.rs b/liana-gui/src/installer/view/mod.rs index 00226ce5a..acd3b7d79 100644 --- a/liana-gui/src/installer/view/mod.rs +++ b/liana-gui/src/installer/view/mod.rs @@ -29,7 +29,6 @@ use liana_ui::{ widget::*, }; -use crate::node::electrum::validate_domain_checkbox; use crate::{ hw::{is_compatible_with_tapminiscript, HardwareWallet, UnsupportedReason}, installer::{ @@ -1135,15 +1134,7 @@ pub fn define_bitcoind<'a>( .into() } -pub fn define_electrum<'a>( - address: &form::Value, - validate_domain: bool, -) -> Element<'a, Message> { - let checkbox = validate_domain_checkbox(address, validate_domain, |b| { - Message::DefineNode(DefineNode::DefineElectrum( - message::DefineElectrum::ValidDomainChanged(b), - )) - }); +pub fn define_electrum<'a>(address: &form::Value) -> Element<'a, Message> { let col_address = Column::new() .push(text("Address:").bold()) .push( @@ -1159,8 +1150,7 @@ pub fn define_electrum<'a>( .size(text::P1_SIZE) .padding(10), ) - .push_maybe(checkbox) - .push(text(electrum::ADDRESS_NOTES)) + .push(text(electrum::ADDRESS_NOTES).size(text::P2_SIZE)) .spacing(10); Column::new().push(col_address).spacing(50).into() diff --git a/liana-gui/src/node/electrum.rs b/liana-gui/src/node/electrum.rs index db55ee9f1..89886f9ab 100644 --- a/liana-gui/src/node/electrum.rs +++ b/liana-gui/src/node/electrum.rs @@ -1,18 +1,13 @@ use std::fmt; -use iced::{widget::checkbox, Element, Renderer}; -use liana_ui::{component::form, theme::Theme}; - #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum ConfigField { Address, } pub const ADDRESS_NOTES: &str = "Note: include \"ssl://\" as a prefix \ - for SSL connections."; - -pub const VALID_SSL_DOMAIN_NOTES: &str = "Do not validate SSL Domain \ - (check this only if you want to use a self-signed certificate)"; + for SSL connections. Be aware that self-signed \ + SSL certificates are currently not supported."; impl fmt::Display for ConfigField { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -22,27 +17,6 @@ impl fmt::Display for ConfigField { } } -pub fn validate_domain_checkbox<'a, F, M>( - addr: &form::Value, - value: bool, - closure: F, -) -> Option> -where - F: 'a + Fn(bool) -> M, - M: 'a, -{ - let checkbox = checkbox(VALID_SSL_DOMAIN_NOTES, !value).on_toggle(move |b| closure(!b)); - if addr.valid && is_ssl(&addr.value) { - Some(checkbox.into()) - } else { - None - } -} - -pub fn is_ssl(value: &str) -> bool { - value.starts_with("ssl://") -} - pub fn is_electrum_address_valid(value: &str) -> bool { let value_noprefix = if value.starts_with("ssl://") { value.replacen("ssl://", "", 1) diff --git a/lianad/Cargo.toml b/lianad/Cargo.toml index 390eb4ed9..f051374d8 100644 --- a/lianad/Cargo.toml +++ b/lianad/Cargo.toml @@ -28,7 +28,6 @@ miniscript = { version = "11.0", features = ["serde", "compiler", "base64"] } # For Electrum backend. This is the latest version with the same bitcoin version as # the miniscript dependency. bdk_electrum = { version = "0.14" } -electrum-client = { version = "0.19", features = ["use-openssl"] } # Don't reinvent the wheel dirs = "5.0" diff --git a/lianad/src/bitcoin/electrum/client.rs b/lianad/src/bitcoin/electrum/client.rs index 0abf89d41..eec542f1f 100644 --- a/lianad/src/bitcoin/electrum/client.rs +++ b/lianad/src/bitcoin/electrum/client.rs @@ -7,11 +7,10 @@ use bdk_electrum::{ spk_client::{FullScanRequest, FullScanResult, SyncRequest, SyncResult}, BlockId, ChainPosition, ConfirmationHeightAnchor, TxGraph, }, + electrum_client::{self, Config, ElectrumApi}, ElectrumExt, }; -use electrum_client::{self, Config, ElectrumApi}; - use super::utils::{ block_id_from_tip, height_i32_from_usize, height_usize_from_i32, outpoints_from_tx, }; @@ -57,13 +56,9 @@ impl Client { /// Create a new client and perform sanity checks. pub fn new(electrum_config: &config::ElectrumConfig) -> Result { // First use a dummy config to check connectivity (no retries, short timeout). - let dummy_config = Config::builder() - .retry(0) - .validate_domain(electrum_config.validate_domain) - .timeout(Some(3)) - .build(); + let dummy_config = Config::builder().retry(0).timeout(Some(3)).build(); // Try to ping the server. - electrum_client::Client::from_config(&electrum_config.addr, dummy_config) + bdk_electrum::electrum_client::Client::from_config(&electrum_config.addr, dummy_config) .and_then(|dummy_client| dummy_client.ping()) .map_err(Error::Server)?; @@ -71,10 +66,10 @@ impl Client { let config = Config::builder() .retry(RETRY_LIMIT) .timeout(Some(RPC_SOCKET_TIMEOUT)) - .validate_domain(electrum_config.validate_domain) .build(); - let client = electrum_client::Client::from_config(&electrum_config.addr, config) - .map_err(Error::Server)?; + let client = + bdk_electrum::electrum_client::Client::from_config(&electrum_config.addr, config) + .map_err(Error::Server)?; Ok(Self(client)) } diff --git a/lianad/src/config.rs b/lianad/src/config.rs index 979d2e02d..bd8d19948 100644 --- a/lianad/src/config.rs +++ b/lianad/src/config.rs @@ -122,20 +122,12 @@ pub struct BitcoindConfig { } /// Everything we need to know for talking to Electrum serenely. -#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct ElectrumConfig { /// The URL the Electrum's RPC is listening on. /// Include "ssl://" for SSL. otherwise TCP will be assumed. /// Can optionally prefix with "tcp://". pub addr: String, - /// If validate_domain == false, domain of ssl certificate will not be validated - /// (useful to allow usage of self signed certificates on local network) - #[serde(default = "default_validate_domain")] - pub validate_domain: bool, -} - -fn default_validate_domain() -> bool { - true } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -294,7 +286,7 @@ impl Config { mod tests { use std::path::PathBuf; - use super::*; + use super::{config_file_path, BitcoindConfig, BitcoindRpcAuth, Config}; // Test the format of the configuration file #[test] @@ -487,41 +479,6 @@ mod tests { .contains("`auth` must be 'user:password'")); } - // Test the format of the `electrum_config` section - #[test] - fn toml_electrum_config() { - // A valid config with `validate_domain` - let toml_str = r#" - addr = 'ssl://electrum.blockstream.info:60002' - validate_domain = false - "# - .trim_start() - .replace(" ", ""); - toml::from_str::(&toml_str).expect("Deserializing toml_str"); - let parsed = toml::from_str::(&toml_str).expect("Deserializing toml_str"); - let serialized = toml::to_string_pretty(&parsed).expect("Serializing to toml"); - assert_eq!(toml_str, serialized); - let expected = ElectrumConfig { - addr: "ssl://electrum.blockstream.info:60002".into(), - validate_domain: false, - }; - assert_eq!(parsed, expected,); - - // A valid config w/o `validate_domain` - let toml_str = r#" - addr = 'ssl://electrum.blockstream.info:60002' - "# - .trim_start() - .replace(" ", ""); - let parsed = toml::from_str::(&toml_str).expect("Deserializing toml_str"); - let expected = ElectrumConfig { - addr: "ssl://electrum.blockstream.info:60002".into(), - // `validate_domain` must default to true - validate_domain: true, - }; - assert_eq!(parsed, expected,); - } - #[test] fn config_directory() { let filepath = config_file_path().expect("Getting config file path");