Skip to content

Commit 82a9d32

Browse files
committed
Persist latest_node_ann_broadcast_timestamp
We remember when we last broadcasted a node announcement and only re-announce if sufficient time has passed, we have at least one public channel, and we have some connected peers to gossip to.
1 parent f6eb56a commit 82a9d32

File tree

3 files changed

+96
-13
lines changed

3 files changed

+96
-13
lines changed

src/io/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ pub(crate) const PEER_INFO_PERSISTENCE_KEY: &str = "peers";
2626
/// The payment information will be persisted under this prefix.
2727
pub(crate) const PAYMENT_INFO_PERSISTENCE_NAMESPACE: &str = "payments";
2828

29+
/// The last time we broadcast a node announcement will be persisted under this key.
30+
pub(crate) const LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE: &str = "";
31+
pub(crate) const LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY: &str = "latest_node_ann_bcast_timestamp";
32+
2933
/// Provides an interface that allows to store and retrieve persisted values that are associated
3034
/// with given keys.
3135
///

src/io/utils.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::*;
2-
use crate::WALLET_KEYS_SEED_LEN;
2+
use crate::{Error, WALLET_KEYS_SEED_LEN};
33

4+
use crate::logger::log_error;
45
use crate::peer_store::PeerStore;
56
use crate::{EventQueue, PaymentDetails};
67

@@ -9,7 +10,7 @@ use lightning::chain::keysinterface::{EntropySource, SignerProvider};
910
use lightning::routing::gossip::NetworkGraph;
1011
use lightning::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringParameters};
1112
use lightning::util::logger::Logger;
12-
use lightning::util::ser::{Readable, ReadableArgs};
13+
use lightning::util::ser::{Readable, ReadableArgs, Writeable};
1314

1415
use bitcoin::hash_types::{BlockHash, Txid};
1516
use bitcoin::hashes::hex::FromHex;
@@ -172,3 +173,60 @@ where
172173
}
173174
Ok(res)
174175
}
176+
177+
pub(crate) fn read_latest_node_ann_bcast_timestamp<K: Deref>(
178+
kv_store: K,
179+
) -> Result<u64, std::io::Error>
180+
where
181+
K::Target: KVStore,
182+
{
183+
let mut reader = kv_store
184+
.read(LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE, LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY)?;
185+
u64::read(&mut reader).map_err(|_| {
186+
std::io::Error::new(
187+
std::io::ErrorKind::InvalidData,
188+
"Failed to deserialize latest node announcment broadcast timestamp",
189+
)
190+
})
191+
}
192+
193+
pub(crate) fn write_latest_node_ann_bcast_timestamp<K: Deref, L: Deref>(
194+
updated_timestamp: u64, kv_store: K, logger: L,
195+
) -> Result<(), Error>
196+
where
197+
K::Target: KVStore,
198+
L::Target: Logger,
199+
{
200+
let mut writer = kv_store
201+
.write(LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE, NETWORK_GRAPH_PERSISTENCE_KEY)
202+
.map_err(|e| {
203+
log_error!(
204+
logger,
205+
"Getting writer for key {}/{} failed due to: {}",
206+
LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE,
207+
LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY,
208+
e
209+
);
210+
Error::PersistenceFailed
211+
})?;
212+
updated_timestamp.write(&mut writer).map_err(|e| {
213+
log_error!(
214+
logger,
215+
"Writing data to key {}/{} failed due to: {}",
216+
LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE,
217+
LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY,
218+
e
219+
);
220+
Error::PersistenceFailed
221+
})?;
222+
writer.commit().map_err(|e| {
223+
log_error!(
224+
logger,
225+
"Committing data to key {}/{} failed due to: {}",
226+
LATEST_NODE_ANN_BCAST_TIMSTAMP_NAMESPACE,
227+
LATEST_NODE_ANN_BCAST_TIMSTAMP_KEY,
228+
e
229+
);
230+
Error::PersistenceFailed
231+
})
232+
}

src/lib.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -802,30 +802,51 @@ impl Node {
802802
let bcast_cm = Arc::clone(&self.channel_manager);
803803
let bcast_pm = Arc::clone(&self.peer_manager);
804804
let bcast_config = Arc::clone(&self.config);
805+
let bcast_store = Arc::clone(&self.kv_store);
806+
let bcast_logger = Arc::clone(&self.logger);
805807
let mut stop_bcast = self.stop_receiver.clone();
806808
runtime.spawn(async move {
807-
let mut interval = tokio::time::interval(NODE_ANN_BCAST_INTERVAL);
809+
// We check every 30 secs whether our last broadcast is NODE_ANN_BCAST_INTERVAL away.
810+
let mut interval = tokio::time::interval(Duration::from_secs(1));
808811
loop {
809812
tokio::select! {
810813
_ = stop_bcast.changed() => {
811814
return;
812815
}
813-
_ = interval.tick(), if bcast_cm.list_channels().iter().any(|chan| chan.is_public) => {
814-
while bcast_pm.get_peer_node_ids().is_empty() {
815-
// Sleep a bit and retry if we don't have any peers yet.
816-
tokio::time::sleep(Duration::from_secs(5)).await;
817-
818-
// Check back if we need to stop.
819-
match stop_bcast.has_changed() {
820-
Ok(false) => {},
821-
Ok(true) => return,
822-
Err(_) => return,
816+
_ = interval.tick() => {
817+
let skip_broadcast = match io::utils::read_latest_node_ann_bcast_timestamp(Arc::clone(&bcast_store)) {
818+
Ok(last_bcast_time_secs) => {
819+
// Skip if the time hasn't elapsed yet.
820+
let next_bcast_unix_time = SystemTime::UNIX_EPOCH + Duration::from_secs(last_bcast_time_secs) + NODE_ANN_BCAST_INTERVAL;
821+
next_bcast_unix_time.elapsed().is_err()
822+
}
823+
Err(_) => {
824+
// Don't skip if we haven't broadcasted before.
825+
false
823826
}
827+
};
828+
829+
if skip_broadcast {
830+
continue;
831+
}
832+
833+
if bcast_cm.list_channels().iter().any(|chan| chan.is_public) {
834+
// Skip if we don't have any public channels.
835+
continue;
836+
}
837+
838+
if bcast_pm.get_peer_node_ids().is_empty() {
839+
// Skip if we don't have any connected peers to gossip to.
840+
continue;
824841
}
825842

826843
let addresses =
827844
bcast_config.listening_address.iter().cloned().map(|a| a.0).collect();
828845
bcast_pm.broadcast_node_announcement([0; 3], [0; 32], addresses);
846+
847+
let unix_time_secs = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
848+
io::utils::write_latest_node_ann_bcast_timestamp(unix_time_secs, Arc::clone(&bcast_store), Arc::clone(&bcast_logger))
849+
.expect("Persistence failed");
829850
}
830851
}
831852
}

0 commit comments

Comments
 (0)