Skip to content
This repository was archived by the owner on Oct 9, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,16 @@ impl<L: Deref + Clone> Snapshotter<L> where L::Target: Logger {
fs::write(&dummy_snapshot_path_v1, dummy_snapshot_v1).unwrap();
fs::write(&dummy_snapshot_path_v2, dummy_snapshot_v2).unwrap();

let dummy_symlink_path = format!("{}/{}.bin", pending_symlink_directory, reference_timestamp);
let relative_dummy_snapshot_path = format!("{}/{}", relative_symlink_to_snapshot_path, dummy_filename);
log_info!(self.logger, "Symlinking dummy: {} -> {}", dummy_symlink_path, relative_dummy_snapshot_path);
symlink(&relative_dummy_snapshot_path, &dummy_symlink_path).unwrap();
// The timestamp written into every snapshot header must exist for
// both protocol versions. Real deltas already do this in the loop
// below. This symlink used to be v1-only, so a v2 client that
// stored `reference_timestamp` got HTTP 404.
for (suffix, path_to_root) in suffixes {
let dummy_symlink_path = format!("{}{}/{}.bin", pending_symlink_directory, suffix, reference_timestamp);
let relative_dummy_snapshot_path = format!("{}{}{}/{}", path_to_root, relative_symlink_to_snapshot_path, suffix, dummy_filename);
log_info!(self.logger, "Symlinking dummy: {} -> {}", dummy_symlink_path, relative_dummy_snapshot_path);
symlink(&relative_dummy_snapshot_path, &dummy_symlink_path).unwrap();
}
}

// Number of intervals since Jan 1, 2022, a few months before RGS server was released.
Expand Down
20 changes: 20 additions & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,26 @@ async fn test_full_snapshot_persistence() {
// the update result must be a multiple of our snapshot granularity
assert_eq!(update_result % config::snapshot_generation_interval(), 0);

// v2 clients request this generation's reference timestamp next.
// That symlink used to be v1-only, so the follow-up sync was HTTP 404.
let v2_dir = std::env::current_dir().unwrap().join(&cache_path).join("symlinks/v2");
let reference_symlink = fs::read_dir(&v2_dir)
.unwrap()
.flatten()
.filter_map(|e| {
let ts = e.path().file_stem().and_then(|s| s.to_str()).and_then(|s| s.parse::<u32>().ok())?;
(ts != 0).then_some((ts, e.path()))
})
.max_by_key(|(ts, _)| *ts)
.unwrap()
.1;
let v2_empty = fs::read(&reference_symlink).unwrap();
let v2_graph = NetworkGraph::new(Network::Bitcoin, logger.clone());
let v2_rgs = RapidGossipSync::new(&v2_graph, logger.clone());
let applied = v2_rgs.update_network_graph(&v2_empty).unwrap();
assert_eq!(applied % config::snapshot_generation_interval(), 0);
assert!(v2_graph.read_only().channels().is_empty());

let readonly_graph = client_graph.read_only();
let channels = readonly_graph.channels();
let client_channel_count = channels.len();
Expand Down
Loading