Skip to content

Add electrum feature flag #558

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
Expand All @@ -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"] }
Expand All @@ -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"] }
Expand All @@ -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"] }
Expand Down
11 changes: 9 additions & 2 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -85,6 +88,7 @@ const LSPS_HARDENED_CHILD_INDEX: u32 = 577;
#[derive(Debug, Clone)]
enum ChainDataSourceConfig {
Esplora { server_url: String, sync_config: Option<EsploraSyncConfig> },
#[cfg(feature = "electrum")]
Electrum { server_url: String, sync_config: Option<ElectrumSyncConfig> },
BitcoindRpc { rpc_host: String, rpc_port: u16, rpc_user: String, rpc_password: String },
}
Expand Down Expand Up @@ -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<ElectrumSyncConfig>,
) -> &mut Self {
Expand Down Expand Up @@ -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<ElectrumSyncConfig>,
) {
Expand Down Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions src/chain/electrum.rs
Original file line number Diff line number Diff line change
@@ -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 <LICENSE-APACHE or
Expand Down
22 changes: 21 additions & 1 deletion src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,24 @@
// accordance with one or both of these licenses.

mod bitcoind_rpc;
#[cfg(feature = "electrum")]
mod electrum;

use crate::chain::bitcoind_rpc::{
BitcoindRpcClient, BoundedHeaderCache, ChainListener, FeeRateEstimationMode,
};
#[cfg(feature = "electrum")]
use crate::chain::electrum::ElectrumRuntimeClient;
use crate::config::{
BackgroundSyncConfig, Config, ElectrumSyncConfig, EsploraSyncConfig, BDK_CLIENT_CONCURRENCY,
BackgroundSyncConfig, Config, EsploraSyncConfig, BDK_CLIENT_CONCURRENCY,
BDK_CLIENT_STOP_GAP, BDK_WALLET_SYNC_TIMEOUT_SECS, FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS,
LDK_WALLET_SYNC_TIMEOUT_SECS, RESOLVED_CHANNEL_MONITOR_ARCHIVAL_INTERVAL,
TX_BROADCAST_TIMEOUT_SECS, WALLET_SYNC_INTERVAL_MINIMUM_SECS,
};

#[cfg(feature = "electrum")]
use crate::config::ElectrumSyncConfig;

use crate::fee_estimator::{
apply_post_estimation_adjustments, get_all_conf_targets, get_num_block_defaults_for_target,
ConfirmationTarget, OnchainFeeEstimator,
Expand Down Expand Up @@ -110,6 +116,7 @@ impl WalletSyncStatus {
}
}

#[cfg(feature = "electrum")]
pub(crate) enum ElectrumRuntimeStatus {
Started(Arc<ElectrumRuntimeClient>),
Stopped {
Expand All @@ -118,6 +125,7 @@ pub(crate) enum ElectrumRuntimeStatus {
},
}

#[cfg(feature = "electrum")]
impl ElectrumRuntimeStatus {
pub(crate) fn new() -> Self {
let pending_registered_txs = Vec::new();
Expand Down Expand Up @@ -201,6 +209,7 @@ pub(crate) enum ChainSource {
logger: Arc<Logger>,
node_metrics: Arc<RwLock<NodeMetrics>>,
},
#[cfg(feature = "electrum")]
Electrum {
server_url: String,
sync_config: ElectrumSyncConfig,
Expand Down Expand Up @@ -260,6 +269,7 @@ impl ChainSource {
}
}

#[cfg(feature = "electrum")]
pub(crate) fn new_electrum(
server_url: String, sync_config: ElectrumSyncConfig, onchain_wallet: Arc<Wallet>,
fee_estimator: Arc<OnchainFeeEstimator>, tx_broadcaster: Arc<Broadcaster>,
Expand Down Expand Up @@ -313,6 +323,7 @@ impl ChainSource {

pub(crate) fn start(&self, runtime: Arc<tokio::runtime::Runtime>) -> 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(),
Expand All @@ -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();
},
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -718,6 +731,7 @@ impl ChainSource {

res
},
#[cfg(feature = "electrum")]
Self::Electrum {
electrum_runtime_status,
onchain_wallet,
Expand Down Expand Up @@ -909,6 +923,7 @@ impl ChainSource {

res
},
#[cfg(feature = "electrum")]
Self::Electrum {
electrum_runtime_status,
lightning_wallet_sync_status,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -1223,6 +1239,7 @@ impl ChainSource {

Ok(())
},
#[cfg(feature = "electrum")]
Self::Electrum {
electrum_runtime_status,
fee_estimator,
Expand Down Expand Up @@ -1478,6 +1495,7 @@ impl ChainSource {
}
}
},
#[cfg(feature = "electrum")]
Self::Electrum { electrum_runtime_status, tx_broadcaster, .. } => {
let electrum_client: Arc<ElectrumRuntimeClient> = if let Some(client) =
electrum_runtime_status.read().unwrap().client().as_ref()
Expand Down Expand Up @@ -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)
},
Expand All @@ -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)
},
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -391,6 +392,7 @@ pub struct ElectrumSyncConfig {
pub background_sync_config: Option<BackgroundSyncConfig>,
}

#[cfg(feature = "electrum")]
impl Default for ElectrumSyncConfig {
fn default() -> Self {
Self { background_sync_config: Some(BackgroundSyncConfig::default()) }
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 nodes 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.
Expand Down
13 changes: 12 additions & 1 deletion tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -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;
Expand Down Expand Up @@ -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),
}
Expand Down Expand Up @@ -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 };
Expand Down Expand Up @@ -360,6 +365,7 @@ pub(crate) fn setup_node(
node
}

#[cfg(feature = "electrum")]
pub(crate) fn generate_blocks_and_wait<E: ElectrumApi>(
bitcoind: &BitcoindClient, electrs: &E, num: usize,
) {
Expand All @@ -376,6 +382,7 @@ pub(crate) fn generate_blocks_and_wait<E: ElectrumApi>(
println!("\n");
}

#[cfg(feature = "electrum")]
pub(crate) fn wait_for_block<E: ElectrumApi>(electrs: &E, min_height: usize) {
let mut header = match electrs.block_headers_subscribe() {
Ok(header) => header,
Expand All @@ -398,6 +405,7 @@ pub(crate) fn wait_for_block<E: ElectrumApi>(electrs: &E, min_height: usize) {
}
}

#[cfg(feature = "electrum")]
pub(crate) fn wait_for_tx<E: ElectrumApi>(electrs: &E, txid: Txid) {
let mut tx_res = electrs.transaction_get(&txid);
loop {
Expand All @@ -411,6 +419,7 @@ pub(crate) fn wait_for_tx<E: ElectrumApi>(electrs: &E, txid: Txid) {
}
}

#[cfg(feature = "electrum")]
pub(crate) fn wait_for_outpoint_spend<E: ElectrumApi>(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;
Expand Down Expand Up @@ -448,6 +457,7 @@ where
}
}

#[cfg(feature = "electrum")]
pub(crate) fn premine_and_distribute_funds<E: ElectrumApi>(
bitcoind: &BitcoindClient, electrs: &E, addrs: Vec<Address>, amount: Amount,
) {
Expand Down Expand Up @@ -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<E: ElectrumApi>(
node_a: TestNode, node_b: TestNode, bitcoind: &BitcoindClient, electrsd: &E, allow_0conf: bool,
expect_anchor_channel: bool, force_close: bool,
Expand Down
Loading