Skip to content

Commit 5513fac

Browse files
committed
Enforce successful initial wallet sync and make sync interval configurable
So far we'd immediately start background syncing upon `start()` which would work fine, except when these initial syncs failed, in which case we'd use our fallback fee. This might lead to being disconnected from peers as our fallback values are likely out of current fee ranges. To mitigate this we here simply enforce that the initial syncs in `start()` are successful and hence we'd at least once got a recent fee estimation update. Moreover, we make the background syncing intervals configurable, however enforcing a floor of 10 seconds.
1 parent f2d157f commit 5513fac

File tree

3 files changed

+121
-52
lines changed

3 files changed

+121
-52
lines changed

bindings/ldk_node.udl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ dictionary Config {
77
Network network;
88
NetAddress? listening_address;
99
u32 default_cltv_expiry_delta;
10+
u64 onchain_wallet_sync_interval_secs;
11+
u64 wallet_sync_interval_secs;
1012
LogLevel log_level;
1113
};
1214

src/lib.rs

Lines changed: 116 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ use types::{
112112
pub use types::{ChannelDetails, ChannelId, PeerDetails, UserChannelId};
113113
use wallet::Wallet;
114114

115-
use logger::{log_error, log_info, FilesystemLogger, Logger};
115+
use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger};
116116

117117
use lightning::chain::keysinterface::EntropySource;
118118
use lightning::chain::{chainmonitor, BestBlock, Confirm, Watch};
@@ -167,9 +167,15 @@ const BDK_CLIENT_STOP_GAP: usize = 20;
167167
// The number of concurrent requests made against the API provider.
168168
const BDK_CLIENT_CONCURRENCY: u8 = 8;
169169

170+
// The default time in-between LDK wallet sync attempts.
171+
const DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS: u64 = 60;
172+
170173
// The timeout after which we abandon retrying failed payments.
171174
const LDK_PAYMENT_RETRY_TIMEOUT: Duration = Duration::from_secs(10);
172175

176+
// The default time in-between LDK wallet sync attempts.
177+
const DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS: u64 = 20;
178+
173179
// The time in-between peer reconnection attempts.
174180
const PEER_RECONNECTION_INTERVAL: Duration = Duration::from_secs(10);
175181

@@ -195,6 +201,14 @@ pub struct Config {
195201
pub listening_address: Option<NetAddress>,
196202
/// The default CLTV expiry delta to be used for payments.
197203
pub default_cltv_expiry_delta: u32,
204+
/// The time in-between background sync attempts of the onchain wallet, in seconds.
205+
///
206+
/// **Note:** A minimum of 10 seconds is always enforced.
207+
pub onchain_wallet_sync_interval_secs: u64,
208+
/// The time in-between background sync attempts of the LDK wallet, in seconds.
209+
///
210+
/// **Note:** A minimum of 10 seconds is always enforced.
211+
pub wallet_sync_interval_secs: u64,
198212
/// The level at which we log messages.
199213
///
200214
/// Any messages below this level will be excluded from the logs.
@@ -209,6 +223,8 @@ impl Default for Config {
209223
network: Network::Regtest,
210224
listening_address: Some("0.0.0.0:9735".parse().unwrap()),
211225
default_cltv_expiry_delta: 144,
226+
onchain_wallet_sync_interval_secs: DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS,
227+
wallet_sync_interval_secs: DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS,
212228
log_level: LogLevel::Debug,
213229
}
214230
}
@@ -717,31 +733,38 @@ impl Node {
717733

718734
let runtime = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();
719735

720-
let event_handler = Arc::new(EventHandler::new(
721-
Arc::clone(&self.wallet),
722-
Arc::clone(&self.event_queue),
723-
Arc::clone(&self.channel_manager),
724-
Arc::clone(&self.network_graph),
725-
Arc::clone(&self.keys_manager),
726-
Arc::clone(&self.payment_store),
727-
Arc::clone(&self.runtime),
728-
Arc::clone(&self.logger),
729-
Arc::clone(&self.config),
730-
));
731-
732736
// Setup wallet sync
733737
let wallet = Arc::clone(&self.wallet);
734-
let tx_sync = Arc::clone(&self.tx_sync);
735-
let sync_cman = Arc::clone(&self.channel_manager);
736-
let sync_cmon = Arc::clone(&self.chain_monitor);
737738
let sync_logger = Arc::clone(&self.logger);
738739
let mut stop_sync = self.stop_receiver.clone();
739740

741+
runtime.block_on(async move {
742+
let now = Instant::now();
743+
match wallet.sync().await {
744+
Ok(()) => {
745+
log_info!(
746+
sync_logger,
747+
"Initial sync of on-chain wallet finished in {}ms.",
748+
now.elapsed().as_millis()
749+
);
750+
Ok(())
751+
}
752+
Err(e) => {
753+
log_error!(sync_logger, "Initial sync of on-chain wallet failed: {}", e,);
754+
Err(e)
755+
}
756+
}
757+
})?;
758+
759+
let sync_logger = Arc::clone(&self.logger);
760+
let wallet = Arc::clone(&self.wallet);
740761
std::thread::spawn(move || {
741762
tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(
742763
async move {
743-
let mut interval = tokio::time::interval(Duration::from_secs(30));
764+
let interval_secs = DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS.max(10);
765+
let mut interval = tokio::time::interval(Duration::from_secs(interval_secs));
744766
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
767+
interval.reset();
745768
loop {
746769
let now = Instant::now();
747770
tokio::select! {
@@ -750,7 +773,7 @@ impl Node {
750773
}
751774
_ = interval.tick() => {
752775
match wallet.sync().await {
753-
Ok(()) => log_info!(
776+
Ok(()) => log_trace!(
754777
sync_logger,
755778
"Background sync of on-chain wallet finished in {}ms.",
756779
now.elapsed().as_millis()
@@ -770,6 +793,68 @@ impl Node {
770793
);
771794
});
772795

796+
let tx_sync = Arc::clone(&self.tx_sync);
797+
let sync_cman = Arc::clone(&self.channel_manager);
798+
let sync_cmon = Arc::clone(&self.chain_monitor);
799+
let sync_logger = Arc::clone(&self.logger);
800+
runtime.block_on(async move {
801+
let now = Instant::now();
802+
let confirmables = vec![
803+
&*sync_cman as &(dyn Confirm + Sync + Send),
804+
&*sync_cmon as &(dyn Confirm + Sync + Send),
805+
];
806+
match tx_sync.sync(confirmables).await {
807+
Ok(()) => {
808+
log_info!(
809+
sync_logger,
810+
"Initial sync of Lightning wallet finished in {}ms.",
811+
now.elapsed().as_millis()
812+
);
813+
Ok(())
814+
}
815+
Err(e) => {
816+
log_error!(sync_logger, "Initial sync of Lightning wallet failed: {}", e);
817+
Err(e)
818+
}
819+
}
820+
})?;
821+
822+
let tx_sync = Arc::clone(&self.tx_sync);
823+
let sync_cman = Arc::clone(&self.channel_manager);
824+
let sync_cmon = Arc::clone(&self.chain_monitor);
825+
let sync_logger = Arc::clone(&self.logger);
826+
let mut stop_sync = self.stop_receiver.clone();
827+
runtime.spawn(async move {
828+
let interval_secs = DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS.max(10);
829+
let mut interval = tokio::time::interval(Duration::from_secs(interval_secs));
830+
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
831+
interval.reset();
832+
loop {
833+
let now = Instant::now();
834+
tokio::select! {
835+
_ = stop_sync.changed() => {
836+
return;
837+
}
838+
_ = interval.tick() => {
839+
let confirmables = vec![
840+
&*sync_cman as &(dyn Confirm + Sync + Send),
841+
&*sync_cmon as &(dyn Confirm + Sync + Send),
842+
];
843+
match tx_sync.sync(confirmables).await {
844+
Ok(()) => log_trace!(
845+
sync_logger,
846+
"Background sync of Lightning wallet finished in {}ms.",
847+
now.elapsed().as_millis()
848+
),
849+
Err(e) => {
850+
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
851+
}
852+
}
853+
}
854+
}
855+
}
856+
});
857+
773858
if self.gossip_source.is_rgs() {
774859
let gossip_source = Arc::clone(&self.gossip_source);
775860
let gossip_sync_store = Arc::clone(&self.kv_store);
@@ -787,7 +872,7 @@ impl Node {
787872
let now = Instant::now();
788873
match gossip_source.update_rgs_snapshot().await {
789874
Ok(updated_timestamp) => {
790-
log_info!(
875+
log_trace!(
791876
gossip_sync_logger,
792877
"Background sync of RGS gossip data finished in {}ms.",
793878
now.elapsed().as_millis()
@@ -811,37 +896,6 @@ impl Node {
811896
});
812897
}
813898

814-
let sync_logger = Arc::clone(&self.logger);
815-
let mut stop_sync = self.stop_receiver.clone();
816-
runtime.spawn(async move {
817-
let mut interval = tokio::time::interval(Duration::from_secs(10));
818-
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
819-
loop {
820-
let now = Instant::now();
821-
tokio::select! {
822-
_ = stop_sync.changed() => {
823-
return;
824-
}
825-
_ = interval.tick() => {
826-
let confirmables = vec![
827-
&*sync_cman as &(dyn Confirm + Sync + Send),
828-
&*sync_cmon as &(dyn Confirm + Sync + Send),
829-
];
830-
match tx_sync.sync(confirmables).await {
831-
Ok(()) => log_info!(
832-
sync_logger,
833-
"Background sync of Lightning wallet finished in {}ms.",
834-
now.elapsed().as_millis()
835-
),
836-
Err(e) => {
837-
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
838-
}
839-
}
840-
}
841-
}
842-
}
843-
});
844-
845899
if let Some(listening_address) = &self.config.listening_address {
846900
// Setup networking
847901
let peer_manager_connection_handler = Arc::clone(&self.peer_manager);
@@ -975,6 +1029,18 @@ impl Node {
9751029
}
9761030
});
9771031

1032+
let event_handler = Arc::new(EventHandler::new(
1033+
Arc::clone(&self.wallet),
1034+
Arc::clone(&self.event_queue),
1035+
Arc::clone(&self.channel_manager),
1036+
Arc::clone(&self.network_graph),
1037+
Arc::clone(&self.keys_manager),
1038+
Arc::clone(&self.payment_store),
1039+
Arc::clone(&self.runtime),
1040+
Arc::clone(&self.logger),
1041+
Arc::clone(&self.config),
1042+
));
1043+
9781044
// Setup background processing
9791045
let background_persister = Arc::clone(&self.kv_store);
9801046
let background_event_handler = Arc::clone(&event_handler);

src/test/functional_tests.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,10 @@ fn onchain_spend_receive() {
375375

376376
#[test]
377377
fn sign_verify_msg() {
378-
let (_, electrsd) = setup_bitcoind_and_electrsd();
378+
let (_bitcoind, electrsd) = setup_bitcoind_and_electrsd();
379379
let esplora_url = electrsd.esplora_url.as_ref().unwrap();
380-
let node = Builder::from_config(random_config(esplora_url)).build();
380+
let config = random_config(esplora_url);
381+
let node = Builder::from_config(config).build();
381382

382383
node.start().unwrap();
383384

0 commit comments

Comments
 (0)