Skip to content

Commit 1bd244b

Browse files
committed
Use the generation time, not last seen time, for update timestamps
When we write an update, we have to include a timestamp that represents both the the time that the client will use to fetch the next diff and the timestamp used as a reference point when adding updates to the network graph (the client actually uses the included timestamp minus two weeks). Because of the second use, updates were being generated with the highest timestmap of all included updates, rounded down to the nearest update-interval multiple (because of the first use). In practice, because we expect to see many updates in any hour window, this meant we were really calculating the generation reference timestamp in a very indirect way. Here we simply change to using the reference timestamp directly. This updates regtest results when generating an initial sync against an empty graph to include a real timestamp, rather than 0, though this shouldn't impact clients' correctness. Fixes #95
1 parent 8493c61 commit 1bd244b

File tree

3 files changed

+10
-17
lines changed

3 files changed

+10
-17
lines changed

src/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ async fn calculate_delta<L: Deref + Clone>(network_graph: Arc<NetworkGraph<L>>,
203203
serialization::serialize_delta_set(delta_set, node_delta_set, last_sync_timestamp)
204204
}
205205

206-
fn serialize_delta<L: Deref + Clone>(serialization_details: &SerializationSet, serialization_version: u8, logger: L) -> SerializedResponse where L::Target: Logger {
206+
fn serialize_delta<L: Deref + Clone>(
207+
serialization_details: &SerializationSet, serialization_time: u32, serialization_version: u8, logger: L,
208+
) -> SerializedResponse where L::Target: Logger {
207209
let mut output: Vec<u8> = vec![];
208210
let snapshot_interval = config::snapshot_generation_interval();
209211

@@ -277,11 +279,9 @@ fn serialize_delta<L: Deref + Clone>(serialization_details: &SerializationSet, s
277279

278280
// always write the chain hash
279281
serialization_details.chain_hash.write(&mut prefixed_output).unwrap();
280-
// always write the latest seen timestamp
281-
let latest_seen_timestamp = serialization_details.latest_seen;
282-
let overflow_seconds = latest_seen_timestamp % snapshot_interval;
283-
let serialized_seen_timestamp = latest_seen_timestamp.saturating_sub(overflow_seconds);
284-
serialized_seen_timestamp.write(&mut prefixed_output).unwrap();
282+
// always write the time we're generating this object
283+
assert_eq!(serialization_time % snapshot_interval, 0);
284+
serialization_time.write(&mut prefixed_output).unwrap();
285285

286286
if serialization_version >= 2 { // serialize the most common node features
287287
for mutated_node_id in serialization_details.node_mutations.keys() {
@@ -389,7 +389,7 @@ fn serialize_delta<L: Deref + Clone>(serialization_details: &SerializationSet, s
389389
prefixed_output.append(&mut output);
390390

391391
log_info!(logger, "duplicated node ids: {}", duplicate_node_ids);
392-
log_info!(logger, "latest seen timestamp: {:?}", serialization_details.latest_seen);
392+
log_info!(logger, "generated at: {}", serialization_time);
393393

394394
SerializedResponse {
395395
data: prefixed_output,

src/serialization.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::cmp::max;
21
use std::collections::HashMap;
32
use std::time::{SystemTime, UNIX_EPOCH};
43

@@ -16,7 +15,6 @@ pub(super) struct SerializationSet {
1615
pub(super) full_update_defaults: DefaultUpdateValues,
1716
pub(super) node_announcement_feature_defaults: Vec<NodeFeatures>,
1817
pub(super) node_mutations: NodeDeltaSet,
19-
pub(super) latest_seen: u32,
2018
pub(super) chain_hash: ChainHash,
2119
}
2220

@@ -130,7 +128,6 @@ pub(super) fn serialize_delta_set(channel_delta_set: DeltaSet, node_delta_set: N
130128
node_announcement_feature_defaults: vec![],
131129
node_mutations: Default::default(),
132130
chain_hash: ChainHash::using_genesis_block(config::network()),
133-
latest_seen: 0,
134131
};
135132

136133
let mut full_update_histograms = FullUpdateValueHistograms {
@@ -165,7 +162,6 @@ pub(super) fn serialize_delta_set(channel_delta_set: DeltaSet, node_delta_set: N
165162
};
166163
let send_announcement = is_new_announcement || is_newly_included_announcement;
167164
if send_announcement {
168-
serialization_set.latest_seen = max(serialization_set.latest_seen, current_announcement_seen);
169165
serialization_set.announcements.push(channel_delta.announcement.unwrap().announcement);
170166
}
171167

@@ -178,10 +174,6 @@ pub(super) fn serialize_delta_set(channel_delta_set: DeltaSet, node_delta_set: N
178174
let latest_update = latest_update_delta.update;
179175
assert_eq!(latest_update.short_channel_id, scid, "Update in DB had wrong SCID column");
180176

181-
// the returned seen timestamp should be the latest of all the returned
182-
// announcements and latest updates
183-
serialization_set.latest_seen = max(serialization_set.latest_seen, latest_update_delta.seen);
184-
185177
if let Some(update_delta) = updates.last_update_before_seen {
186178
let mutated_properties = updates.mutated_properties;
187179
if send_announcement || mutated_properties.len() == 5 || update_delta.seen <= non_incremental_previous_update_threshold_timestamp {

src/snapshot.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ impl<L: Deref + Clone> Snapshotter<L> where L::Target: Logger {
7373
let snapshot_generation_time = SystemTime::now();
7474
let snapshot_generation_timestamp = snapshot_generation_time.duration_since(UNIX_EPOCH).unwrap().as_secs();
7575
let reference_timestamp = Self::round_down_to_nearest_multiple(snapshot_generation_timestamp, snapshot_interval);
76+
let serialized_timestamp: u32 = reference_timestamp.try_into().unwrap();
7677
log_info!(self.logger, "Capturing snapshots at {} for: {}", snapshot_generation_timestamp, reference_timestamp);
7778

7879
// 2. sleep until the next round interval
@@ -121,8 +122,8 @@ impl<L: Deref + Clone> Snapshotter<L> where L::Target: Logger {
121122
log_info!(self.logger, "Calculating {}-second snapshot", current_scope);
122123
// calculate the snapshot
123124
let delta = super::calculate_delta(network_graph_clone.clone(), current_last_sync_timestamp.clone() as u32, Some(reference_timestamp), self.logger.clone()).await;
124-
let snapshot_v1 = super::serialize_delta(&delta, 1, self.logger.clone());
125-
let snapshot_v2 = super::serialize_delta(&delta, 2, self.logger.clone());
125+
let snapshot_v1 = super::serialize_delta(&delta, serialized_timestamp, 1, self.logger.clone());
126+
let snapshot_v2 = super::serialize_delta(&delta, serialized_timestamp, 2, self.logger.clone());
126127

127128
// persist the snapshot and update the symlink
128129
let snapshot_filename = format!("snapshot__calculated-at:{}__range:{}-scope__previous-sync:{}.lngossip", reference_timestamp, current_scope, current_last_sync_timestamp);

0 commit comments

Comments
 (0)