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)?;
40 if prefix != GOSSIP_PREFIX {
41 return Err(DecodeError::UnknownVersion.into());
44 let chain_hash: BlockHash = Readable::read(read_cursor)?;
45 let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
46 // backdate the applied timestamp by a week
47 let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
49 let node_id_count: u32 = Readable::read(read_cursor)?;
50 let mut node_ids: Vec<PublicKey> = Vec::with_capacity(core::cmp::min(
52 MAX_INITIAL_NODE_ID_VECTOR_CAPACITY,
54 for _ in 0..node_id_count {
55 let current_node_id = Readable::read(read_cursor)?;
56 node_ids.push(current_node_id);
59 let network_graph = &self.network_graph;
61 let mut previous_scid: u64 = 0;
62 let announcement_count: u32 = Readable::read(read_cursor)?;
63 for _ in 0..announcement_count {
64 let features = Readable::read(read_cursor)?;
67 let scid_delta: BigSize = Readable::read(read_cursor)?;
68 let short_channel_id = previous_scid
69 .checked_add(scid_delta.0)
70 .ok_or(DecodeError::InvalidValue)?;
71 previous_scid = short_channel_id;
73 let node_id_1_index: BigSize = Readable::read(read_cursor)?;
74 let node_id_2_index: BigSize = Readable::read(read_cursor)?;
75 if max(node_id_1_index.0, node_id_2_index.0) >= node_id_count as u64 {
76 return Err(DecodeError::InvalidValue.into());
78 let node_id_1 = node_ids[node_id_1_index.0 as usize];
79 let node_id_2 = node_ids[node_id_2_index.0 as usize];
81 let announcement_result = network_graph.add_channel_from_partial_announcement(
83 backdated_timestamp as u64,
88 if let Err(lightning_error) = announcement_result {
89 if let ErrorAction::IgnoreDuplicateGossip = lightning_error.action {
90 // everything is fine, just a duplicate channel announcement
92 return Err(lightning_error.into());
97 previous_scid = 0; // updates start at a new scid
99 let update_count: u32 = Readable::read(read_cursor)?;
100 if update_count == 0 {
101 return Ok(latest_seen_timestamp);
104 // obtain default values for non-incremental updates
105 let default_cltv_expiry_delta: u16 = Readable::read(&mut read_cursor)?;
106 let default_htlc_minimum_msat: u64 = Readable::read(&mut read_cursor)?;
107 let default_fee_base_msat: u32 = Readable::read(&mut read_cursor)?;
108 let default_fee_proportional_millionths: u32 = Readable::read(&mut read_cursor)?;
109 let default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?;
111 for _ in 0..update_count {
112 let scid_delta: BigSize = Readable::read(read_cursor)?;
113 let short_channel_id = previous_scid
114 .checked_add(scid_delta.0)
115 .ok_or(DecodeError::InvalidValue)?;
116 previous_scid = short_channel_id;
118 let channel_flags: u8 = Readable::read(read_cursor)?;
120 // flags are always sent in full, and hence always need updating
121 let standard_channel_flags = channel_flags & 0b_0000_0011;
123 let mut synthetic_update = if channel_flags & 0b_1000_0000 == 0 {
124 // full update, field flags will indicate deviations from the default
125 UnsignedChannelUpdate {
128 timestamp: backdated_timestamp,
129 flags: standard_channel_flags,
130 cltv_expiry_delta: default_cltv_expiry_delta,
131 htlc_minimum_msat: default_htlc_minimum_msat,
132 htlc_maximum_msat: default_htlc_maximum_msat,
133 fee_base_msat: default_fee_base_msat,
134 fee_proportional_millionths: default_fee_proportional_millionths,
135 excess_data: Vec::new(),
138 // incremental update, field flags will indicate mutated values
139 let read_only_network_graph = network_graph.read_only();
140 let channel = read_only_network_graph
142 .get(&short_channel_id)
143 .ok_or(LightningError {
144 err: "Couldn't find channel for update".to_owned(),
145 action: ErrorAction::IgnoreError,
148 let directional_info = channel
149 .get_directional_info(channel_flags)
150 .ok_or(LightningError {
151 err: "Couldn't find previous directional data for update".to_owned(),
152 action: ErrorAction::IgnoreError,
155 UnsignedChannelUpdate {
158 timestamp: backdated_timestamp,
159 flags: standard_channel_flags,
160 cltv_expiry_delta: directional_info.cltv_expiry_delta,
161 htlc_minimum_msat: directional_info.htlc_minimum_msat,
162 htlc_maximum_msat: directional_info.htlc_maximum_msat,
163 fee_base_msat: directional_info.fees.base_msat,
164 fee_proportional_millionths: directional_info.fees.proportional_millionths,
165 excess_data: Vec::new(),
169 if channel_flags & 0b_0100_0000 > 0 {
170 let cltv_expiry_delta: u16 = Readable::read(read_cursor)?;
171 synthetic_update.cltv_expiry_delta = cltv_expiry_delta;
174 if channel_flags & 0b_0010_0000 > 0 {
175 let htlc_minimum_msat: u64 = Readable::read(read_cursor)?;
176 synthetic_update.htlc_minimum_msat = htlc_minimum_msat;
179 if channel_flags & 0b_0001_0000 > 0 {
180 let fee_base_msat: u32 = Readable::read(read_cursor)?;
181 synthetic_update.fee_base_msat = fee_base_msat;
184 if channel_flags & 0b_0000_1000 > 0 {
185 let fee_proportional_millionths: u32 = Readable::read(read_cursor)?;
186 synthetic_update.fee_proportional_millionths = fee_proportional_millionths;
189 if channel_flags & 0b_0000_0100 > 0 {
190 let htlc_maximum_msat: u64 = Readable::read(read_cursor)?;
191 synthetic_update.htlc_maximum_msat = htlc_maximum_msat;
194 match network_graph.update_channel_unsigned(&synthetic_update) {
196 Err(LightningError { action: ErrorAction::IgnoreDuplicateGossip, .. }) => {},
197 Err(LightningError { action: ErrorAction::IgnoreAndLog(_), .. }) => {},
198 Err(LightningError { action: ErrorAction::IgnoreError, .. }) => {},
199 Err(e) => return Err(e.into()),
203 self.network_graph.set_last_rapid_gossip_sync_timestamp(latest_seen_timestamp);
204 self.is_initial_sync_complete.store(true, Ordering::Release);
205 Ok(latest_seen_timestamp)
211 use bitcoin::blockdata::constants::genesis_block;
212 use bitcoin::Network;
214 use lightning::ln::msgs::DecodeError;
215 use lightning::routing::gossip::NetworkGraph;
216 use lightning::util::test_utils::TestLogger;
218 use crate::error::GraphSyncError;
219 use crate::RapidGossipSync;
222 fn network_graph_fails_to_update_from_clipped_input() {
223 let block_hash = genesis_block(Network::Bitcoin).block_hash();
224 let logger = TestLogger::new();
225 let network_graph = NetworkGraph::new(block_hash, &logger);
227 let example_input = vec![
228 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
229 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
230 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
231 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
232 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
233 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
234 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
235 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
236 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
237 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
238 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,
239 0, 0, 2, 224, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 36, 0, 0,
240 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,
243 let rapid_sync = RapidGossipSync::new(&network_graph);
244 let update_result = rapid_sync.update_network_graph(&example_input[..]);
245 assert!(update_result.is_err());
246 if let Err(GraphSyncError::DecodeError(DecodeError::ShortRead)) = update_result {
247 // this is the expected error type
249 panic!("Unexpected update result: {:?}", update_result)
254 fn incremental_only_update_fails_without_prior_announcements() {
255 let incremental_update_input = vec![
256 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
257 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
258 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,
259 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,
260 68, 226, 0, 6, 11, 0, 1, 128,
263 let block_hash = genesis_block(Network::Bitcoin).block_hash();
264 let logger = TestLogger::new();
265 let network_graph = NetworkGraph::new(block_hash, &logger);
267 assert_eq!(network_graph.read_only().channels().len(), 0);
269 let rapid_sync = RapidGossipSync::new(&network_graph);
270 let update_result = rapid_sync.update_network_graph(&incremental_update_input[..]);
271 assert!(update_result.is_err());
272 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
273 assert_eq!(lightning_error.err, "Couldn't find channel for update");
275 panic!("Unexpected update result: {:?}", update_result)
280 fn incremental_only_update_fails_without_prior_updates() {
281 let announced_update_input = vec![
282 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
283 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
284 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
285 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
286 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
287 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
288 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
289 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
290 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
291 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
292 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,
293 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,
294 2, 68, 226, 0, 6, 11, 0, 1, 128,
297 let block_hash = genesis_block(Network::Bitcoin).block_hash();
298 let logger = TestLogger::new();
299 let network_graph = NetworkGraph::new(block_hash, &logger);
301 assert_eq!(network_graph.read_only().channels().len(), 0);
303 let rapid_sync = RapidGossipSync::new(&network_graph);
304 let update_result = rapid_sync.update_network_graph(&announced_update_input[..]);
305 assert!(update_result.is_err());
306 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
309 "Couldn't find previous directional data for update"
312 panic!("Unexpected update result: {:?}", update_result)
317 fn incremental_only_update_fails_without_prior_same_direction_updates() {
318 let initialization_input = vec![
319 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
320 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
321 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
322 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
323 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
324 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
325 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
326 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
327 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
328 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
329 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,
330 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
331 0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
334 let block_hash = genesis_block(Network::Bitcoin).block_hash();
335 let logger = TestLogger::new();
336 let network_graph = NetworkGraph::new(block_hash, &logger);
338 assert_eq!(network_graph.read_only().channels().len(), 0);
340 let rapid_sync = RapidGossipSync::new(&network_graph);
341 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
342 if initialization_result.is_err() {
344 "Unexpected initialization result: {:?}",
345 initialization_result
349 assert_eq!(network_graph.read_only().channels().len(), 2);
350 let initialized = network_graph.to_string();
352 .contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643"));
354 .contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b"));
356 .contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432"));
358 .contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61"));
359 assert!(initialized.contains("619737530008010752"));
360 assert!(initialized.contains("783241506229452801"));
362 let opposite_direction_incremental_update_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, 229, 183, 167,
365 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,
366 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,
367 68, 226, 0, 6, 11, 0, 1, 128,
369 let update_result = rapid_sync.update_network_graph(&opposite_direction_incremental_update_input[..]);
370 assert!(update_result.is_err());
371 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
374 "Couldn't find previous directional data for update"
377 panic!("Unexpected update result: {:?}", update_result)
382 fn incremental_update_succeeds_with_prior_announcements_and_full_updates() {
383 let initialization_input = vec![
384 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
385 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
386 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
387 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
388 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
389 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
390 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
391 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
392 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
393 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
394 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,
395 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
396 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,
397 68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
401 let block_hash = genesis_block(Network::Bitcoin).block_hash();
402 let logger = TestLogger::new();
403 let network_graph = NetworkGraph::new(block_hash, &logger);
405 assert_eq!(network_graph.read_only().channels().len(), 0);
407 let rapid_sync = RapidGossipSync::new(&network_graph);
408 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
409 assert!(initialization_result.is_ok());
411 let single_direction_incremental_update_input = vec![
412 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
413 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
414 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,
415 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,
416 68, 226, 0, 6, 11, 0, 1, 128,
418 let update_result = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
419 if update_result.is_err() {
420 panic!("Unexpected update result: {:?}", update_result)
423 assert_eq!(network_graph.read_only().channels().len(), 2);
424 let after = network_graph.to_string();
426 after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
429 after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
432 after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
435 after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
437 assert!(after.contains("619737530008010752"));
438 assert!(after.contains("783241506229452801"));
442 fn update_succeeds_when_duplicate_gossip_is_applied() {
443 let initialization_input = vec![
444 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
445 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
446 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
447 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
448 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
449 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
450 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
451 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
452 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
453 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
454 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,
455 0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
456 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,
457 68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
461 let block_hash = genesis_block(Network::Bitcoin).block_hash();
462 let logger = TestLogger::new();
463 let network_graph = NetworkGraph::new(block_hash, &logger);
465 assert_eq!(network_graph.read_only().channels().len(), 0);
467 let rapid_sync = RapidGossipSync::new(&network_graph);
468 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
469 assert!(initialization_result.is_ok());
471 let single_direction_incremental_update_input = vec![
472 76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
473 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
474 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,
475 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,
476 68, 226, 0, 6, 11, 0, 1, 128,
478 let update_result_1 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
479 // Apply duplicate update
480 let update_result_2 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
481 assert!(update_result_1.is_ok());
482 assert!(update_result_2.is_ok());
486 fn full_update_succeeds() {
487 let valid_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, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
500 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,
501 0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
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 update_result = rapid_sync.update_network_graph(&valid_input[..]);
513 if update_result.is_err() {
514 panic!("Unexpected update result: {:?}", update_result)
517 assert_eq!(network_graph.read_only().channels().len(), 2);
518 let after = network_graph.to_string();
520 after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
523 after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
526 after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
529 after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
531 assert!(after.contains("619737530008010752"));
532 assert!(after.contains("783241506229452801"));
536 pub fn update_fails_with_unknown_version() {
537 let unknown_version_input = vec![
538 76, 68, 75, 2, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
539 79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
540 0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
541 187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
542 157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
543 88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
544 204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
545 181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
546 110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
547 76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
548 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,
549 0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
550 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,
551 0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
555 let block_hash = genesis_block(Network::Bitcoin).block_hash();
556 let logger = TestLogger::new();
557 let network_graph = NetworkGraph::new(block_hash, &logger);
558 let rapid_sync = RapidGossipSync::new(&network_graph);
559 let update_result = rapid_sync.update_network_graph(&unknown_version_input[..]);
561 assert!(update_result.is_err());
563 if let Err(GraphSyncError::DecodeError(DecodeError::UnknownVersion)) = update_result {
564 // this is the expected error type
566 panic!("Unexpected update result: {:?}", update_result)