Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e5f5e7a
Cbf chain source (#25)
randomlogin Sep 8, 2026
eb798a4
fix(cbf): shut down chain source cleanly
febyeji Jun 8, 2026
f723214
fix(cbf): stop chain source before waiting on tasks
febyeji May 22, 2026
2347002
fix(cbf): abort restart when stopped during backoff
febyeji Jun 8, 2026
1419ae9
Implement `process_kyoto_events` (#28)
randomlogin Jun 9, 2026
28c2d53
Implement fee source (#29)
randomlogin Jun 12, 2026
296714b
cbf: implement package broadcasting
randomlogin Jun 9, 2026
f4fb44f
Add `next_height` to the block applicator
randomlogin Jun 11, 2026
88557c3
cbf: make sync_wallets wait for applied tip
febyeji Jul 8, 2026
ed27b55
Cbf fix block fetch (#35)
febyeji Jul 16, 2026
6db4710
Use block header from IndexedFilter event
randomlogin Jul 21, 2026
2b4ebad
tests: add waiting time for CBF tx propagation
randomlogin Sep 29, 2026
7b1923f
cbf: add uniffi builder
randomlogin Sep 30, 2026
7319806
cbf: add preprocessing step before kyoto runs
randomlogin Oct 8, 2026
2df1471
cbf: discover a stable tip for a fresh wallet
randomlogin Oct 26, 2026
5ecf361
cbf: wait for the chain source to sync in `initialize_wallets`
randomlogin Oct 27, 2026
8d93f37
cbf: apply our own transactions to the wallet at broadcast
randomlogin Oct 27, 2026
4e6624c
cbf: do not require both Esplora and Electrum
randomlogin Oct 27, 2026
51a297e
cbf: make required peers and whitelist-only configurable
randomlogin Nov 1, 2026
dace9de
cbf: remove block fetch timeout in `ChainOp`
randomlogin Nov 12, 2026
cac1a13
cbf: broadcast txs even if local application failed
randomlogin Nov 12, 2026
610d992
cbf: bump kyoto version to 0.9.0
randomlogin Nov 12, 2026
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ default = [
"chain-esplora",
"chain-electrum",
"chain-bitcoind",
"chain-cbf",
"storage-sqlite",
"storage-filesystem",
"storage-vss",
Expand All @@ -52,6 +53,7 @@ chain-electrum = [
"lightning-transaction-sync/electrum-rustls-ring",
]
chain-bitcoind = ["dep:lightning-block-sync"]
chain-cbf = ["dep:bip157", "dep:lightning-block-sync"]
storage-sqlite = ["dep:rusqlite"]
storage-filesystem = ["dep:lightning-persister"]
storage-vss = ["dep:vss-client", "dep:prost"]
Expand Down Expand Up @@ -103,6 +105,7 @@ bdk_chain = { version = "0.23.3", default-features = false, features = ["std"] }
bdk_esplora = { version = "0.22.2", default-features = false, features = ["async-https-rustls", "tokio"], optional = true }
bdk_electrum = { version = "0.24.0", default-features = false, features = ["use-rustls-ring"], optional = true }
bdk_wallet = { version = "3.2.0", default-features = false, features = ["std", "keys-bip39"]}
bip157 = { version = "0.9.0", default-features = false, optional = true }

bitreq = { version = "0.3", default-features = false, features = ["async-https", "json-using-serde"] }
rustls = { version = "0.23", default-features = false }
Expand Down
75 changes: 74 additions & 1 deletion src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ use lightning_dns_resolver::OMDomainResolver;
use vss_client::headers::VssHeaderProvider;

use crate::chain::ChainSource;
#[cfg(feature = "chain-cbf")]
use crate::chain::{CbfFeeSourceConfig, CbfNetworkConfig};
#[cfg(feature = "chain-bitcoind")]
use crate::config::BitcoindRestClientConfig;
use crate::config::{
Expand Down Expand Up @@ -139,6 +141,11 @@ enum ChainDataSourceConfig {
rest_client_config: Option<BitcoindRestClientConfig>,
wallet_rescan_from_height: Option<u32>,
},
#[cfg(feature = "chain-cbf")]
Cbf {
network_config: Option<CbfNetworkConfig>,
fee_source_config: Option<CbfFeeSourceConfig>,
},
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -440,6 +447,24 @@ impl NodeBuilder {
self
}

/// Configures the [`Node`] instance to source chain data via compact block filters
/// (BIP157/BIP158).
///
/// If no `network_config` is given, peers are discovered automatically. See
/// [`CbfNetworkConfig`] for more information on the peer settings.
///
/// `fee_source_config` optionally delegates fee estimation to an Esplora or Electrum server;
/// if `None`, fee rates are derived from recent blocks.
#[cfg(feature = "chain-cbf")]
pub fn set_chain_source_cbf(
&mut self, network_config: Option<CbfNetworkConfig>,
fee_source_config: Option<CbfFeeSourceConfig>,
) -> &mut Self {
self.chain_data_source_config =
Some(ChainDataSourceConfig::Cbf { network_config, fee_source_config });
self
}

/// Configures the [`Node`] instance to connect to a Bitcoin Core node via RPC.
///
/// This method establishes an RPC connection that enables all essential chain operations including
Expand Down Expand Up @@ -1101,6 +1126,28 @@ impl Builder {
}
}

#[cfg(all(feature = "uniffi", feature = "chain-cbf"))]
#[uniffi::export]
impl Builder {
/// Configures the [`Node`] instance to source chain data via compact block filters
/// (BIP157/BIP158).
///
/// If no `network_config` is given, peers are discovered automatically. See
/// [`CbfNetworkConfig`] for more information on the peer settings.
///
/// `fee_source_config` optionally delegates fee estimation to an Esplora or Electrum server;
/// if `None`, fee rates are derived from recent blocks.
pub fn set_chain_source_cbf(
&self, network_config: Option<CbfNetworkConfig>,
fee_source_config: Option<CbfFeeSourceConfig>,
) {
self.inner
.write()
.expect("lock")
.set_chain_source_cbf(network_config, fee_source_config);
}
}

#[cfg(all(feature = "uniffi", feature = "chain-bitcoind"))]
#[uniffi::export]
impl Builder {
Expand Down Expand Up @@ -1643,7 +1690,8 @@ fn build_with_store_internal(
},
};

let (chain_source, chain_tip_opt) = match chain_data_source_config {
#[allow(unused_mut)]
let (chain_source, mut chain_tip_opt) = match chain_data_source_config {
#[cfg(feature = "chain-esplora")]
Some(ChainDataSourceConfig::Esplora { server_url, headers, sync_config }) => {
let sync_config = sync_config.unwrap_or(EsploraSyncConfig::default());
Expand Down Expand Up @@ -1674,6 +1722,19 @@ fn build_with_store_internal(
Arc::clone(&node_metrics),
)
},
#[cfg(feature = "chain-cbf")]
Some(ChainDataSourceConfig::Cbf { network_config, fee_source_config }) => ChainSource::new_cbf(
network_config.clone(),
fee_source_config.clone(),
Arc::clone(&runtime),
Arc::clone(&fee_estimator),
Arc::clone(&tx_broadcaster),
Arc::clone(&kv_store),
Arc::clone(&config),
Arc::clone(&logger),
Arc::clone(&node_metrics),
)
.map_err(|_| BuildError::ChainSourceSetupFailed)?,
#[cfg(feature = "chain-bitcoind")]
Some(ChainDataSourceConfig::Bitcoind {
rpc_host,
Expand Down Expand Up @@ -1818,6 +1879,18 @@ fn build_with_store_internal(
wallet
},
None => {
// A CBF node has no trusted node to ask for the tip, so a fresh wallet discovers it
// with a short headers-only sync and starts there, as everything below it is empty.
#[cfg(feature = "chain-cbf")]
if chain_tip_opt.is_none()
&& matches!(chain_data_source_config, Some(ChainDataSourceConfig::Cbf { .. }))
{
let stable_tip = runtime
.block_on(chain_source.fetch_stable_tip())
.map_err(|_| BuildError::ChainTipFetchFailed)?;
chain_tip_opt = Some(stable_tip);
}

// Guard against silently setting the wallet birthday to genesis on a fresh node:
// if we are creating a new wallet but failed to learn the current chain tip from
// a Bitcoin Core RPC/REST backend, we'd otherwise persist fresh wallet state
Expand Down
Loading
Loading