@@ -45,8 +45,8 @@ use vss_client::headers::VssHeaderProvider;
4545use crate :: chain:: ChainSource ;
4646use crate :: config:: {
4747 default_user_config, may_announce_channel, AnnounceError , AsyncPaymentsRole ,
48- BitcoindRestClientConfig , Config , ElectrumSyncConfig , EsploraSyncConfig , TorConfig ,
49- DEFAULT_ESPLORA_SERVER_URL , DEFAULT_LOG_FILENAME , DEFAULT_LOG_LEVEL ,
48+ BitcoindRestClientConfig , CbfSyncConfig , Config , ElectrumSyncConfig , EsploraSyncConfig ,
49+ TorConfig , DEFAULT_ESPLORA_SERVER_URL , DEFAULT_LOG_FILENAME , DEFAULT_LOG_LEVEL ,
5050} ;
5151use crate :: connection:: ConnectionManager ;
5252use crate :: entropy:: NodeEntropy ;
@@ -105,6 +105,10 @@ enum ChainDataSourceConfig {
105105 rpc_password : String ,
106106 rest_client_config : Option < BitcoindRestClientConfig > ,
107107 } ,
108+ Cbf {
109+ peers : Vec < String > ,
110+ sync_config : Option < CbfSyncConfig > ,
111+ } ,
108112}
109113
110114#[ derive( Debug , Clone ) ]
@@ -365,6 +369,26 @@ impl NodeBuilder {
365369 self
366370 }
367371
372+ /// Configures the [`Node`] instance to source its chain data via BIP 157 compact block
373+ /// filters.
374+ ///
375+ /// `peers` is an optional list of peer addresses to connect to for sourcing compact block
376+ /// filters. If empty, the node will discover peers via DNS seeds.
377+ ///
378+ /// If no `sync_config` is given, default values are used. See [`CbfSyncConfig`] for more
379+ /// information.
380+ ///
381+ /// Note: fee rate estimation with this chain source uses block-level averages (total fees
382+ /// divided by block weight) rather than per-transaction fee rates. This can underestimate
383+ /// next-block inclusion rates during periods of high mempool congestion. Percentile-based
384+ /// target selection partially mitigates this.
385+ pub fn set_chain_source_cbf (
386+ & mut self , peers : Vec < String > , sync_config : Option < CbfSyncConfig > ,
387+ ) -> & mut Self {
388+ self . chain_data_source_config = Some ( ChainDataSourceConfig :: Cbf { peers, sync_config } ) ;
389+ self
390+ }
391+
368392 /// Configures the [`Node`] instance to connect to a Bitcoin Core node via RPC.
369393 ///
370394 /// This method establishes an RPC connection that enables all essential chain operations including
@@ -892,6 +916,23 @@ impl ArcedNodeBuilder {
892916 self . inner . write ( ) . unwrap ( ) . set_chain_source_electrum ( server_url, sync_config) ;
893917 }
894918
919+ /// Configures the [`Node`] instance to source its chain data via BIP 157 compact block
920+ /// filters.
921+ ///
922+ /// `peers` is an optional list of peer addresses to connect to for sourcing compact block
923+ /// filters. If empty, the node will discover peers via DNS seeds.
924+ ///
925+ /// If no `sync_config` is given, default values are used. See [`CbfSyncConfig`] for more
926+ /// information.
927+ ///
928+ /// Note: fee rate estimation with this chain source uses block-level averages (total fees
929+ /// divided by block weight) rather than per-transaction fee rates. This can underestimate
930+ /// next-block inclusion rates during periods of high mempool congestion. Percentile-based
931+ /// target selection partially mitigates this.
932+ pub fn set_chain_source_cbf ( & self , peers : Vec < String > , sync_config : Option < CbfSyncConfig > ) {
933+ self . inner . write ( ) . unwrap ( ) . set_chain_source_cbf ( peers, sync_config) ;
934+ }
935+
895936 /// Configures the [`Node`] instance to connect to a Bitcoin Core node via RPC.
896937 ///
897938 /// This method establishes an RPC connection that enables all essential chain operations including
@@ -1364,6 +1405,20 @@ fn build_with_store_internal(
13641405 } ) ,
13651406 } ,
13661407
1408+ Some ( ChainDataSourceConfig :: Cbf { peers, sync_config } ) => {
1409+ let sync_config = sync_config. clone ( ) . unwrap_or ( CbfSyncConfig :: default ( ) ) ;
1410+ ChainSource :: new_cbf (
1411+ peers. clone ( ) ,
1412+ sync_config,
1413+ Arc :: clone ( & fee_estimator) ,
1414+ Arc :: clone ( & tx_broadcaster) ,
1415+ Arc :: clone ( & kv_store) ,
1416+ Arc :: clone ( & config) ,
1417+ Arc :: clone ( & logger) ,
1418+ Arc :: clone ( & node_metrics) ,
1419+ )
1420+ } ,
1421+
13671422 None => {
13681423 // Default to Esplora client.
13691424 let server_url = DEFAULT_ESPLORA_SERVER_URL . to_string ( ) ;
@@ -2079,6 +2134,9 @@ pub(crate) fn sanitize_alias(alias_str: &str) -> Result<NodeAlias, BuildError> {
20792134
20802135#[ cfg( test) ]
20812136mod tests {
2137+ #[ cfg( feature = "uniffi" ) ]
2138+ use crate :: config:: CbfSyncConfig ;
2139+
20822140 use super :: { sanitize_alias, BuildError , NodeAlias } ;
20832141
20842142 #[ test]
@@ -2116,4 +2174,23 @@ mod tests {
21162174 let node = sanitize_alias ( alias) ;
21172175 assert_eq ! ( node. err( ) . unwrap( ) , BuildError :: InvalidNodeAlias ) ;
21182176 }
2177+
2178+ #[ cfg( feature = "uniffi" ) ]
2179+ #[ test]
2180+ fn arced_builder_can_set_cbf_chain_source ( ) {
2181+ let builder = super :: ArcedNodeBuilder :: new ( ) ;
2182+ let sync_config = CbfSyncConfig :: default ( ) ;
2183+
2184+ let peers = vec ! [ "127.0.0.1:8333" . to_string( ) ] ;
2185+ builder. set_chain_source_cbf ( peers. clone ( ) , Some ( sync_config. clone ( ) ) ) ;
2186+
2187+ let guard = builder. inner . read ( ) . unwrap ( ) ;
2188+ assert ! ( matches!(
2189+ guard. chain_data_source_config. as_ref( ) ,
2190+ Some ( super :: ChainDataSourceConfig :: Cbf {
2191+ peers: p,
2192+ sync_config: Some ( config) ,
2193+ } ) if config == & sync_config && p == & peers
2194+ ) ) ;
2195+ }
21192196}
0 commit comments