3 use core::sync::atomic::Ordering;
5 use bitcoin::BlockHash;
6 use bitcoin::secp256k1::PublicKey;
8 use lightning::ln::msgs::{
9 DecodeError, ErrorAction, LightningError, UnsignedChannelUpdate,
11 use lightning::routing::gossip::NetworkGraph;
12 use lightning::util::logger::Logger;
13 use lightning::util::ser::{BigSize, Readable};
16 use crate::error::GraphSyncError;
17 use crate::RapidGossipSync;
19 #[cfg(all(feature = "std", not(test)))]
20 use std::time::{SystemTime, UNIX_EPOCH};
22 #[cfg(not(feature = "std"))]
23 use alloc::{vec::Vec, borrow::ToOwned};
25 /// The purpose of this prefix is to identify the serialization format, should other rapid gossip
26 /// sync formats arise in the future.
28 /// The fourth byte is the protocol version in case our format gets updated.
29 const GOSSIP_PREFIX: [u8; 4] = [76, 68, 75, 1];
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;
35 /// We disallow gossip data that's more than two weeks old, per BOLT 7's
37 const STALE_RGS_UPDATE_AGE_LIMIT_SECS: u64 = 60 * 60 * 24 * 14;
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>(
43 ) -> Result<u32, GraphSyncError> {
45 let mut current_time_unix = None;
46 #[cfg(all(feature = "std", not(test)))]
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());
52 self.update_network_graph_from_byte_stream_no_std(read_cursor, current_time_unix)
55 pub(crate) fn update_network_graph_from_byte_stream_no_std<R: io::Read>(
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)?;
63 if prefix != GOSSIP_PREFIX {
64 return Err(DecodeError::UnknownVersion.into());
67 let chain_hash: BlockHash = Readable::read(read_cursor)?;
68 let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
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());
76 // backdate the applied timestamp by a week
77 let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
79 let node_id_count: u32 = Readable::read(read_cursor)?;
80 let mut node_ids: Vec<PublicKey> = Vec::with_capacity(core::cmp::min(
82 MAX_INITIAL_NODE_ID_VECTOR_CAPACITY,
84 for _ in 0..node_id_count {
85 let current_node_id = Readable::read(read_cursor)?;
86 node_ids.push(current_node_id);
89 let network_graph = &self.network_graph;
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)?;
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;
103 let node_id_1_index: BigSize = Readable::read(read_cursor)?;
104 let node_id_2_index: BigSize = Readable::read(read_cursor)?;
106 if max(node_id_1_index.0, node_id_2_index.0) >= node_id_count as u64 {
107 return Err(DecodeError::InvalidValue.into());
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];
112 let announcement_result = network_graph.add_channel_from_partial_announcement(
114 backdated_timestamp as u64,
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
123 return Err(lightning_error.into());
128 previous_scid = 0; // updates start at a new scid
130 let update_count: u32 = Readable::read(read_cursor)?;
131 if update_count == 0 {
132 return Ok(latest_seen_timestamp);
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)?;
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;
149 let channel_flags: u8 = Readable::read(read_cursor)?;
151 // flags are always sent in full, and hence always need updating
152 let standard_channel_flags = channel_flags & 0b_0000_0011;
154 let mut synthetic_update = UnsignedChannelUpdate {
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(),
167 let mut skip_update_for_unknown_channel = false;
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
174 .get(&short_channel_id) {
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,
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;
190 skip_update_for_unknown_channel = true;
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;
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;
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;
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;
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;
219 if skip_update_for_unknown_channel {
223 match network_graph.update_channel_unsigned(&synthetic_update) {
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()),
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)
240 use bitcoin::blockdata::constants::genesis_block;
241 use bitcoin::Network;
243 use lightning::ln::msgs::DecodeError;
244 use lightning::routing::gossip::NetworkGraph;
245 use lightning::util::test_utils::TestLogger;
247 use crate::error::GraphSyncError;
248 use crate::processing::STALE_RGS_UPDATE_AGE_LIMIT_SECS;
249 use crate::RapidGossipSync;
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,
268 const VALID_BINARY_TIMESTAMP: u64 = 1642291930;
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);
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,
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
298 panic!("Unexpected update result: {:?}", update_result)
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,
312 let block_hash = genesis_block(Network::Bitcoin).block_hash();
313 let logger = TestLogger::new();
314 let network_graph = NetworkGraph::new(block_hash, &logger);
316 assert_eq!(network_graph.read_only().channels().len(), 0);
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());
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,
341 let block_hash = genesis_block(Network::Bitcoin).block_hash();
342 let logger = TestLogger::new();
343 let network_graph = NetworkGraph::new(block_hash, &logger);
345 assert_eq!(network_graph.read_only().channels().len(), 0);
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 {
353 "Couldn't find previous directional data for update"
356 panic!("Unexpected update result: {:?}", update_result)
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,
378 let block_hash = genesis_block(Network::Bitcoin).block_hash();
379 let logger = TestLogger::new();
380 let network_graph = NetworkGraph::new(block_hash, &logger);
382 assert_eq!(network_graph.read_only().channels().len(), 0);
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() {
388 "Unexpected initialization result: {:?}",
389 initialization_result
393 assert_eq!(network_graph.read_only().channels().len(), 2);
394 let initialized = network_graph.to_string();
396 .contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643"));
398 .contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b"));
400 .contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432"));
402 .contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61"));
403 assert!(initialized.contains("619737530008010752"));
404 assert!(initialized.contains("783241506229452801"));
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,
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 {
418 "Couldn't find previous directional data for update"
421 panic!("Unexpected update result: {:?}", update_result)
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,
445 let block_hash = genesis_block(Network::Bitcoin).block_hash();
446 let logger = TestLogger::new();
447 let network_graph = NetworkGraph::new(block_hash, &logger);
449 assert_eq!(network_graph.read_only().channels().len(), 0);
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());
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,
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)
467 assert_eq!(network_graph.read_only().channels().len(), 2);
468 let after = network_graph.to_string();
470 after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
473 after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
476 after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
479 after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
481 assert!(after.contains("619737530008010752"));
482 assert!(after.contains("783241506229452801"));
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,
505 let block_hash = genesis_block(Network::Bitcoin).block_hash();
506 let logger = TestLogger::new();
507 let network_graph = NetworkGraph::new(block_hash, &logger);
509 assert_eq!(network_graph.read_only().channels().len(), 0);
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());
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,
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());
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);
535 assert_eq!(network_graph.read_only().channels().len(), 0);
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)
543 assert_eq!(network_graph.read_only().channels().len(), 2);
544 let after = network_graph.to_string();
546 after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
549 after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
552 after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
555 after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
557 assert!(after.contains("619737530008010752"));
558 assert!(after.contains("783241506229452801"));
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);
567 assert_eq!(network_graph.read_only().channels().len(), 0);
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);
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();
582 let latest_succeeding_time = VALID_BINARY_TIMESTAMP + STALE_RGS_UPDATE_AGE_LIMIT_SECS;
583 let earliest_failing_time = latest_succeeding_time + 1;
586 let network_graph = NetworkGraph::new(block_hash, &logger);
587 assert_eq!(network_graph.read_only().channels().len(), 0);
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);
596 let network_graph = NetworkGraph::new(block_hash, &logger);
597 assert_eq!(network_graph.read_only().channels().len(), 0);
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 {
605 "Rapid Gossip Sync data is more than two weeks old"
608 panic!("Unexpected update result: {:?}", update_result)
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,
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[..]);
639 assert!(update_result.is_err());
641 if let Err(GraphSyncError::DecodeError(DecodeError::UnknownVersion)) = update_result {
642 // this is the expected error type
644 panic!("Unexpected update result: {:?}", update_result)