Skip to content

Commit 461b8c4

Browse files
authored
Merge pull request #93 from tnull/2023-04-broadcast-node-announcments
Regularly broadcast node announcements
2 parents 8ba0604 + d86aa1a commit 461b8c4

File tree

3 files changed

+120
-1
lines changed

3 files changed

+120
-1
lines changed

src/io/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ pub(crate) const PAYMENT_INFO_PERSISTENCE_NAMESPACE: &str = "payments";
3030
pub(crate) const LATEST_RGS_SYNC_TIMESTAMP_NAMESPACE: &str = "";
3131
pub(crate) const LATEST_RGS_SYNC_TIMESTAMP_KEY: &str = "latest_rgs_sync_timestamp";
3232

33+
/// The last time we broadcast a node announcement will be persisted under this key.
34+
pub(crate) const LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE: &str = "";
35+
pub(crate) const LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY: &str = "latest_node_ann_bcast_timestamp";
36+
3337
/// Provides an interface that allows to store and retrieve persisted values that are associated
3438
/// with given keys.
3539
///

src/io/utils.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,60 @@ where
228228
Error::PersistenceFailed
229229
})
230230
}
231+
232+
pub(crate) fn read_latest_node_ann_bcast_timestamp<K: Deref>(
233+
kv_store: K,
234+
) -> Result<u64, std::io::Error>
235+
where
236+
K::Target: KVStore,
237+
{
238+
let mut reader = kv_store
239+
.read(LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE, LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY)?;
240+
u64::read(&mut reader).map_err(|_| {
241+
std::io::Error::new(
242+
std::io::ErrorKind::InvalidData,
243+
"Failed to deserialize latest node announcment broadcast timestamp",
244+
)
245+
})
246+
}
247+
248+
pub(crate) fn write_latest_node_ann_bcast_timestamp<K: Deref, L: Deref>(
249+
updated_timestamp: u64, kv_store: K, logger: L,
250+
) -> Result<(), Error>
251+
where
252+
K::Target: KVStore,
253+
L::Target: Logger,
254+
{
255+
let mut writer = kv_store
256+
.write(LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE, LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY)
257+
.map_err(|e| {
258+
log_error!(
259+
logger,
260+
"Getting writer for key {}/{} failed due to: {}",
261+
LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE,
262+
LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY,
263+
e
264+
);
265+
Error::PersistenceFailed
266+
})?;
267+
updated_timestamp.write(&mut writer).map_err(|e| {
268+
log_error!(
269+
logger,
270+
"Writing data to key {}/{} failed due to: {}",
271+
LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE,
272+
LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY,
273+
e
274+
);
275+
Error::PersistenceFailed
276+
})?;
277+
writer.commit().map_err(|e| {
278+
log_error!(
279+
logger,
280+
"Committing data to key {}/{} failed due to: {}",
281+
LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE,
282+
LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY,
283+
e
284+
);
285+
Error::PersistenceFailed
286+
})
287+
}

src/lib.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,15 @@ const BDK_CLIENT_CONCURRENCY: u8 = 8;
169169
// The timeout after which we abandon retrying failed payments.
170170
const LDK_PAYMENT_RETRY_TIMEOUT: Duration = Duration::from_secs(10);
171171

172-
// The time in between peer reconnection attempts.
172+
// The time in-between peer reconnection attempts.
173173
const PEER_RECONNECTION_INTERVAL: Duration = Duration::from_secs(10);
174174

175175
// The time in-between RGS sync attempts.
176176
const RGS_SYNC_INTERVAL: Duration = Duration::from_secs(60 * 60);
177177

178+
// The time in-between node announcement broadcast attempts.
179+
const NODE_ANN_BCAST_INTERVAL: Duration = Duration::from_secs(60 * 60);
180+
178181
// The length in bytes of our wallets' keys seed.
179182
const WALLET_KEYS_SEED_LEN: usize = 64;
180183

@@ -870,6 +873,7 @@ impl Node {
870873
let mut stop_connect = self.stop_receiver.clone();
871874
runtime.spawn(async move {
872875
let mut interval = tokio::time::interval(PEER_RECONNECTION_INTERVAL);
876+
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
873877
loop {
874878
tokio::select! {
875879
_ = stop_connect.changed() => {
@@ -902,6 +906,60 @@ impl Node {
902906
}
903907
});
904908

909+
// Regularly broadcast node announcements.
910+
let bcast_cm = Arc::clone(&self.channel_manager);
911+
let bcast_pm = Arc::clone(&self.peer_manager);
912+
let bcast_config = Arc::clone(&self.config);
913+
let bcast_store = Arc::clone(&self.kv_store);
914+
let bcast_logger = Arc::clone(&self.logger);
915+
let mut stop_bcast = self.stop_receiver.clone();
916+
runtime.spawn(async move {
917+
// We check every 30 secs whether our last broadcast is NODE_ANN_BCAST_INTERVAL away.
918+
let mut interval = tokio::time::interval(Duration::from_secs(30));
919+
loop {
920+
tokio::select! {
921+
_ = stop_bcast.changed() => {
922+
return;
923+
}
924+
_ = interval.tick() => {
925+
let skip_broadcast = match io::utils::read_latest_node_ann_bcast_timestamp(Arc::clone(&bcast_store)) {
926+
Ok(latest_bcast_time_secs) => {
927+
// Skip if the time hasn't elapsed yet.
928+
let next_bcast_unix_time = SystemTime::UNIX_EPOCH + Duration::from_secs(latest_bcast_time_secs) + NODE_ANN_BCAST_INTERVAL;
929+
next_bcast_unix_time.elapsed().is_err()
930+
}
931+
Err(_) => {
932+
// Don't skip if we haven't broadcasted before.
933+
false
934+
}
935+
};
936+
937+
if skip_broadcast {
938+
continue;
939+
}
940+
941+
if bcast_cm.list_channels().iter().any(|chan| chan.is_public) {
942+
// Skip if we don't have any public channels.
943+
continue;
944+
}
945+
946+
if bcast_pm.get_peer_node_ids().is_empty() {
947+
// Skip if we don't have any connected peers to gossip to.
948+
continue;
949+
}
950+
951+
let addresses =
952+
bcast_config.listening_address.iter().cloned().map(|a| a.0).collect();
953+
bcast_pm.broadcast_node_announcement([0; 3], [0; 32], addresses);
954+
955+
let unix_time_secs = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
956+
io::utils::write_latest_node_ann_bcast_timestamp(unix_time_secs, Arc::clone(&bcast_store), Arc::clone(&bcast_logger))
957+
.expect("Persistence failed");
958+
}
959+
}
960+
}
961+
});
962+
905963
// Setup background processing
906964
let background_persister = Arc::clone(&self.kv_store);
907965
let background_event_handler = Arc::clone(&event_handler);

0 commit comments

Comments
 (0)