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(not(feature = "std"))]
20 use alloc::{vec::Vec, borrow::ToOwned};
22 /// The purpose of this prefix is to identify the serialization format, should other rapid gossip
23 /// sync formats arise in the future.
25 /// The fourth byte is the protocol version in case our format gets updated.
26 const GOSSIP_PREFIX: [u8; 4] = [76, 68, 75, 1];
28 /// Maximum vector allocation capacity for distinct node IDs. This constraint is necessary to
29 /// avoid malicious updates being able to trigger excessive memory allocation.
30 const MAX_INITIAL_NODE_ID_VECTOR_CAPACITY: u32 = 50_000;
32 impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L::Target: Logger {
33 pub(crate) fn update_network_graph_from_byte_stream<R: io::Read>(
35 mut read_cursor: &mut R,
36 ) -> Result<u32, GraphSyncError> {
37 let mut prefix = [0u8; 4];
38 read_cursor.read_exact(&mut prefix)?;
43 return Err(DecodeError::UnknownVersion.into());
47 let chain_hash: BlockHash = Readable::read(read_cursor)?;
48 let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
49 // backdate the applied timestamp by a week
50 let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
52 let node_id_count: u32 = Readable::read(read_cursor)?;
53 let mut node_ids: Vec<PublicKey> = Vec::with_capacity(core::cmp::min(
55 MAX_INITIAL_NODE_ID_VECTOR_CAPACITY,
57 for _ in 0..node_id_count {
58 let current_node_id = Readable::read(read_cursor)?;
59 node_ids.push(current_node_id);
62 let network_graph = &self.network_graph;
64 let mut previous_scid: u64 = 0;
65 let announcement_count: u32 = Readable::read(read_cursor)?;
66 for _ in 0..announcement_count {
67 let features = Readable::read(read_cursor)?;
70 let scid_delta: BigSize = Readable::read(read_cursor)?;
71 let short_channel_id = previous_scid
72 .checked_add(scid_delta.0)
73 .ok_or(DecodeError::InvalidValue)?;
74 previous_scid = short_channel_id;
76 let node_id_1_index: BigSize = Readable::read(read_cursor)?;
77 let node_id_2_index: BigSize = Readable::read(read_cursor)?;
78 if max(node_id_1_index.0, node_id_2_index.0) >= node_id_count as u64 {
79 return Err(DecodeError::InvalidValue.into());
81 let node_id_1 = node_ids[node_id_1_index.0 as usize];
82 let node_id_2 = node_ids[node_id_2_index.0 as usize];
84 let announcement_result = network_graph.add_channel_from_partial_announcement(
86 backdated_timestamp as u64,
91 if let Err(lightning_error) = announcement_result {
92 if let ErrorAction::IgnoreDuplicateGossip = lightning_error.action {
93 // everything is fine, just a duplicate channel announcement
95 return Err(lightning_error.into());
100 previous_scid = 0; // updates start at a new scid
102 let update_count: u32 = Readable::read(read_cursor)?;
103 if update_count == 0 {
104 return Ok(latest_seen_timestamp);
107 // obtain default values for non-incremental updates
108 let default_cltv_expiry_delta: u16 = Readable::read(&mut read_cursor)?;
109 let default_htlc_minimum_msat: u64 = Readable::read(&mut read_cursor)?;
110 let default_fee_base_msat: u32 = Readable::read(&mut read_cursor)?;
111 let default_fee_proportional_millionths: u32 = Readable::read(&mut read_cursor)?;
112 let default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?;
114 for _ in 0..update_count {
115 let scid_delta: BigSize = Readable::read(read_cursor)?;
116 let short_channel_id = previous_scid
117 .checked_add(scid_delta.0)
118 .ok_or(DecodeError::InvalidValue)?;
119 previous_scid = short_channel_id;
121 let channel_flags: u8 = Readable::read(read_cursor)?;
123 // flags are always sent in full, and hence always need updating
124 let standard_channel_flags = channel_flags & 0b_0000_0011;
126 let mut synthetic_update = if channel_flags & 0b_1000_0000 == 0 {
127 // full update, field flags will indicate deviations from the default
128 UnsignedChannelUpdate {
131 timestamp: backdated_timestamp,
132 flags: standard_channel_flags,
133 cltv_expiry_delta: default_cltv_expiry_delta,
134 htlc_minimum_msat: default_htlc_minimum_msat,
135 htlc_maximum_msat: default_htlc_maximum_msat,
136 fee_base_msat: default_fee_base_msat,
137 fee_proportional_millionths: default_fee_proportional_millionths,
138 excess_data: Vec::new(),
141 // incremental update, field flags will indicate mutated values
142 let read_only_network_graph = network_graph.read_only();
143 let channel = read_only_network_graph
145 .get(&short_channel_id)
146 .ok_or(LightningError {
147 err: "Couldn't find channel for update".to_owned(),
148 action: ErrorAction::IgnoreError,
151 let directional_info = channel
152 .get_directional_info(channel_flags)
153 .ok_or(LightningError {
154 err: "Couldn't find previous directional data for update".to_owned(),
155 action: ErrorAction::IgnoreError,
158 UnsignedChannelUpdate {
161 timestamp: backdated_timestamp,
162 flags: standard_channel_flags,
163 cltv_expiry_delta: directional_info.cltv_expiry_delta,
164 htlc_minimum_msat: directional_info.htlc_minimum_msat,
165 htlc_maximum_msat: directional_info.htlc_maximum_msat,
166 fee_base_msat: directional_info.fees.base_msat,
167 fee_proportional_millionths: directional_info.fees.proportional_millionths,
168 excess_data: Vec::new(),
172 if channel_flags & 0b_0100_0000 > 0 {
173 let cltv_expiry_delta: u16 = Readable::read(read_cursor)?;
174 synthetic_update.cltv_expiry_delta = cltv_expiry_delta;
177 if channel_flags & 0b_0010_0000 > 0 {
178 let htlc_minimum_msat: u64 = Readable::read(read_cursor)?;
179 synthetic_update.htlc_minimum_msat = htlc_minimum_msat;
182 if channel_flags & 0b_0001_0000 > 0 {
183 let fee_base_msat: u32 = Readable::read(read_cursor)?;
184 synthetic_update.fee_base_msat = fee_base_msat;
187 if channel_flags & 0b_0000_1000 > 0 {
188 let fee_proportional_millionths: u32 = Readable::read(read_cursor)?;
189 synthetic_update.fee_proportional_millionths = fee_proportional_millionths;
192 if channel_flags & 0b_0000_0100 > 0 {
193 let htlc_maximum_msat: u64 = Readable::read(read_cursor)?;
194 synthetic_update.htlc_maximum_msat = htlc_maximum_msat;
197 match network_graph.update_channel_unsigned(&synthetic_update) {
199 Err(LightningError { action: ErrorAction::IgnoreDuplicateGossip, .. }) => {},
200 Err(LightningError { action: ErrorAction::IgnoreAndLog(_), .. }) => {},
201 Err(LightningError { action: ErrorAction::IgnoreError, .. }) => {},
202 Err(e) => return Err(e.into()),
206 self.network_graph.set_last_rapid_gossip_sync_timestamp(latest_seen_timestamp);
207 self.is_initial_sync_complete.store(true, Ordering::Release);
208 Ok(latest_seen_timestamp)
214 use bitcoin::blockdata::constants::genesis_block;
215 use bitcoin::Network;
217 use lightning::ln::msgs::DecodeError;
218 use lightning::routing::gossip::NetworkGraph;
219 use lightning::util::test_utils::TestLogger;
221 use crate::error::GraphSyncError;
222 use crate::RapidGossipSync;
225 fn network_graph_fails_to_update_from_clipped_input() {
226 let block_hash = genesis_block(Network::Bitcoin).block_hash();
227 let logger = TestLogger::new();
228 let network_graph = NetworkGraph::new(block_hash, &logger);
230 let example_input = vec![
231 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
232 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
233 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
234 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
235 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
236 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
237 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
238 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
239 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
240 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
241 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,
242 0, 0, 2, 224, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 36, 0, 0,
243 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,
246 let rapid_sync = RapidGossipSync::new(&network_graph);
247 let update_result = rapid_sync.update_network_graph(&example_input[..]);
248 assert!(update_result.is_err());
249 if let Err(GraphSyncError::DecodeError(DecodeError::ShortRead)) = update_result {
250 // this is the expected error type
252 panic!("Unexpected update result: {:?}", update_result)
257 fn incremental_only_update_fails_without_prior_announcements() {
258 let incremental_update_input = vec![
259 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
260 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
261 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,
262 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,
263 68, 226, 0, 6, 11, 0, 1, 128,
266 let block_hash = genesis_block(Network::Bitcoin).block_hash();
267 let logger = TestLogger::new();
268 let network_graph = NetworkGraph::new(block_hash, &logger);
270 assert_eq!(network_graph.read_only().channels().len(), 0);
272 let rapid_sync = RapidGossipSync::new(&network_graph);
273 let update_result = rapid_sync.update_network_graph(&incremental_update_input[..]);
274 assert!(update_result.is_err());
275 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
276 assert_eq!(lightning_error.err, "Couldn't find channel for update");
278 panic!("Unexpected update result: {:?}", update_result)
283 fn incremental_only_update_fails_without_prior_updates() {
284 let announced_update_input = vec![
285 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
286 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
287 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
288 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
289 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
290 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
291 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
292 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
293 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
294 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
295 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,
296 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,
297 2, 68, 226, 0, 6, 11, 0, 1, 128,
300 let block_hash = genesis_block(Network::Bitcoin).block_hash();
301 let logger = TestLogger::new();
302 let network_graph = NetworkGraph::new(block_hash, &logger);
304 assert_eq!(network_graph.read_only().channels().len(), 0);
306 let rapid_sync = RapidGossipSync::new(&network_graph);
307 let update_result = rapid_sync.update_network_graph(&announced_update_input[..]);
308 assert!(update_result.is_err());
309 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
312 "Couldn't find previous directional data for update"
315 panic!("Unexpected update result: {:?}", update_result)
320 fn incremental_only_update_fails_without_prior_same_direction_updates() {
321 let initialization_input = vec![
322 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
323 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
324 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
325 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
326 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
327 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
328 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
329 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
330 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
331 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
332 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,
333 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
334 0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
337 let block_hash = genesis_block(Network::Bitcoin).block_hash();
338 let logger = TestLogger::new();
339 let network_graph = NetworkGraph::new(block_hash, &logger);
341 assert_eq!(network_graph.read_only().channels().len(), 0);
343 let rapid_sync = RapidGossipSync::new(&network_graph);
344 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
345 if initialization_result.is_err() {
347 "Unexpected initialization result: {:?}",
348 initialization_result
352 assert_eq!(network_graph.read_only().channels().len(), 2);
353 let initialized = network_graph.to_string();
355 .contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643"));
357 .contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b"));
359 .contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432"));
361 .contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61"));
362 assert!(initialized.contains("619737530008010752"));
363 assert!(initialized.contains("783241506229452801"));
365 let opposite_direction_incremental_update_input = vec![
366 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
367 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
368 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,
369 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,
370 68, 226, 0, 6, 11, 0, 1, 128,
372 let update_result = rapid_sync.update_network_graph(&opposite_direction_incremental_update_input[..]);
373 assert!(update_result.is_err());
374 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
377 "Couldn't find previous directional data for update"
380 panic!("Unexpected update result: {:?}", update_result)
385 fn incremental_update_succeeds_with_prior_announcements_and_full_updates() {
386 let initialization_input = vec![
387 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
388 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
389 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
390 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
391 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
392 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
393 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
394 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
395 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
396 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
397 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,
398 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
399 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,
400 68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
404 let block_hash = genesis_block(Network::Bitcoin).block_hash();
405 let logger = TestLogger::new();
406 let network_graph = NetworkGraph::new(block_hash, &logger);
408 assert_eq!(network_graph.read_only().channels().len(), 0);
410 let rapid_sync = RapidGossipSync::new(&network_graph);
411 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
412 assert!(initialization_result.is_ok());
414 let single_direction_incremental_update_input = vec![
415 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
416 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
417 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,
418 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,
419 68, 226, 0, 6, 11, 0, 1, 128,
421 let update_result = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
422 if update_result.is_err() {
423 panic!("Unexpected update result: {:?}", update_result)
426 assert_eq!(network_graph.read_only().channels().len(), 2);
427 let after = network_graph.to_string();
429 after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
432 after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
435 after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
438 after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
440 assert!(after.contains("619737530008010752"));
441 assert!(after.contains("783241506229452801"));
445 fn update_succeeds_when_duplicate_gossip_is_applied() {
446 let initialization_input = vec![
447 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
448 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
449 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
450 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
451 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
452 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
453 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
454 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
455 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
456 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
457 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,
458 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
459 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,
460 68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
464 let block_hash = genesis_block(Network::Bitcoin).block_hash();
465 let logger = TestLogger::new();
466 let network_graph = NetworkGraph::new(block_hash, &logger);
468 assert_eq!(network_graph.read_only().channels().len(), 0);
470 let rapid_sync = RapidGossipSync::new(&network_graph);
471 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
472 assert!(initialization_result.is_ok());
474 let single_direction_incremental_update_input = vec![
475 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
476 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
477 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,
478 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,
479 68, 226, 0, 6, 11, 0, 1, 128,
481 let update_result_1 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
482 // Apply duplicate update
483 let update_result_2 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
484 assert!(update_result_1.is_ok());
485 assert!(update_result_2.is_ok());
489 fn full_update_succeeds() {
490 let valid_input = vec![
491 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
492 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
493 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
494 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
495 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
496 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
497 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
498 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
499 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
500 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
501 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,
502 0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
503 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,
504 0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
508 let block_hash = genesis_block(Network::Bitcoin).block_hash();
509 let logger = TestLogger::new();
510 let network_graph = NetworkGraph::new(block_hash, &logger);
512 assert_eq!(network_graph.read_only().channels().len(), 0);
514 let rapid_sync = RapidGossipSync::new(&network_graph);
515 let update_result = rapid_sync.update_network_graph(&valid_input[..]);
516 if update_result.is_err() {
517 panic!("Unexpected update result: {:?}", update_result)
520 assert_eq!(network_graph.read_only().channels().len(), 2);
521 let after = network_graph.to_string();
523 after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
526 after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
529 after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
532 after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
534 assert!(after.contains("619737530008010752"));
535 assert!(after.contains("783241506229452801"));