Skip to content

Commit 74c9ea2

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 90ad5d1 commit 74c9ea2

File tree

2 files changed

+118
-50
lines changed

2 files changed

+118
-50
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
};
1113

1214
interface Builder {

src/lib.rs

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

116-
use logger::{log_error, log_info, FilesystemLogger, Logger};
116+
use logger::{log_error, log_info, log_trace, FilesystemLogger, Logger};
117117

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

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

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

@@ -194,6 +200,14 @@ pub struct Config {
194200
pub listening_address: Option<NetAddress>,
195201
/// The default CLTV expiry delta to be used for payments.
196202
pub default_cltv_expiry_delta: u32,
203+
/// The time in-between background sync attempts of the onchain wallet, in seconds.
204+
///
205+
/// **Note:** A minimum of 10 seconds is always enforced.
206+
pub onchain_wallet_sync_interval_secs: u64,
207+
/// The time in-between background sync attempts of the LDK wallet, in seconds.
208+
///
209+
/// **Note:** A minimum of 10 seconds is always enforced.
210+
pub wallet_sync_interval_secs: u64,
197211
}
198212

199213
impl Default for Config {
@@ -204,6 +218,8 @@ impl Default for Config {
204218
network: Network::Regtest,
205219
listening_address: Some("0.0.0.0:9735".parse().unwrap()),
206220
default_cltv_expiry_delta: 144,
221+
onchain_wallet_sync_interval_secs: DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS,
222+
wallet_sync_interval_secs: DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS,
207223
}
208224
}
209225
}
@@ -702,31 +718,38 @@ impl Node {
702718

703719
let runtime = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();
704720

705-
let event_handler = Arc::new(EventHandler::new(
706-
Arc::clone(&self.wallet),
707-
Arc::clone(&self.event_queue),
708-
Arc::clone(&self.channel_manager),
709-
Arc::clone(&self.network_graph),
710-
Arc::clone(&self.keys_manager),
711-
Arc::clone(&self.payment_store),
712-
Arc::clone(&self.runtime),
713-
Arc::clone(&self.logger),
714-
Arc::clone(&self.config),
715-
));
716-
717721
// Setup wallet sync
718722
let wallet = Arc::clone(&self.wallet);
719-
let tx_sync = Arc::clone(&self.tx_sync);
720-
let sync_cman = Arc::clone(&self.channel_manager);
721-
let sync_cmon = Arc::clone(&self.chain_monitor);
722723
let sync_logger = Arc::clone(&self.logger);
723724
let mut stop_sync = self.stop_receiver.clone();
724725

726+
runtime.block_on(async move {
727+
let now = Instant::now();
728+
match wallet.sync().await {
729+
Ok(()) => {
730+
log_info!(
731+
sync_logger,
732+
"Initial sync of on-chain wallet finished in {}ms.",
733+
now.elapsed().as_millis()
734+
);
735+
Ok(())
736+
}
737+
Err(e) => {
738+
log_error!(sync_logger, "Intial sync of on-chain wallet failed: {}", e,);
739+
Err(e)
740+
}
741+
}
742+
})?;
743+
744+
let sync_logger = Arc::clone(&self.logger);
745+
let wallet = Arc::clone(&self.wallet);
725746
std::thread::spawn(move || {
726747
tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(
727748
async move {
728-
let mut interval = tokio::time::interval(Duration::from_secs(30));
749+
let interval_secs = DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS.max(10);
750+
let mut interval = tokio::time::interval(Duration::from_secs(interval_secs));
729751
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
752+
interval.reset();
730753
loop {
731754
let now = Instant::now();
732755
tokio::select! {
@@ -735,7 +758,7 @@ impl Node {
735758
}
736759
_ = interval.tick() => {
737760
match wallet.sync().await {
738-
Ok(()) => log_info!(
761+
Ok(()) => log_trace!(
739762
sync_logger,
740763
"Background sync of on-chain wallet finished in {}ms.",
741764
now.elapsed().as_millis()
@@ -755,6 +778,68 @@ impl Node {
755778
);
756779
});
757780

781+
let tx_sync = Arc::clone(&self.tx_sync);
782+
let sync_cman = Arc::clone(&self.channel_manager);
783+
let sync_cmon = Arc::clone(&self.chain_monitor);
784+
let sync_logger = Arc::clone(&self.logger);
785+
runtime.block_on(async move {
786+
let now = Instant::now();
787+
let confirmables = vec![
788+
&*sync_cman as &(dyn Confirm + Sync + Send),
789+
&*sync_cmon as &(dyn Confirm + Sync + Send),
790+
];
791+
match tx_sync.sync(confirmables).await {
792+
Ok(()) => {
793+
log_info!(
794+
sync_logger,
795+
"Initial sync of Lightning wallet finished in {}ms.",
796+
now.elapsed().as_millis()
797+
);
798+
Ok(())
799+
}
800+
Err(e) => {
801+
log_error!(sync_logger, "Initial sync of Lightning wallet failed: {}", e);
802+
Err(e)
803+
}
804+
}
805+
})?;
806+
807+
let tx_sync = Arc::clone(&self.tx_sync);
808+
let sync_cman = Arc::clone(&self.channel_manager);
809+
let sync_cmon = Arc::clone(&self.chain_monitor);
810+
let sync_logger = Arc::clone(&self.logger);
811+
let mut stop_sync = self.stop_receiver.clone();
812+
runtime.spawn(async move {
813+
let interval_secs = DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS.max(10);
814+
let mut interval = tokio::time::interval(Duration::from_secs(interval_secs));
815+
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
816+
interval.reset();
817+
loop {
818+
let now = Instant::now();
819+
tokio::select! {
820+
_ = stop_sync.changed() => {
821+
return;
822+
}
823+
_ = interval.tick() => {
824+
let confirmables = vec![
825+
&*sync_cman as &(dyn Confirm + Sync + Send),
826+
&*sync_cmon as &(dyn Confirm + Sync + Send),
827+
];
828+
match tx_sync.sync(confirmables).await {
829+
Ok(()) => log_trace!(
830+
sync_logger,
831+
"Background sync of Lightning wallet finished in {}ms.",
832+
now.elapsed().as_millis()
833+
),
834+
Err(e) => {
835+
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
836+
}
837+
}
838+
}
839+
}
840+
}
841+
});
842+
758843
if self.gossip_source.is_rgs() {
759844
let gossip_source = Arc::clone(&self.gossip_source);
760845
let gossip_sync_store = Arc::clone(&self.kv_store);
@@ -772,7 +857,7 @@ impl Node {
772857
let now = Instant::now();
773858
match gossip_source.update_rgs_snapshot().await {
774859
Ok(updated_timestamp) => {
775-
log_info!(
860+
log_trace!(
776861
gossip_sync_logger,
777862
"Background sync of RGS gossip data finished in {}ms.",
778863
now.elapsed().as_millis()
@@ -796,37 +881,6 @@ impl Node {
796881
});
797882
}
798883

799-
let sync_logger = Arc::clone(&self.logger);
800-
let mut stop_sync = self.stop_receiver.clone();
801-
runtime.spawn(async move {
802-
let mut interval = tokio::time::interval(Duration::from_secs(10));
803-
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
804-
loop {
805-
let now = Instant::now();
806-
tokio::select! {
807-
_ = stop_sync.changed() => {
808-
return;
809-
}
810-
_ = interval.tick() => {
811-
let confirmables = vec![
812-
&*sync_cman as &(dyn Confirm + Sync + Send),
813-
&*sync_cmon as &(dyn Confirm + Sync + Send),
814-
];
815-
match tx_sync.sync(confirmables).await {
816-
Ok(()) => log_info!(
817-
sync_logger,
818-
"Background sync of Lightning wallet finished in {}ms.",
819-
now.elapsed().as_millis()
820-
),
821-
Err(e) => {
822-
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
823-
}
824-
}
825-
}
826-
}
827-
}
828-
});
829-
830884
if let Some(listening_address) = &self.config.listening_address {
831885
// Setup networking
832886
let peer_manager_connection_handler = Arc::clone(&self.peer_manager);
@@ -960,6 +1014,18 @@ impl Node {
9601014
}
9611015
});
9621016

1017+
let event_handler = Arc::new(EventHandler::new(
1018+
Arc::clone(&self.wallet),
1019+
Arc::clone(&self.event_queue),
1020+
Arc::clone(&self.channel_manager),
1021+
Arc::clone(&self.network_graph),
1022+
Arc::clone(&self.keys_manager),
1023+
Arc::clone(&self.payment_store),
1024+
Arc::clone(&self.runtime),
1025+
Arc::clone(&self.logger),
1026+
Arc::clone(&self.config),
1027+
));
1028+
9631029
// Setup background processing
9641030
let background_persister = Arc::clone(&self.kv_store);
9651031
let background_event_handler = Arc::clone(&event_handler);

0 commit comments

Comments
 (0)