Throw error for RGS data that's more than two weeks old, fixing #1785
[rust-lightning] / lightning-rapid-gossip-sync / src / processing.rs
1 use core::cmp::max;
2 use core::ops::Deref;
3 use core::sync::atomic::Ordering;
4
5 use bitcoin::BlockHash;
6 use bitcoin::secp256k1::PublicKey;
7
8 use lightning::ln::msgs::{
9         DecodeError, ErrorAction, LightningError, UnsignedChannelUpdate,
10 };
11 use lightning::routing::gossip::NetworkGraph;
12 use lightning::util::logger::Logger;
13 use lightning::util::ser::{BigSize, Readable};
14 use lightning::io;
15
16 use crate::error::GraphSyncError;
17 use crate::RapidGossipSync;
18
19 #[cfg(all(feature = "std", not(test)))]
20 use std::time::{SystemTime, UNIX_EPOCH};
21
22 #[cfg(not(feature = "std"))]
23 use alloc::{vec::Vec, borrow::ToOwned};
24
25 /// The purpose of this prefix is to identify the serialization format, should other rapid gossip
26 /// sync formats arise in the future.
27 ///
28 /// The fourth byte is the protocol version in case our format gets updated.
29 const GOSSIP_PREFIX: [u8; 4] = [76, 68, 75, 1];
30
31 /// Maximum vector allocation capacity for distinct node IDs. This constraint is necessary to
32 /// avoid malicious updates being able to trigger excessive memory allocation.
33 const MAX_INITIAL_NODE_ID_VECTOR_CAPACITY: u32 = 50_000;
34
35 /// We disallow gossip data that's more than two weeks old, per BOLT 7's
36 /// suggestion.
37 const STALE_RGS_UPDATE_AGE_LIMIT_SECS: u64 = 60 * 60 * 24 * 14;
38
39 impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L::Target: Logger {
40         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>(
56                 &self,
57                 mut read_cursor: &mut R,
58                 current_time_unix: Option<u64>
59         ) -> Result<u32, GraphSyncError> {
60                 let mut prefix = [0u8; 4];
61                 read_cursor.read_exact(&mut prefix)?;
62
63                 if prefix != GOSSIP_PREFIX {
64                         return Err(DecodeError::UnknownVersion.into());
65                 }
66
67                 let chain_hash: BlockHash = Readable::read(read_cursor)?;
68                 let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
69
70                 if let Some(time) = current_time_unix {
71                         if (latest_seen_timestamp as u64) < time.saturating_sub(STALE_RGS_UPDATE_AGE_LIMIT_SECS) {
72                                 return Err(LightningError{err: "Rapid Gossip Sync data is more than two weeks old".to_owned(), action: ErrorAction::IgnoreError}.into());
73                         }
74                 }
75
76                 // backdate the applied timestamp by a week
77                 let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
78
79                 let node_id_count: u32 = Readable::read(read_cursor)?;
80                 let mut node_ids: Vec<PublicKey> = Vec::with_capacity(core::cmp::min(
81                         node_id_count,
82                         MAX_INITIAL_NODE_ID_VECTOR_CAPACITY,
83                 ) as usize);
84                 for _ in 0..node_id_count {
85                         let current_node_id = Readable::read(read_cursor)?;
86                         node_ids.push(current_node_id);
87                 }
88
89                 let network_graph = &self.network_graph;
90
91                 let mut previous_scid: u64 = 0;
92                 let announcement_count: u32 = Readable::read(read_cursor)?;
93                 for _ in 0..announcement_count {
94                         let features = Readable::read(read_cursor)?;
95
96                         // handle SCID
97                         let scid_delta: BigSize = Readable::read(read_cursor)?;
98                         let short_channel_id = previous_scid
99                                 .checked_add(scid_delta.0)
100                                 .ok_or(DecodeError::InvalidValue)?;
101                         previous_scid = short_channel_id;
102
103                         let node_id_1_index: BigSize = Readable::read(read_cursor)?;
104                         let node_id_2_index: BigSize = Readable::read(read_cursor)?;
105
106                         if max(node_id_1_index.0, node_id_2_index.0) >= node_id_count as u64 {
107                                 return Err(DecodeError::InvalidValue.into());
108                         };
109                         let node_id_1 = node_ids[node_id_1_index.0 as usize];
110                         let node_id_2 = node_ids[node_id_2_index.0 as usize];
111
112                         let announcement_result = network_graph.add_channel_from_partial_announcement(
113                                 short_channel_id,
114                                 backdated_timestamp as u64,
115                                 features,
116                                 node_id_1,
117                                 node_id_2,
118                         );
119                         if let Err(lightning_error) = announcement_result {
120                                 if let ErrorAction::IgnoreDuplicateGossip = lightning_error.action {
121                                         // everything is fine, just a duplicate channel announcement
122                                 } else {
123                                         return Err(lightning_error.into());
124                                 }
125                         }
126                 }
127
128                 previous_scid = 0; // updates start at a new scid
129
130                 let update_count: u32 = Readable::read(read_cursor)?;
131                 if update_count == 0 {
132                         return Ok(latest_seen_timestamp);
133                 }
134
135                 // obtain default values for non-incremental updates
136                 let default_cltv_expiry_delta: u16 = Readable::read(&mut read_cursor)?;
137                 let default_htlc_minimum_msat: u64 = Readable::read(&mut read_cursor)?;
138                 let default_fee_base_msat: u32 = Readable::read(&mut read_cursor)?;
139                 let default_fee_proportional_millionths: u32 = Readable::read(&mut read_cursor)?;
140                 let default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?;
141
142                 for _ in 0..update_count {
143                         let scid_delta: BigSize = Readable::read(read_cursor)?;
144                         let short_channel_id = previous_scid
145                                 .checked_add(scid_delta.0)
146                                 .ok_or(DecodeError::InvalidValue)?;
147                         previous_scid = short_channel_id;
148
149                         let channel_flags: u8 = Readable::read(read_cursor)?;
150
151                         // flags are always sent in full, and hence always need updating
152                         let standard_channel_flags = channel_flags & 0b_0000_0011;
153
154                         let mut synthetic_update = UnsignedChannelUpdate {
155                                 chain_hash,
156                                 short_channel_id,
157                                 timestamp: backdated_timestamp,
158                                 flags: standard_channel_flags,
159                                 cltv_expiry_delta: default_cltv_expiry_delta,
160                                 htlc_minimum_msat: default_htlc_minimum_msat,
161                                 htlc_maximum_msat: default_htlc_maximum_msat,
162                                 fee_base_msat: default_fee_base_msat,
163                                 fee_proportional_millionths: default_fee_proportional_millionths,
164                                 excess_data: Vec::new(),
165                         };
166
167                         let mut skip_update_for_unknown_channel = false;
168
169                         if (channel_flags & 0b_1000_0000) != 0 {
170                                 // incremental update, field flags will indicate mutated values
171                                 let read_only_network_graph = network_graph.read_only();
172                                 if let Some(channel) = read_only_network_graph
173                                         .channels()
174                                         .get(&short_channel_id) {
175
176                                         let directional_info = channel
177                                                 .get_directional_info(channel_flags)
178                                                 .ok_or(LightningError {
179                                                         err: "Couldn't find previous directional data for update".to_owned(),
180                                                         action: ErrorAction::IgnoreError,
181                                                 })?;
182
183                                         synthetic_update.cltv_expiry_delta = directional_info.cltv_expiry_delta;
184                                         synthetic_update.htlc_minimum_msat = directional_info.htlc_minimum_msat;
185                                         synthetic_update.htlc_maximum_msat = directional_info.htlc_maximum_msat;
186                                         synthetic_update.fee_base_msat = directional_info.fees.base_msat;
187                                         synthetic_update.fee_proportional_millionths = directional_info.fees.proportional_millionths;
188
189                                 } else {
190                                         skip_update_for_unknown_channel = true;
191                                 }
192                         };
193
194                         if channel_flags & 0b_0100_0000 > 0 {
195                                 let cltv_expiry_delta: u16 = Readable::read(read_cursor)?;
196                                 synthetic_update.cltv_expiry_delta = cltv_expiry_delta;
197                         }
198
199                         if channel_flags & 0b_0010_0000 > 0 {
200                                 let htlc_minimum_msat: u64 = Readable::read(read_cursor)?;
201                                 synthetic_update.htlc_minimum_msat = htlc_minimum_msat;
202                         }
203
204                         if channel_flags & 0b_0001_0000 > 0 {
205                                 let fee_base_msat: u32 = Readable::read(read_cursor)?;
206                                 synthetic_update.fee_base_msat = fee_base_msat;
207                         }
208
209                         if channel_flags & 0b_0000_1000 > 0 {
210                                 let fee_proportional_millionths: u32 = Readable::read(read_cursor)?;
211                                 synthetic_update.fee_proportional_millionths = fee_proportional_millionths;
212                         }
213
214                         if channel_flags & 0b_0000_0100 > 0 {
215                                 let htlc_maximum_msat: u64 = Readable::read(read_cursor)?;
216                                 synthetic_update.htlc_maximum_msat = htlc_maximum_msat;
217                         }
218
219                         if skip_update_for_unknown_channel {
220                                 continue;
221                         }
222
223                         match network_graph.update_channel_unsigned(&synthetic_update) {
224                                 Ok(_) => {},
225                                 Err(LightningError { action: ErrorAction::IgnoreDuplicateGossip, .. }) => {},
226                                 Err(LightningError { action: ErrorAction::IgnoreAndLog(_), .. }) => {},
227                                 Err(LightningError { action: ErrorAction::IgnoreError, .. }) => {},
228                                 Err(e) => return Err(e.into()),
229                         }
230                 }
231
232                 self.network_graph.set_last_rapid_gossip_sync_timestamp(latest_seen_timestamp);
233                 self.is_initial_sync_complete.store(true, Ordering::Release);
234                 Ok(latest_seen_timestamp)
235         }
236 }
237
238 #[cfg(test)]
239 mod tests {
240         use bitcoin::blockdata::constants::genesis_block;
241         use bitcoin::Network;
242
243         use lightning::ln::msgs::DecodeError;
244         use lightning::routing::gossip::NetworkGraph;
245         use lightning::util::test_utils::TestLogger;
246
247         use crate::error::GraphSyncError;
248         use crate::processing::STALE_RGS_UPDATE_AGE_LIMIT_SECS;
249         use crate::RapidGossipSync;
250
251         const VALID_RGS_BINARY: [u8; 300] = [
252                 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
253                 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
254                 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
255                 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
256                 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
257                 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
258                 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
259                 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
260                 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
261                 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
262                 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,
263                 0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
264                 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,
265                 0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
266                 0, 0, 1,
267         ];
268         const VALID_BINARY_TIMESTAMP: u64 = 1642291930;
269
270         #[test]
271         fn network_graph_fails_to_update_from_clipped_input() {
272                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
273                 let logger = TestLogger::new();
274                 let network_graph = NetworkGraph::new(block_hash, &logger);
275
276                 let example_input = vec![
277                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
278                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
279                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
280                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
281                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
282                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
283                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
284                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
285                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
286                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
287                         226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 2, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 0, 100,
288                         0, 0, 2, 224, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 36, 0, 0,
289                         0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1, 24, 0,
290                         0, 3, 232, 0, 0, 0,
291                 ];
292                 let rapid_sync = RapidGossipSync::new(&network_graph);
293                 let update_result = rapid_sync.update_network_graph(&example_input[..]);
294                 assert!(update_result.is_err());
295                 if let Err(GraphSyncError::DecodeError(DecodeError::ShortRead)) = update_result {
296                         // this is the expected error type
297                 } else {
298                         panic!("Unexpected update result: {:?}", update_result)
299                 }
300         }
301
302         #[test]
303         fn incremental_only_update_ignores_missing_channel() {
304                 let incremental_update_input = vec![
305                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
306                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
307                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308                         0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 136, 0, 0, 0, 221, 255, 2,
309                         68, 226, 0, 6, 11, 0, 1, 128,
310                 ];
311
312                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
313                 let logger = TestLogger::new();
314                 let network_graph = NetworkGraph::new(block_hash, &logger);
315
316                 assert_eq!(network_graph.read_only().channels().len(), 0);
317
318                 let rapid_sync = RapidGossipSync::new(&network_graph);
319                 let update_result = rapid_sync.update_network_graph(&incremental_update_input[..]);
320                 assert!(update_result.is_ok());
321         }
322
323         #[test]
324         fn incremental_only_update_fails_without_prior_updates() {
325                 let announced_update_input = vec![
326                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
327                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
328                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
329                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
330                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
331                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
332                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
333                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
334                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
335                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
336                         226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 136, 0, 0, 0, 221, 255,
338                         2, 68, 226, 0, 6, 11, 0, 1, 128,
339                 ];
340
341                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
342                 let logger = TestLogger::new();
343                 let network_graph = NetworkGraph::new(block_hash, &logger);
344
345                 assert_eq!(network_graph.read_only().channels().len(), 0);
346
347                 let rapid_sync = RapidGossipSync::new(&network_graph);
348                 let update_result = rapid_sync.update_network_graph(&announced_update_input[..]);
349                 assert!(update_result.is_err());
350                 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
351                         assert_eq!(
352                                 lightning_error.err,
353                                 "Couldn't find previous directional data for update"
354                         );
355                 } else {
356                         panic!("Unexpected update result: {:?}", update_result)
357                 }
358         }
359
360         #[test]
361         fn incremental_only_update_fails_without_prior_same_direction_updates() {
362                 let initialization_input = vec![
363                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
364                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
365                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
366                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
367                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
368                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
369                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
370                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
371                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
372                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
373                         226, 0, 6, 11, 0, 1, 2, 3, 0, 0, 0, 2, 0, 40, 0, 0, 0, 0, 0, 0, 3, 232, 0, 0, 3, 232,
374                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
375                         0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
376                 ];
377
378                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
379                 let logger = TestLogger::new();
380                 let network_graph = NetworkGraph::new(block_hash, &logger);
381
382                 assert_eq!(network_graph.read_only().channels().len(), 0);
383
384                 let rapid_sync = RapidGossipSync::new(&network_graph);
385                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
386                 if initialization_result.is_err() {
387                         panic!(
388                                 "Unexpected initialization result: {:?}",
389                                 initialization_result
390                         )
391                 }
392
393                 assert_eq!(network_graph.read_only().channels().len(), 2);
394                 let initialized = network_graph.to_string();
395                 assert!(initialized
396                         .contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643"));
397                 assert!(initialized
398                         .contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b"));
399                 assert!(initialized
400                         .contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432"));
401                 assert!(initialized
402                         .contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61"));
403                 assert!(initialized.contains("619737530008010752"));
404                 assert!(initialized.contains("783241506229452801"));
405
406                 let opposite_direction_incremental_update_input = vec![
407                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
408                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
409                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
410                         0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 136, 0, 0, 0, 221, 255, 2,
411                         68, 226, 0, 6, 11, 0, 1, 128,
412                 ];
413                 let update_result = rapid_sync.update_network_graph(&opposite_direction_incremental_update_input[..]);
414                 assert!(update_result.is_err());
415                 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
416                         assert_eq!(
417                                 lightning_error.err,
418                                 "Couldn't find previous directional data for update"
419                         );
420                 } else {
421                         panic!("Unexpected update result: {:?}", update_result)
422                 }
423         }
424
425         #[test]
426         fn incremental_update_succeeds_with_prior_announcements_and_full_updates() {
427                 let initialization_input = vec![
428                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
429                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
430                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
431                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
432                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
433                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
434                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
435                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
436                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
437                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
438                         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,
439                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
440                         0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 25, 0, 0, 0, 1, 0, 0, 0, 125, 255, 2,
441                         68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
442                         25, 192,
443                 ];
444
445                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
446                 let logger = TestLogger::new();
447                 let network_graph = NetworkGraph::new(block_hash, &logger);
448
449                 assert_eq!(network_graph.read_only().channels().len(), 0);
450
451                 let rapid_sync = RapidGossipSync::new(&network_graph);
452                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
453                 assert!(initialization_result.is_ok());
454
455                 let single_direction_incremental_update_input = vec![
456                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
457                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
458                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
459                         0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 136, 0, 0, 0, 221, 255, 2,
460                         68, 226, 0, 6, 11, 0, 1, 128,
461                 ];
462                 let update_result = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
463                 if update_result.is_err() {
464                         panic!("Unexpected update result: {:?}", update_result)
465                 }
466
467                 assert_eq!(network_graph.read_only().channels().len(), 2);
468                 let after = network_graph.to_string();
469                 assert!(
470                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
471                 );
472                 assert!(
473                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
474                 );
475                 assert!(
476                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
477                 );
478                 assert!(
479                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
480                 );
481                 assert!(after.contains("619737530008010752"));
482                 assert!(after.contains("783241506229452801"));
483         }
484
485         #[test]
486         fn update_succeeds_when_duplicate_gossip_is_applied() {
487                 let initialization_input = vec![
488                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
489                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
490                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
491                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
492                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
493                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
494                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
495                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
496                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
497                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
498                         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,
499                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
500                         0, 0, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 2, 224, 0, 25, 0, 0, 0, 1, 0, 0, 0, 125, 255, 2,
501                         68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
502                         25, 192,
503                 ];
504
505                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
506                 let logger = TestLogger::new();
507                 let network_graph = NetworkGraph::new(block_hash, &logger);
508
509                 assert_eq!(network_graph.read_only().channels().len(), 0);
510
511                 let rapid_sync = RapidGossipSync::new(&network_graph);
512                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
513                 assert!(initialization_result.is_ok());
514
515                 let single_direction_incremental_update_input = vec![
516                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
517                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
518                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
519                         0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 136, 0, 0, 0, 221, 255, 2,
520                         68, 226, 0, 6, 11, 0, 1, 128,
521                 ];
522                 let update_result_1 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
523                 // Apply duplicate update
524                 let update_result_2 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
525                 assert!(update_result_1.is_ok());
526                 assert!(update_result_2.is_ok());
527         }
528
529         #[test]
530         fn full_update_succeeds() {
531                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
532                 let logger = TestLogger::new();
533                 let network_graph = NetworkGraph::new(block_hash, &logger);
534
535                 assert_eq!(network_graph.read_only().channels().len(), 0);
536
537                 let rapid_sync = RapidGossipSync::new(&network_graph);
538                 let update_result = rapid_sync.update_network_graph(&VALID_RGS_BINARY);
539                 if update_result.is_err() {
540                         panic!("Unexpected update result: {:?}", update_result)
541                 }
542
543                 assert_eq!(network_graph.read_only().channels().len(), 2);
544                 let after = network_graph.to_string();
545                 assert!(
546                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
547                 );
548                 assert!(
549                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
550                 );
551                 assert!(
552                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
553                 );
554                 assert!(
555                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
556                 );
557                 assert!(after.contains("619737530008010752"));
558                 assert!(after.contains("783241506229452801"));
559         }
560
561         #[test]
562         fn full_update_succeeds_at_the_beginning_of_the_unix_era() {
563                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
564                 let logger = TestLogger::new();
565                 let network_graph = NetworkGraph::new(block_hash, &logger);
566
567                 assert_eq!(network_graph.read_only().channels().len(), 0);
568
569                 let rapid_sync = RapidGossipSync::new(&network_graph);
570                 // this is mostly for checking uint underflow issues before the fuzzer does
571                 let update_result = rapid_sync.update_network_graph_no_std(&VALID_RGS_BINARY, Some(0));
572                 assert!(update_result.is_ok());
573                 assert_eq!(network_graph.read_only().channels().len(), 2);
574         }
575
576         #[test]
577         fn timestamp_edge_cases_are_handled_correctly() {
578                 // this is the timestamp encoded in the binary data of valid_input below
579                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
580                 let logger = TestLogger::new();
581
582                 let latest_succeeding_time = VALID_BINARY_TIMESTAMP + STALE_RGS_UPDATE_AGE_LIMIT_SECS;
583                 let earliest_failing_time = latest_succeeding_time + 1;
584
585                 {
586                         let network_graph = NetworkGraph::new(block_hash, &logger);
587                         assert_eq!(network_graph.read_only().channels().len(), 0);
588
589                         let rapid_sync = RapidGossipSync::new(&network_graph);
590                         let update_result = rapid_sync.update_network_graph_no_std(&VALID_RGS_BINARY, Some(latest_succeeding_time));
591                         assert!(update_result.is_ok());
592                         assert_eq!(network_graph.read_only().channels().len(), 2);
593                 }
594
595                 {
596                         let network_graph = NetworkGraph::new(block_hash, &logger);
597                         assert_eq!(network_graph.read_only().channels().len(), 0);
598
599                         let rapid_sync = RapidGossipSync::new(&network_graph);
600                         let update_result = rapid_sync.update_network_graph_no_std(&VALID_RGS_BINARY, Some(earliest_failing_time));
601                         assert!(update_result.is_err());
602                         if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
603                                 assert_eq!(
604                                         lightning_error.err,
605                                         "Rapid Gossip Sync data is more than two weeks old"
606                                 );
607                         } else {
608                                 panic!("Unexpected update result: {:?}", update_result)
609                         }
610                 }
611         }
612
613         #[test]
614         pub fn update_fails_with_unknown_version() {
615                 let unknown_version_input = vec![
616                         76, 68, 75, 2, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
617                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
618                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
619                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
620                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
621                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
622                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
623                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
624                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
625                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
626                         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,
627                         0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
628                         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,
629                         0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
630                         0, 0, 1,
631                 ];
632
633                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
634                 let logger = TestLogger::new();
635                 let network_graph = NetworkGraph::new(block_hash, &logger);
636                 let rapid_sync = RapidGossipSync::new(&network_graph);
637                 let update_result = rapid_sync.update_network_graph(&unknown_version_input[..]);
638
639                 assert!(update_result.is_err());
640
641                 if let Err(GraphSyncError::DecodeError(DecodeError::UnknownVersion)) = update_result {
642                         // this is the expected error type
643                 } else {
644                         panic!("Unexpected update result: {:?}", update_result)
645                 }
646         }
647 }