Skip to content

Commit a5271ea

Browse files
committed
Use mock timestamps.
1 parent 84d2efb commit a5271ea

File tree

5 files changed

+144
-15
lines changed

5 files changed

+144
-15
lines changed

lightning-background-processor/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,3 @@ futures-util = { version = "0.3", default-features = false, features = ["async-a
2929
lightning = { version = "0.0.113", path = "../lightning", features = ["_test_utils"] }
3030
lightning-invoice = { version = "0.21.0", path = "../lightning-invoice" }
3131
lightning-persister = { version = "0.0.113", path = "../lightning-persister" }
32-
lightning-rapid-gossip-sync = { version = "0.0.113", path = "../lightning-rapid-gossip-sync", features = ["_test_utils"] }

lightning-background-processor/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,7 @@ mod tests {
13101310
0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
13111311
0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
13121312
];
1313-
nodes[0].rapid_gossip_sync.update_network_graph(&initialization_input[..]).unwrap();
1313+
nodes[0].rapid_gossip_sync.update_network_graph_no_std(&initialization_input[..], Some(1642291930)).unwrap();
13141314

13151315
// this should have added two channels
13161316
assert_eq!(network_graph.read_only().channels().len(), 3);

lightning-rapid-gossip-sync/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ Utility to process gossip routing data from Rapid Gossip Sync Server.
1010
"""
1111

1212
[features]
13-
_test_utils = []
1413
default = ["std"]
1514
no-std = ["lightning/no-std"]
1615
std = ["lightning/std"]

lightning-rapid-gossip-sync/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,22 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
126126
/// Update network graph from binary data.
127127
/// Returns the last sync timestamp to be used the next time rapid sync data is queried.
128128
///
129-
/// `network_graph`: network graph to be updated
130-
///
131129
/// `update_data`: `&[u8]` binary stream that comprises the update data
132130
pub fn update_network_graph(&self, update_data: &[u8]) -> Result<u32, GraphSyncError> {
133131
let mut read_cursor = io::Cursor::new(update_data);
134132
self.update_network_graph_from_byte_stream(&mut read_cursor)
135133
}
136134

135+
/// Update network graph from binary data.
136+
/// Returns the last sync timestamp to be used the next time rapid sync data is queried.
137+
///
138+
/// `update_data`: `&[u8]` binary stream that comprises the update data
139+
/// `current_time_unix`: `Option<u64>` optional current timestamp to verify data age
140+
pub fn update_network_graph_no_std(&self, update_data: &[u8], current_time_unix: Option<u64>) -> Result<u32, GraphSyncError> {
141+
let mut read_cursor = io::Cursor::new(update_data);
142+
self.update_network_graph_from_byte_stream_no_std(&mut read_cursor, current_time_unix)
143+
}
144+
137145
/// Gets a reference to the underlying [`NetworkGraph`] which was provided in
138146
/// [`RapidGossipSync::new`].
139147
///

lightning-rapid-gossip-sync/src/processing.rs

Lines changed: 133 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use lightning::io;
1616
use crate::error::GraphSyncError;
1717
use crate::RapidGossipSync;
1818

19-
#[cfg(all(feature = "std", not(test), not(feature = "_test_utils")))]
19+
#[cfg(all(feature = "std", not(test)))]
2020
use std::time::{SystemTime, UNIX_EPOCH};
2121

2222
#[cfg(not(feature = "std"))]
@@ -34,13 +34,28 @@ const MAX_INITIAL_NODE_ID_VECTOR_CAPACITY: u32 = 50_000;
3434

3535
/// We remove disallow gossip data that's more than two weeks old, per BOLT 7's
3636
/// suggestion.
37-
#[cfg(all(feature = "std", not(test), not(feature = "_test_utils")))]
3837
const STALE_RGS_UPDATE_AGE_LIMIT_SECS: u64 = 60 * 60 * 24 * 14;
3938

4039
impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L::Target: Logger {
4140
pub(crate) fn update_network_graph_from_byte_stream<R: io::Read>(
41+
&self,
42+
read_cursor: &mut R,
43+
) -> Result<u32, GraphSyncError> {
44+
#[allow(unused_mut)]
45+
let mut current_time_unix = None;
46+
#[cfg(all(feature = "std", not(test)))]
47+
{
48+
// Note that many tests rely on being able to set arbitrarily old timestamps, thus we
49+
// disable this check during tests!
50+
current_time_unix = Some(SystemTime::now().duration_since(UNIX_EPOCH).expect("Time must be > 1970").as_secs());
51+
}
52+
self.update_network_graph_from_byte_stream_no_std(read_cursor, current_time_unix)
53+
}
54+
55+
pub(crate) fn update_network_graph_from_byte_stream_no_std<R: io::Read>(
4256
&self,
4357
mut read_cursor: &mut R,
58+
current_time_unix: Option<u64>
4459
) -> Result<u32, GraphSyncError> {
4560
let mut prefix = [0u8; 4];
4661
read_cursor.read_exact(&mut prefix)?;
@@ -51,19 +66,17 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
5166

5267
let chain_hash: BlockHash = Readable::read(read_cursor)?;
5368
let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
54-
// backdate the applied timestamp by a week
55-
let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
5669

57-
#[cfg(all(feature = "std", not(test), not(feature = "_test_utils")))]
58-
{
59-
// Note that many tests rely on being able to set arbitrarily old timestamps, thus we
60-
// disable this check during tests!
61-
let time = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time must be > 1970").as_secs();
62-
if (latest_seen_timestamp as u64) < time - STALE_RGS_UPDATE_AGE_LIMIT_SECS {
70+
if let Some(time) = current_time_unix {
71+
println!("latest seen timestamp: {}", latest_seen_timestamp);
72+
if (latest_seen_timestamp as u64) < time.saturating_sub(STALE_RGS_UPDATE_AGE_LIMIT_SECS) {
6373
return Err(LightningError{err: "Rapid Gossip Sync data is more than two weeks old".to_owned(), action: ErrorAction::IgnoreError}.into());
6474
}
6575
}
6676

77+
// backdate the applied timestamp by a week
78+
let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
79+
6780
let node_id_count: u32 = Readable::read(read_cursor)?;
6881
let mut node_ids: Vec<PublicKey> = Vec::with_capacity(core::cmp::min(
6982
node_id_count,
@@ -233,6 +246,7 @@ mod tests {
233246
use lightning::util::test_utils::TestLogger;
234247

235248
use crate::error::GraphSyncError;
249+
use crate::processing::STALE_RGS_UPDATE_AGE_LIMIT_SECS;
236250
use crate::RapidGossipSync;
237251

238252
#[test]
@@ -544,6 +558,115 @@ mod tests {
544558
assert!(after.contains("783241506229452801"));
545559
}
546560

561+
#[test]
562+
fn full_update_succeeds_with_edge_timestamp_age() {
563+
const LATEST_SEEN_TIMESTAMP: u64 = 1642291930;
564+
let valid_input = vec![
565+
76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
566+
79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
567+
0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
568+
187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
569+
157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
570+
88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
571+
204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
572+
181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
573+
110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
574+
76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
575+
226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 4, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 3, 232,
576+
0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
577+
0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 0, 0, 0, 58, 85, 116, 216, 0, 29, 0,
578+
0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
579+
0, 0, 1,
580+
];
581+
582+
let block_hash = genesis_block(Network::Bitcoin).block_hash();
583+
let logger = TestLogger::new();
584+
let network_graph = NetworkGraph::new(block_hash, &logger);
585+
586+
assert_eq!(network_graph.read_only().channels().len(), 0);
587+
588+
let earliest_failing_time = LATEST_SEEN_TIMESTAMP + STALE_RGS_UPDATE_AGE_LIMIT_SECS;
589+
590+
let rapid_sync = RapidGossipSync::new(&network_graph);
591+
let update_result = rapid_sync.update_network_graph_no_std(&valid_input[..], Some(earliest_failing_time));
592+
assert!(update_result.is_ok());
593+
assert_eq!(network_graph.read_only().channels().len(), 2);
594+
}
595+
596+
#[test]
597+
fn full_update_succeeds_with_oldest_possible_timestamp() {
598+
let valid_input = vec![
599+
76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
600+
79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
601+
0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
602+
187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
603+
157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
604+
88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
605+
204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
606+
181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
607+
110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
608+
76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
609+
226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 4, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 3, 232,
610+
0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
611+
0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 0, 0, 0, 58, 85, 116, 216, 0, 29, 0,
612+
0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
613+
0, 0, 1,
614+
];
615+
616+
let block_hash = genesis_block(Network::Bitcoin).block_hash();
617+
let logger = TestLogger::new();
618+
let network_graph = NetworkGraph::new(block_hash, &logger);
619+
620+
assert_eq!(network_graph.read_only().channels().len(), 0);
621+
622+
let rapid_sync = RapidGossipSync::new(&network_graph);
623+
let update_result = rapid_sync.update_network_graph_no_std(&valid_input[..], Some(0));
624+
assert!(update_result.is_ok());
625+
assert_eq!(network_graph.read_only().channels().len(), 2);
626+
}
627+
628+
#[test]
629+
fn full_update_fails_with_old_timestamp() {
630+
const LATEST_SEEN_TIMESTAMP: u64 = 1642291930;
631+
let valid_input = vec![
632+
76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
633+
79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
634+
0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
635+
187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
636+
157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
637+
88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
638+
204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
639+
181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
640+
110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
641+
76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
642+
226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 4, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 3, 232,
643+
0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
644+
0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 0, 0, 0, 58, 85, 116, 216, 0, 29, 0,
645+
0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
646+
0, 0, 1,
647+
];
648+
649+
let block_hash = genesis_block(Network::Bitcoin).block_hash();
650+
let logger = TestLogger::new();
651+
let network_graph = NetworkGraph::new(block_hash, &logger);
652+
653+
assert_eq!(network_graph.read_only().channels().len(), 0);
654+
655+
let earliest_failing_time = LATEST_SEEN_TIMESTAMP + STALE_RGS_UPDATE_AGE_LIMIT_SECS + 1;
656+
657+
let rapid_sync = RapidGossipSync::new(&network_graph);
658+
let update_result = rapid_sync.update_network_graph_no_std(&valid_input[..], Some(earliest_failing_time));
659+
assert!(update_result.is_err());
660+
if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
661+
assert_eq!(
662+
lightning_error.err,
663+
"Rapid Gossip Sync data is more than two weeks old"
664+
);
665+
} else {
666+
panic!("Unexpected update result: {:?}", update_result)
667+
}
668+
}
669+
547670
#[test]
548671
pub fn update_fails_with_unknown_version() {
549672
let unknown_version_input = vec![

0 commit comments

Comments
 (0)