diff --git a/Cargo.toml b/Cargo.toml index 5ce10d6ad..4dfccb3e4 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,8 @@ codegen-units = 1 # Reduce number of codegen units to increase optimizations. panic = 'abort' # Abort on panic [features] -default = [] +default = ["electrum"] +electrum = ["dep:bdk_electrum", "dep:electrum-client", "lightning-transaction-sync/electrum"] [dependencies] lightning = { version = "0.1.0", features = ["std"] } @@ -36,7 +37,7 @@ lightning-persister = { version = "0.1.0" } lightning-background-processor = { version = "0.1.0", features = ["futures"] } lightning-rapid-gossip-sync = { version = "0.1.0" } lightning-block-sync = { version = "0.1.0", features = ["rpc-client", "tokio"] } -lightning-transaction-sync = { version = "0.1.0", features = ["esplora-async-https", "time", "electrum"] } +lightning-transaction-sync = { version = "0.1.0", features = ["esplora-async-https", "time"] } lightning-liquidity = { version = "0.1.0", features = ["std"] } #lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "main", features = ["std"] } @@ -63,7 +64,7 @@ lightning-liquidity = { version = "0.1.0", features = ["std"] } bdk_chain = { version = "0.21.1", default-features = false, features = ["std"] } bdk_esplora = { version = "0.20.1", default-features = false, features = ["async-https-rustls", "tokio"]} -bdk_electrum = { version = "0.20.1", default-features = false, features = ["use-rustls"]} +bdk_electrum = { version = "0.20.1", default-features = false, features = ["use-rustls"], optional = true } bdk_wallet = { version = "1.0.0", default-features = false, features = ["std", "keys-bip39"]} reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls"] } @@ -77,7 +78,7 @@ rand = "0.8.5" chrono = { version = "0.4", default-features = false, features = ["clock"] } tokio = { version = "1.37", default-features = false, features = [ "rt-multi-thread", "time", "sync", "macros" ] } esplora-client = { version = "0.11", default-features = false, features = ["tokio", "async-https-rustls"] } -electrum-client = { version = "0.22.0", default-features = true } +electrum-client = { version = "0.22.0", default-features = true, optional = true } libc = "0.2" uniffi = { version = "0.27.3", features = ["build"], optional = true } serde = { version = "1.0.210", default-features = false, features = ["std", "derive"] } diff --git a/src/builder.rs b/src/builder.rs index 31a0fee45..b6a8fdd49 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -7,10 +7,13 @@ use crate::chain::{ChainSource, DEFAULT_ESPLORA_SERVER_URL}; use crate::config::{ - default_user_config, may_announce_channel, AnnounceError, Config, ElectrumSyncConfig, - EsploraSyncConfig, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN, + default_user_config, may_announce_channel, AnnounceError, Config, EsploraSyncConfig, + DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL, WALLET_KEYS_SEED_LEN, }; +#[cfg(feature = "electrum")] +use crate::config::ElectrumSyncConfig; + use crate::connection::ConnectionManager; use crate::event::EventQueue; use crate::fee_estimator::OnchainFeeEstimator; @@ -85,6 +88,7 @@ const LSPS_HARDENED_CHILD_INDEX: u32 = 577; #[derive(Debug, Clone)] enum ChainDataSourceConfig { Esplora { server_url: String, sync_config: Option }, + #[cfg(feature = "electrum")] Electrum { server_url: String, sync_config: Option }, BitcoindRpc { rpc_host: String, rpc_port: u16, rpc_user: String, rpc_password: String }, } @@ -291,6 +295,7 @@ impl NodeBuilder { /// /// If no `sync_config` is given, default values are used. See [`ElectrumSyncConfig`] for more /// information. + #[cfg(feature = "electrum")] pub fn set_chain_source_electrum( &mut self, server_url: String, sync_config: Option, ) -> &mut Self { @@ -710,6 +715,7 @@ impl ArcedNodeBuilder { /// /// If no `sync_config` is given, default values are used. See [`ElectrumSyncConfig`] for more /// information. + #[cfg(feature = "electrum")] pub fn set_chain_source_electrum( &self, server_url: String, sync_config: Option, ) { @@ -1054,6 +1060,7 @@ fn build_with_store_internal( Arc::clone(&node_metrics), )) }, + #[cfg(feature = "electrum")] Some(ChainDataSourceConfig::Electrum { server_url, sync_config }) => { let sync_config = sync_config.unwrap_or(ElectrumSyncConfig::default()); Arc::new(ChainSource::new_electrum( diff --git a/src/chain/electrum.rs b/src/chain/electrum.rs index 6e62d9c08..71739bb87 100644 --- a/src/chain/electrum.rs +++ b/src/chain/electrum.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "electrum")] // This file is Copyright its original authors, visible in version control history. // // This file is licensed under the Apache License, Version 2.0 ), Stopped { @@ -118,6 +125,7 @@ pub(crate) enum ElectrumRuntimeStatus { }, } +#[cfg(feature = "electrum")] impl ElectrumRuntimeStatus { pub(crate) fn new() -> Self { let pending_registered_txs = Vec::new(); @@ -201,6 +209,7 @@ pub(crate) enum ChainSource { logger: Arc, node_metrics: Arc>, }, + #[cfg(feature = "electrum")] Electrum { server_url: String, sync_config: ElectrumSyncConfig, @@ -260,6 +269,7 @@ impl ChainSource { } } + #[cfg(feature = "electrum")] pub(crate) fn new_electrum( server_url: String, sync_config: ElectrumSyncConfig, onchain_wallet: Arc, fee_estimator: Arc, tx_broadcaster: Arc, @@ -313,6 +323,7 @@ impl ChainSource { pub(crate) fn start(&self, runtime: Arc) -> Result<(), Error> { match self { + #[cfg(feature = "electrum")] Self::Electrum { server_url, electrum_runtime_status, config, logger, .. } => { electrum_runtime_status.write().unwrap().start( server_url.clone(), @@ -330,6 +341,7 @@ impl ChainSource { pub(crate) fn stop(&self) { match self { + #[cfg(feature = "electrum")] Self::Electrum { electrum_runtime_status, .. } => { electrum_runtime_status.write().unwrap().stop(); }, @@ -372,6 +384,7 @@ impl ChainSource { return; } }, + #[cfg(feature = "electrum")] Self::Electrum { sync_config, logger, .. } => { if let Some(background_sync_config) = sync_config.background_sync_config.as_ref() { self.start_tx_based_sync_loop( @@ -718,6 +731,7 @@ impl ChainSource { res }, + #[cfg(feature = "electrum")] Self::Electrum { electrum_runtime_status, onchain_wallet, @@ -909,6 +923,7 @@ impl ChainSource { res }, + #[cfg(feature = "electrum")] Self::Electrum { electrum_runtime_status, lightning_wallet_sync_status, @@ -998,6 +1013,7 @@ impl ChainSource { // `sync_onchain_wallet` and `sync_lightning_wallet`. So nothing to do here. unreachable!("Listeners will be synced via transction-based syncing") }, + #[cfg(feature = "electrum")] Self::Electrum { .. } => { // In Electrum mode we sync lightning and onchain wallets via // `sync_onchain_wallet` and `sync_lightning_wallet`. So nothing to do here. @@ -1223,6 +1239,7 @@ impl ChainSource { Ok(()) }, + #[cfg(feature = "electrum")] Self::Electrum { electrum_runtime_status, fee_estimator, @@ -1478,6 +1495,7 @@ impl ChainSource { } } }, + #[cfg(feature = "electrum")] Self::Electrum { electrum_runtime_status, tx_broadcaster, .. } => { let electrum_client: Arc = if let Some(client) = electrum_runtime_status.read().unwrap().client().as_ref() @@ -1560,6 +1578,7 @@ impl Filter for ChainSource { fn register_tx(&self, txid: &Txid, script_pubkey: &Script) { match self { Self::Esplora { tx_sync, .. } => tx_sync.register_tx(txid, script_pubkey), + #[cfg(feature = "electrum")] Self::Electrum { electrum_runtime_status, .. } => { electrum_runtime_status.write().unwrap().register_tx(txid, script_pubkey) }, @@ -1569,6 +1588,7 @@ impl Filter for ChainSource { fn register_output(&self, output: lightning::chain::WatchedOutput) { match self { Self::Esplora { tx_sync, .. } => tx_sync.register_output(output), + #[cfg(feature = "electrum")] Self::Electrum { electrum_runtime_status, .. } => { electrum_runtime_status.write().unwrap().register_output(output) }, diff --git a/src/config.rs b/src/config.rs index 4a39c1b56..ec4d1c9a0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -380,6 +380,7 @@ impl Default for EsploraSyncConfig { /// /// Background syncing is enabled by default, using the default values specified in /// [`BackgroundSyncConfig`]. +#[cfg(feature = "electrum")] #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct ElectrumSyncConfig { /// Background sync configuration. @@ -391,6 +392,7 @@ pub struct ElectrumSyncConfig { pub background_sync_config: Option, } +#[cfg(feature = "electrum")] impl Default for ElectrumSyncConfig { fn default() -> Self { Self { background_sync_config: Some(BackgroundSyncConfig::default()) } diff --git a/src/lib.rs b/src/lib.rs index c3bfe16d8..73c461142 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1269,6 +1269,7 @@ impl Node { .await?; chain_source.sync_onchain_wallet().await?; }, + #[cfg(feature = "electrum")] ChainSource::Electrum { .. } => { chain_source.update_fee_rate_estimates().await?; chain_source @@ -1546,7 +1547,7 @@ impl Node { /// Creates a digital ECDSA signature of a message with the node's secret key. /// - /// A receiver knowing the corresponding `PublicKey` (e.g. the node’s id) and the message + /// A receiver knowing the corresponding `PublicKey` (e.g. the node's id) and the message /// can be sure that the signature was generated by the caller. /// Signatures are EC recoverable, meaning that given the message and the /// signature the `PublicKey` of the signer can be extracted. diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 3258df791..106d0ed20 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -12,7 +12,9 @@ pub(crate) mod logging; use logging::TestLogWriter; -use ldk_node::config::{Config, ElectrumSyncConfig, EsploraSyncConfig}; +use ldk_node::config::{Config, EsploraSyncConfig}; +#[cfg(feature = "electrum")] +use ldk_node::config::ElectrumSyncConfig; use ldk_node::io::sqlite_store::SqliteStore; use ldk_node::payment::{PaymentDirection, PaymentKind, PaymentStatus}; use ldk_node::{ @@ -36,6 +38,7 @@ use bitcoin::{Address, Amount, Network, OutPoint, Txid}; use electrsd::corepc_node::Client as BitcoindClient; use electrsd::corepc_node::Node as BitcoinD; use electrsd::{corepc_node, ElectrsD}; +#[cfg(feature = "electrum")] use electrum_client::ElectrumApi; use rand::distributions::Alphanumeric; @@ -255,6 +258,7 @@ type TestNode = Node; #[derive(Clone)] pub(crate) enum TestChainSource<'a> { Esplora(&'a ElectrsD), + #[cfg(feature = "electrum")] Electrum(&'a ElectrsD), BitcoindRpc(&'a BitcoinD), } @@ -312,6 +316,7 @@ pub(crate) fn setup_node( let sync_config = EsploraSyncConfig { background_sync_config: None }; builder.set_chain_source_esplora(esplora_url.clone(), Some(sync_config)); }, + #[cfg(feature = "electrum")] TestChainSource::Electrum(electrsd) => { let electrum_url = format!("tcp://{}", electrsd.electrum_url); let sync_config = ElectrumSyncConfig { background_sync_config: None }; @@ -360,6 +365,7 @@ pub(crate) fn setup_node( node } +#[cfg(feature = "electrum")] pub(crate) fn generate_blocks_and_wait( bitcoind: &BitcoindClient, electrs: &E, num: usize, ) { @@ -376,6 +382,7 @@ pub(crate) fn generate_blocks_and_wait( println!("\n"); } +#[cfg(feature = "electrum")] pub(crate) fn wait_for_block(electrs: &E, min_height: usize) { let mut header = match electrs.block_headers_subscribe() { Ok(header) => header, @@ -398,6 +405,7 @@ pub(crate) fn wait_for_block(electrs: &E, min_height: usize) { } } +#[cfg(feature = "electrum")] pub(crate) fn wait_for_tx(electrs: &E, txid: Txid) { let mut tx_res = electrs.transaction_get(&txid); loop { @@ -411,6 +419,7 @@ pub(crate) fn wait_for_tx(electrs: &E, txid: Txid) { } } +#[cfg(feature = "electrum")] pub(crate) fn wait_for_outpoint_spend(electrs: &E, outpoint: OutPoint) { let tx = electrs.transaction_get(&outpoint.txid).unwrap(); let txout_script = tx.output.get(outpoint.vout as usize).unwrap().clone().script_pubkey; @@ -448,6 +457,7 @@ where } } +#[cfg(feature = "electrum")] pub(crate) fn premine_and_distribute_funds( bitcoind: &BitcoindClient, electrs: &E, addrs: Vec
, amount: Amount, ) { @@ -496,6 +506,7 @@ pub fn open_channel( wait_for_tx(&electrsd.client, funding_txo_a.txid); } +#[cfg(feature = "electrum")] pub(crate) fn do_channel_full_cycle( node_a: TestNode, node_b: TestNode, bitcoind: &BitcoindClient, electrsd: &E, allow_0conf: bool, expect_anchor_channel: bool, force_close: bool,