@@ -57,9 +57,23 @@ pub const DEFAULT_STORAGE_DIR_PATH: &str = "/tmp/ldk_node";
5757// The default Esplora server we're using.
5858pub ( crate ) const DEFAULT_ESPLORA_SERVER_URL : & str = "https://blockstream.info/api" ;
5959
60- // The 'stop gap' parameter used by BDK's wallet sync. This seems to configure the threshold
61- // number of derivation indexes after which BDK stops looking for new scripts belonging to the wallet.
62- pub ( crate ) const BDK_CLIENT_STOP_GAP : usize = 20 ;
60+ /// The default stop gap used for BDK full scans of the on-chain wallet.
61+ ///
62+ /// The current default is 20.
63+ pub const DEFAULT_FULL_SCAN_STOP_GAP : u32 = 20 ;
64+
65+ /// The minimum allowed stop gap used for BDK full scans of the on-chain wallet.
66+ ///
67+ /// Values below 1 are clamped to 1 when a full scan runs.
68+ pub const MIN_FULL_SCAN_STOP_GAP : u32 = 1 ;
69+
70+ /// The maximum allowed stop gap used for BDK full scans of the on-chain wallet.
71+ ///
72+ /// Values above 1000 are clamped to 1000 when a full scan runs.
73+ pub const MAX_FULL_SCAN_STOP_GAP : u32 = 1000 ;
74+
75+ // The fixed stop gap used by backends that don't yet expose a configurable value.
76+ pub ( crate ) const BDK_CLIENT_STOP_GAP : usize = DEFAULT_FULL_SCAN_STOP_GAP as usize ;
6377
6478// The number of concurrent requests made against the API provider.
6579pub ( crate ) const BDK_CLIENT_CONCURRENCY : usize = 4 ;
@@ -506,6 +520,23 @@ pub struct EsploraSyncConfig {
506520 pub background_sync_config : Option < BackgroundSyncConfig > ,
507521 /// Sync timeouts configuration.
508522 pub timeouts_config : SyncTimeoutsConfig ,
523+ /// The stop gap used for BDK full scans of the on-chain wallet.
524+ ///
525+ /// A full scan for each keychain stops after this many consecutive script pubkeys
526+ /// with no associated transactions. This value is only used for BDK `full_scan`
527+ /// calls, which ldk-node performs on the first on-chain wallet sync or when
528+ /// [`Self::force_wallet_full_scan`] is set. Incremental BDK `sync` calls do not use it.
529+ ///
530+ /// **Default:** 20 ([`DEFAULT_FULL_SCAN_STOP_GAP`])
531+ ///
532+ /// **Allowed values:** 1 ([`MIN_FULL_SCAN_STOP_GAP`]) to 1000
533+ /// ([`MAX_FULL_SCAN_STOP_GAP`]), inclusive. Values outside this range will be clamped to the
534+ /// nearest bound and a warning will be logged when the full scan runs.
535+ ///
536+ /// **Note:** Large values can cause many Esplora requests, hit server rate limits,
537+ /// take a long time to complete, or cause syncs to fail with
538+ /// [`SyncTimeoutsConfig::onchain_wallet_sync_timeout_secs`].
539+ pub full_scan_stop_gap : u32 ,
509540 /// Whether to force BDK full scans until one succeeds.
510541 ///
511542 /// This can be useful when restoring a wallet from seed on a node that has already synced
@@ -518,6 +549,7 @@ impl Default for EsploraSyncConfig {
518549 Self {
519550 background_sync_config : Some ( BackgroundSyncConfig :: default ( ) ) ,
520551 timeouts_config : SyncTimeoutsConfig :: default ( ) ,
552+ full_scan_stop_gap : DEFAULT_FULL_SCAN_STOP_GAP ,
521553 force_wallet_full_scan : false ,
522554 }
523555 }
@@ -556,6 +588,10 @@ impl Default for ElectrumSyncConfig {
556588 }
557589}
558590
591+ pub ( crate ) fn clamp_full_scan_stop_gap ( full_scan_stop_gap : u32 ) -> u32 {
592+ full_scan_stop_gap. clamp ( MIN_FULL_SCAN_STOP_GAP , MAX_FULL_SCAN_STOP_GAP )
593+ }
594+
559595/// Configuration for syncing with Bitcoin Core backend via REST.
560596#[ derive( Debug , Clone ) ]
561597pub struct BitcoindRestClientConfig {
@@ -711,7 +747,11 @@ pub enum AsyncPaymentsRole {
711747mod tests {
712748 use std:: str:: FromStr ;
713749
714- use super :: { may_announce_channel, AnnounceError , Config , NodeAlias , SocketAddress } ;
750+ use super :: {
751+ clamp_full_scan_stop_gap, may_announce_channel, AnnounceError , Config , EsploraSyncConfig ,
752+ NodeAlias , SocketAddress , DEFAULT_FULL_SCAN_STOP_GAP , MAX_FULL_SCAN_STOP_GAP ,
753+ MIN_FULL_SCAN_STOP_GAP ,
754+ } ;
715755
716756 #[ test]
717757 fn node_announce_channel ( ) {
@@ -758,4 +798,21 @@ mod tests {
758798 }
759799 assert ! ( may_announce_channel( & node_config) . is_ok( ) ) ;
760800 }
801+
802+ #[ test]
803+ fn full_scan_stop_gap_defaults ( ) {
804+ assert_eq ! ( EsploraSyncConfig :: default ( ) . full_scan_stop_gap, DEFAULT_FULL_SCAN_STOP_GAP ) ;
805+ }
806+
807+ #[ test]
808+ fn full_scan_stop_gap_is_clamped_to_valid_range ( ) {
809+ assert_eq ! ( clamp_full_scan_stop_gap( MIN_FULL_SCAN_STOP_GAP ) , MIN_FULL_SCAN_STOP_GAP ) ;
810+ assert_eq ! (
811+ clamp_full_scan_stop_gap( DEFAULT_FULL_SCAN_STOP_GAP ) ,
812+ DEFAULT_FULL_SCAN_STOP_GAP
813+ ) ;
814+ assert_eq ! ( clamp_full_scan_stop_gap( MAX_FULL_SCAN_STOP_GAP ) , MAX_FULL_SCAN_STOP_GAP ) ;
815+ assert_eq ! ( clamp_full_scan_stop_gap( 0 ) , MIN_FULL_SCAN_STOP_GAP ) ;
816+ assert_eq ! ( clamp_full_scan_stop_gap( MAX_FULL_SCAN_STOP_GAP + 1 ) , MAX_FULL_SCAN_STOP_GAP ) ;
817+ }
761818}
0 commit comments