@@ -11,7 +11,7 @@ use std::default::Default;
1111use std:: path:: PathBuf ;
1212use std:: sync:: atomic:: AtomicU64 ;
1313use std:: sync:: { Arc , Mutex , Once , RwLock } ;
14- use std:: time:: { Duration , SystemTime } ;
14+ use std:: time:: SystemTime ;
1515use std:: { fmt, fs} ;
1616
1717use bdk_wallet:: template:: Bip84 ;
@@ -48,8 +48,7 @@ use crate::config::{
4848 default_user_config, may_announce_channel, AnnounceError , AsyncPaymentsRole ,
4949 BitcoindRestClientConfig , Config , ElectrumSyncConfig , EsploraSyncConfig , TorConfig ,
5050 DEFAULT_ESPLORA_SERVER_URL , DEFAULT_LOG_FILENAME , DEFAULT_LOG_LEVEL ,
51- DEFAULT_MAX_PROBE_AMOUNT_MSAT , DEFAULT_MAX_PROBE_LOCKED_MSAT , DEFAULT_PROBING_INTERVAL_SECS ,
52- MIN_PROBE_AMOUNT_MSAT ,
51+ DEFAULT_MAX_PROBE_AMOUNT_MSAT , MIN_PROBE_AMOUNT_MSAT ,
5352} ;
5453use crate :: connection:: ConnectionManager ;
5554use crate :: entropy:: NodeEntropy ;
@@ -155,38 +154,6 @@ impl std::fmt::Debug for LogWriterConfig {
155154 }
156155}
157156
158- #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
159- enum ProbingStrategyKind {
160- HighDegree { top_n : usize } ,
161- Random { max_hops : usize } ,
162- Custom ( Arc < dyn probing:: ProbingStrategy > ) ,
163- }
164-
165- struct ProbingStrategyConfig {
166- kind : ProbingStrategyKind ,
167- interval : Duration ,
168- max_locked_msat : u64 ,
169- }
170-
171- impl fmt:: Debug for ProbingStrategyConfig {
172- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
173- let kind_str = match & self . kind {
174- ProbingStrategyKind :: HighDegree { top_n } => {
175- format ! ( "HighDegree {{ top_n: {} }}" , top_n)
176- } ,
177- ProbingStrategyKind :: Random { max_hops } => {
178- format ! ( "Random {{ max_hops: {} }}" , max_hops)
179- } ,
180- ProbingStrategyKind :: Custom ( _) => "Custom(<probing strategy>)" . to_string ( ) ,
181- } ;
182- f. debug_struct ( "ProbingStrategyConfig" )
183- . field ( "kind" , & kind_str)
184- . field ( "interval" , & self . interval )
185- . field ( "max_locked_msat" , & self . max_locked_msat )
186- . finish ( )
187- }
188- }
189-
190157/// An error encountered during building a [`Node`].
191158///
192159/// [`Node`]: crate::Node
@@ -317,8 +284,7 @@ pub struct NodeBuilder {
317284 runtime_handle : Option < tokio:: runtime:: Handle > ,
318285 pathfinding_scores_sync_config : Option < PathfindingScoresSyncConfig > ,
319286 recovery_mode : bool ,
320- probing_strategy : Option < ProbingStrategyConfig > ,
321- probing_diversity_penalty_msat : Option < u64 > ,
287+ probing_config : Option < probing:: ProbingConfig > ,
322288}
323289
324290impl NodeBuilder {
@@ -338,8 +304,7 @@ impl NodeBuilder {
338304 let pathfinding_scores_sync_config = None ;
339305 let recovery_mode = false ;
340306 let async_payments_role = None ;
341- let probing_strategy = None ;
342- let probing_diversity_penalty_msat = None ;
307+ let probing_config = None ;
343308 Self {
344309 config,
345310 chain_data_source_config,
@@ -350,8 +315,7 @@ impl NodeBuilder {
350315 async_payments_role,
351316 pathfinding_scores_sync_config,
352317 recovery_mode,
353- probing_strategy,
354- probing_diversity_penalty_msat,
318+ probing_config,
355319 }
356320 }
357321
@@ -657,87 +621,23 @@ impl NodeBuilder {
657621 self
658622 }
659623
660- /// Configures background probing toward the highest-degree nodes in the network graph.
661- ///
662- /// `top_n` controls how many of the most-connected nodes are cycled through.
663- #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
664- pub fn set_high_degree_probing_strategy ( & mut self , top_n : usize ) -> & mut Self {
665- let kind = ProbingStrategyKind :: HighDegree { top_n } ;
666- self . probing_strategy = Some ( self . make_probing_config ( kind) ) ;
667- self
668- }
669-
670- /// Configures background probing via random graph walks of up to `max_hops` hops.
671- #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
672- pub fn set_random_probing_strategy ( & mut self , max_hops : usize ) -> & mut Self {
673- let kind = ProbingStrategyKind :: Random { max_hops } ;
674- self . probing_strategy = Some ( self . make_probing_config ( kind) ) ;
675- self
676- }
677-
678- /// Configures a custom probing strategy for background channel probing.
679- ///
680- /// When set, the node will periodically call [`probing::ProbingStrategy::next_probe`] and dispatch the
681- /// returned probe via the channel manager.
682- #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
683- pub fn set_custom_probing_strategy (
684- & mut self , strategy : Arc < dyn probing:: ProbingStrategy > ,
685- ) -> & mut Self {
686- let kind = ProbingStrategyKind :: Custom ( strategy) ;
687- self . probing_strategy = Some ( self . make_probing_config ( kind) ) ;
688- self
689- }
690-
691- /// Overrides the interval between probe attempts. Only has effect if a probing strategy is set.
692- #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
693- pub fn set_probing_interval ( & mut self , interval : Duration ) -> & mut Self {
694- if let Some ( cfg) = & mut self . probing_strategy {
695- cfg. interval = interval;
696- }
697- self
698- }
699-
700- /// Overrides the maximum millisatoshis that may be locked in in-flight probes at any time.
701- /// Only has effect if a probing strategy is set.
702- #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
703- pub fn set_max_probe_locked_msat ( & mut self , max_msat : u64 ) -> & mut Self {
704- if let Some ( cfg) = & mut self . probing_strategy {
705- cfg. max_locked_msat = max_msat;
706- }
707- self
708- }
709-
710- /// Sets the probing diversity penalty applied by the probabilistic scorer.
624+ /// Configures background probing.
711625 ///
712- /// When set, the scorer will penalize channels that have been recently probed,
713- /// encouraging path diversity during background probing. The penalty decays
714- /// quadratically over 24 hours.
626+ /// Use [`probing::ProbingConfig`] to build the configuration:
627+ /// ```ignore
628+ /// use ldk_node::probing::ProbingConfig;
715629 ///
716- /// This is only useful for probing strategies that route through the scorer
717- /// (e.g., [`probing::HighDegreeStrategy`]). Strategies that build paths manually
718- /// (e.g., [`probing::RandomStrategy`]) bypass the scorer entirely.
719- ///
720- /// If unset, LDK's default of `0` (no penalty) is used.
721- # [ cfg_attr ( feature = "uniffi" , allow ( dead_code ) ) ]
722- pub fn set_probing_diversity_penalty_msat ( & mut self , penalty_msat : u64 ) -> & mut Self {
723- self . probing_diversity_penalty_msat = Some ( penalty_msat ) ;
630+ /// builder.set_probing_config(
631+ /// ProbingConfig::high_degree(100)
632+ /// .interval(Duration::from_secs(30))
633+ /// .build()
634+ /// );
635+ /// ```
636+ pub fn set_probing_config ( & mut self , config : probing :: ProbingConfig ) -> & mut Self {
637+ self . probing_config = Some ( config ) ;
724638 self
725639 }
726640
727- #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
728- fn make_probing_config ( & self , kind : ProbingStrategyKind ) -> ProbingStrategyConfig {
729- let existing = self . probing_strategy . as_ref ( ) ;
730- ProbingStrategyConfig {
731- kind,
732- interval : existing
733- . map ( |c| c. interval )
734- . unwrap_or ( Duration :: from_secs ( DEFAULT_PROBING_INTERVAL_SECS ) ) ,
735- max_locked_msat : existing
736- . map ( |c| c. max_locked_msat )
737- . unwrap_or ( DEFAULT_MAX_PROBE_LOCKED_MSAT ) ,
738- }
739- }
740-
741641 /// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
742642 /// previously configured.
743643 pub fn build ( & self , node_entropy : NodeEntropy ) -> Result < Node , BuildError > {
@@ -909,14 +809,13 @@ impl NodeBuilder {
909809 self . gossip_source_config . as_ref ( ) ,
910810 self . liquidity_source_config . as_ref ( ) ,
911811 self . pathfinding_scores_sync_config . as_ref ( ) ,
812+ self . probing_config . as_ref ( ) ,
912813 self . async_payments_role ,
913814 self . recovery_mode ,
914815 seed_bytes,
915816 runtime,
916817 logger,
917818 Arc :: new ( DynStoreWrapper ( kv_store) ) ,
918- self . probing_strategy . as_ref ( ) ,
919- self . probing_diversity_penalty_msat ,
920819 )
921820 }
922821}
@@ -1207,34 +1106,11 @@ impl ArcedNodeBuilder {
12071106 self . inner . write ( ) . unwrap ( ) . set_wallet_recovery_mode ( ) ;
12081107 }
12091108
1210- /// Configures background probing toward the highest-degree nodes in the network graph.
1211- pub fn set_high_degree_probing_strategy ( & self , top_n : usize ) {
1212- self . inner . write ( ) . unwrap ( ) . set_high_degree_probing_strategy ( top_n) ;
1213- }
1214-
1215- /// Configures background probing via random graph walks of up to `max_hops` hops.
1216- pub fn set_random_probing_strategy ( & self , max_hops : usize ) {
1217- self . inner . write ( ) . unwrap ( ) . set_random_probing_strategy ( max_hops) ;
1218- }
1219-
1220- /// Configures a custom probing strategy for background channel probing.
1221- pub fn set_custom_probing_strategy ( & self , strategy : Arc < dyn probing:: ProbingStrategy > ) {
1222- self . inner . write ( ) . unwrap ( ) . set_custom_probing_strategy ( strategy) ;
1223- }
1224-
1225- /// Overrides the interval between probe attempts.
1226- pub fn set_probing_interval ( & self , interval : Duration ) {
1227- self . inner . write ( ) . unwrap ( ) . set_probing_interval ( interval) ;
1228- }
1229-
1230- /// Overrides the maximum millisatoshis that may be locked in in-flight probes at any time.
1231- pub fn set_max_probe_locked_msat ( & self , max_msat : u64 ) {
1232- self . inner . write ( ) . unwrap ( ) . set_max_probe_locked_msat ( max_msat) ;
1233- }
1234-
1235- /// Sets the probing diversity penalty applied by the probabilistic scorer.
1236- pub fn set_probing_diversity_penalty_msat ( & self , penalty_msat : u64 ) {
1237- self . inner . write ( ) . unwrap ( ) . set_probing_diversity_penalty_msat ( penalty_msat) ;
1109+ /// Configures background probing.
1110+ ///
1111+ /// See [`probing::ProbingConfig`] for details.
1112+ pub fn set_probing_config ( & self , config : probing:: ProbingConfig ) {
1113+ self . inner . write ( ) . unwrap ( ) . set_probing_config ( config) ;
12381114 }
12391115
12401116 /// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
@@ -1380,9 +1256,9 @@ fn build_with_store_internal(
13801256 gossip_source_config : Option < & GossipSourceConfig > ,
13811257 liquidity_source_config : Option < & LiquiditySourceConfig > ,
13821258 pathfinding_scores_sync_config : Option < & PathfindingScoresSyncConfig > ,
1259+ probing_config : Option < & probing:: ProbingConfig > ,
13831260 async_payments_role : Option < AsyncPaymentsRole > , recovery_mode : bool , seed_bytes : [ u8 ; 64 ] ,
13841261 runtime : Arc < Runtime > , logger : Arc < Logger > , kv_store : Arc < DynStore > ,
1385- probing_config : Option < & ProbingStrategyConfig > , probing_diversity_penalty_msat : Option < u64 > ,
13861262) -> Result < Node , BuildError > {
13871263 optionally_install_rustls_cryptoprovider ( ) ;
13881264
@@ -1784,7 +1660,7 @@ fn build_with_store_internal(
17841660 }
17851661
17861662 let mut scoring_fee_params = ProbabilisticScoringFeeParameters :: default ( ) ;
1787- if let Some ( penalty) = probing_diversity_penalty_msat {
1663+ if let Some ( penalty) = probing_config . and_then ( |c| c . diversity_penalty_msat ) {
17881664 scoring_fee_params. probing_diversity_penalty_msat = penalty;
17891665 }
17901666 let router = Arc :: new ( DefaultRouter :: new (
@@ -2127,26 +2003,29 @@ fn build_with_store_internal(
21272003
21282004 let prober = probing_config. map ( |probing_cfg| {
21292005 let strategy: Arc < dyn probing:: ProbingStrategy > = match & probing_cfg. kind {
2130- ProbingStrategyKind :: HighDegree { top_n } => {
2006+ probing :: ProbingStrategyKind :: HighDegree { top_node_count } => {
21312007 Arc :: new ( probing:: HighDegreeStrategy :: new (
2132- network_graph. clone ( ) ,
2133- * top_n,
2008+ Arc :: clone ( & network_graph) ,
2009+ * top_node_count,
2010+ MIN_PROBE_AMOUNT_MSAT ,
2011+ DEFAULT_MAX_PROBE_AMOUNT_MSAT ,
2012+ probing_cfg. cooldown ,
2013+ ) )
2014+ } ,
2015+ probing:: ProbingStrategyKind :: Random { max_hops } => {
2016+ Arc :: new ( probing:: RandomStrategy :: new (
2017+ Arc :: clone ( & network_graph) ,
2018+ Arc :: clone ( & channel_manager) ,
2019+ * max_hops,
21342020 MIN_PROBE_AMOUNT_MSAT ,
21352021 DEFAULT_MAX_PROBE_AMOUNT_MSAT ,
21362022 ) )
21372023 } ,
2138- ProbingStrategyKind :: Random { max_hops } => Arc :: new ( probing:: RandomStrategy :: new (
2139- network_graph. clone ( ) ,
2140- channel_manager. clone ( ) ,
2141- * max_hops,
2142- MIN_PROBE_AMOUNT_MSAT ,
2143- DEFAULT_MAX_PROBE_AMOUNT_MSAT ,
2144- ) ) ,
2145- ProbingStrategyKind :: Custom ( s) => s. clone ( ) ,
2024+ probing:: ProbingStrategyKind :: Custom ( s) => Arc :: clone ( s) ,
21462025 } ;
21472026 Arc :: new ( probing:: Prober {
2148- channel_manager : channel_manager . clone ( ) ,
2149- logger : logger . clone ( ) ,
2027+ channel_manager : Arc :: clone ( & channel_manager ) ,
2028+ logger : Arc :: clone ( & logger ) ,
21502029 strategy,
21512030 interval : probing_cfg. interval ,
21522031 liquidity_limit_multiplier : Some ( config. probing_liquidity_limit_multiplier ) ,
0 commit comments