Indicate ongoing rapid sync to background processor.
[rust-lightning] / lightning-rapid-gossip-sync / src / processing.rs
1 use std::cmp::max;
2 use std::io;
3 use std::io::Read;
4 use std::ops::Deref;
5 use std::sync::atomic::Ordering;
6
7 use bitcoin::BlockHash;
8 use bitcoin::secp256k1::PublicKey;
9
10 use lightning::ln::msgs::{
11         DecodeError, ErrorAction, LightningError, OptionalField, UnsignedChannelUpdate,
12 };
13 use lightning::routing::network_graph::NetworkGraph;
14 use lightning::util::ser::{BigSize, Readable};
15
16 use crate::error::GraphSyncError;
17 use crate::RapidGossipSync;
18
19 /// The purpose of this prefix is to identify the serialization format, should other rapid gossip
20 /// sync formats arise in the future.
21 ///
22 /// The fourth byte is the protocol version in case our format gets updated.
23 const GOSSIP_PREFIX: [u8; 4] = [76, 68, 75, 1];
24
25 /// Maximum vector allocation capacity for distinct node IDs. This constraint is necessary to
26 /// avoid malicious updates being able to trigger excessive memory allocation.
27 const MAX_INITIAL_NODE_ID_VECTOR_CAPACITY: u32 = 50_000;
28
29 impl<NG: Deref<Target=NetworkGraph>> RapidGossipSync<NG> {
30         /// Update network graph from binary data.
31         /// Returns the last sync timestamp to be used the next time rapid sync data is queried.
32         ///
33         /// `network_graph`: network graph to be updated
34         ///
35         /// `update_data`: `&[u8]` binary stream that comprises the update data
36         pub fn update_network_graph(&self, update_data: &[u8]) -> Result<u32, GraphSyncError> {
37                 let mut read_cursor = io::Cursor::new(update_data);
38                 self.update_network_graph_from_byte_stream(&mut read_cursor)
39         }
40
41
42         pub(crate) fn update_network_graph_from_byte_stream<R: Read>(
43                 &self,
44                 mut read_cursor: &mut R,
45         ) -> Result<u32, GraphSyncError> {
46                 let mut prefix = [0u8; 4];
47                 read_cursor.read_exact(&mut prefix)?;
48
49                 match prefix {
50                         GOSSIP_PREFIX => {}
51                         _ => {
52                                 return Err(DecodeError::UnknownVersion.into());
53                         }
54                 };
55
56                 let chain_hash: BlockHash = Readable::read(read_cursor)?;
57                 let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
58                 // backdate the applied timestamp by a week
59                 let backdated_timestamp = latest_seen_timestamp.saturating_sub(24 * 3600 * 7);
60
61                 let node_id_count: u32 = Readable::read(read_cursor)?;
62                 let mut node_ids: Vec<PublicKey> = Vec::with_capacity(std::cmp::min(
63                         node_id_count,
64                         MAX_INITIAL_NODE_ID_VECTOR_CAPACITY,
65                 ) as usize);
66                 for _ in 0..node_id_count {
67                         let current_node_id = Readable::read(read_cursor)?;
68                         node_ids.push(current_node_id);
69                 }
70
71                 let network_graph = &self.network_graph;
72
73                 let mut previous_scid: u64 = 0;
74                 let announcement_count: u32 = Readable::read(read_cursor)?;
75                 for _ in 0..announcement_count {
76                         let features = Readable::read(read_cursor)?;
77
78                         // handle SCID
79                         let scid_delta: BigSize = Readable::read(read_cursor)?;
80                         let short_channel_id = previous_scid
81                                 .checked_add(scid_delta.0)
82                                 .ok_or(DecodeError::InvalidValue)?;
83                         previous_scid = short_channel_id;
84
85                         let node_id_1_index: BigSize = Readable::read(read_cursor)?;
86                         let node_id_2_index: BigSize = Readable::read(read_cursor)?;
87                         if max(node_id_1_index.0, node_id_2_index.0) >= node_id_count as u64 {
88                                 return Err(DecodeError::InvalidValue.into());
89                         };
90                         let node_id_1 = node_ids[node_id_1_index.0 as usize];
91                         let node_id_2 = node_ids[node_id_2_index.0 as usize];
92
93                         let announcement_result = network_graph.add_channel_from_partial_announcement(
94                                 short_channel_id,
95                                 backdated_timestamp as u64,
96                                 features,
97                                 node_id_1,
98                                 node_id_2,
99                         );
100                         if let Err(lightning_error) = announcement_result {
101                                 if let ErrorAction::IgnoreDuplicateGossip = lightning_error.action {
102                                         // everything is fine, just a duplicate channel announcement
103                                 } else {
104                                         return Err(lightning_error.into());
105                                 }
106                         }
107                 }
108
109                 previous_scid = 0; // updates start at a new scid
110
111                 let update_count: u32 = Readable::read(read_cursor)?;
112                 if update_count == 0 {
113                         return Ok(latest_seen_timestamp);
114                 }
115
116                 // obtain default values for non-incremental updates
117                 let default_cltv_expiry_delta: u16 = Readable::read(&mut read_cursor)?;
118                 let default_htlc_minimum_msat: u64 = Readable::read(&mut read_cursor)?;
119                 let default_fee_base_msat: u32 = Readable::read(&mut read_cursor)?;
120                 let default_fee_proportional_millionths: u32 = Readable::read(&mut read_cursor)?;
121                 let tentative_default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?;
122                 let default_htlc_maximum_msat = if tentative_default_htlc_maximum_msat == u64::max_value() {
123                         OptionalField::Absent
124                 } else {
125                         OptionalField::Present(tentative_default_htlc_maximum_msat)
126                 };
127
128                 for _ in 0..update_count {
129                         let scid_delta: BigSize = Readable::read(read_cursor)?;
130                         let short_channel_id = previous_scid
131                                 .checked_add(scid_delta.0)
132                                 .ok_or(DecodeError::InvalidValue)?;
133                         previous_scid = short_channel_id;
134
135                         let channel_flags: u8 = Readable::read(read_cursor)?;
136
137                         // flags are always sent in full, and hence always need updating
138                         let standard_channel_flags = channel_flags & 0b_0000_0011;
139
140                         let mut synthetic_update = if channel_flags & 0b_1000_0000 == 0 {
141                                 // full update, field flags will indicate deviations from the default
142                                 UnsignedChannelUpdate {
143                                         chain_hash,
144                                         short_channel_id,
145                                         timestamp: backdated_timestamp,
146                                         flags: standard_channel_flags,
147                                         cltv_expiry_delta: default_cltv_expiry_delta,
148                                         htlc_minimum_msat: default_htlc_minimum_msat,
149                                         htlc_maximum_msat: default_htlc_maximum_msat.clone(),
150                                         fee_base_msat: default_fee_base_msat,
151                                         fee_proportional_millionths: default_fee_proportional_millionths,
152                                         excess_data: vec![],
153                                 }
154                         } else {
155                                 // incremental update, field flags will indicate mutated values
156                                 let read_only_network_graph = network_graph.read_only();
157                                 let channel = read_only_network_graph
158                                         .channels()
159                                         .get(&short_channel_id)
160                                         .ok_or(LightningError {
161                                                 err: "Couldn't find channel for update".to_owned(),
162                                                 action: ErrorAction::IgnoreError,
163                                         })?;
164
165                                 let directional_info = channel
166                                         .get_directional_info(channel_flags)
167                                         .ok_or(LightningError {
168                                                 err: "Couldn't find previous directional data for update".to_owned(),
169                                                 action: ErrorAction::IgnoreError,
170                                         })?;
171
172                                 let htlc_maximum_msat =
173                                         if let Some(htlc_maximum_msat) = directional_info.htlc_maximum_msat {
174                                                 OptionalField::Present(htlc_maximum_msat)
175                                         } else {
176                                                 OptionalField::Absent
177                                         };
178
179                                 UnsignedChannelUpdate {
180                                         chain_hash,
181                                         short_channel_id,
182                                         timestamp: backdated_timestamp,
183                                         flags: standard_channel_flags,
184                                         cltv_expiry_delta: directional_info.cltv_expiry_delta,
185                                         htlc_minimum_msat: directional_info.htlc_minimum_msat,
186                                         htlc_maximum_msat,
187                                         fee_base_msat: directional_info.fees.base_msat,
188                                         fee_proportional_millionths: directional_info.fees.proportional_millionths,
189                                         excess_data: vec![],
190                                 }
191                         };
192
193                         if channel_flags & 0b_0100_0000 > 0 {
194                                 let cltv_expiry_delta: u16 = Readable::read(read_cursor)?;
195                                 synthetic_update.cltv_expiry_delta = cltv_expiry_delta;
196                         }
197
198                         if channel_flags & 0b_0010_0000 > 0 {
199                                 let htlc_minimum_msat: u64 = Readable::read(read_cursor)?;
200                                 synthetic_update.htlc_minimum_msat = htlc_minimum_msat;
201                         }
202
203                         if channel_flags & 0b_0001_0000 > 0 {
204                                 let fee_base_msat: u32 = Readable::read(read_cursor)?;
205                                 synthetic_update.fee_base_msat = fee_base_msat;
206                         }
207
208                         if channel_flags & 0b_0000_1000 > 0 {
209                                 let fee_proportional_millionths: u32 = Readable::read(read_cursor)?;
210                                 synthetic_update.fee_proportional_millionths = fee_proportional_millionths;
211                         }
212
213                         if channel_flags & 0b_0000_0100 > 0 {
214                                 let tentative_htlc_maximum_msat: u64 = Readable::read(read_cursor)?;
215                                 synthetic_update.htlc_maximum_msat = if tentative_htlc_maximum_msat == u64::max_value()
216                                 {
217                                         OptionalField::Absent
218                                 } else {
219                                         OptionalField::Present(tentative_htlc_maximum_msat)
220                                 };
221                         }
222
223                         network_graph.update_channel_unsigned(&synthetic_update)?;
224                 }
225
226                 self.network_graph.set_last_rapid_gossip_sync_timestamp(latest_seen_timestamp);
227                 self.is_initial_sync_complete.store(true, Ordering::Release);
228                 Ok(latest_seen_timestamp)
229         }
230 }
231
232 #[cfg(test)]
233 mod tests {
234         use bitcoin::blockdata::constants::genesis_block;
235         use bitcoin::Network;
236
237         use lightning::ln::msgs::DecodeError;
238         use lightning::routing::network_graph::NetworkGraph;
239
240         use crate::error::GraphSyncError;
241         use crate::RapidGossipSync;
242
243         #[test]
244         fn network_graph_fails_to_update_from_clipped_input() {
245                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
246                 let network_graph = NetworkGraph::new(block_hash);
247
248                 let example_input = vec![
249                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
250                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
251                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
252                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
253                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
254                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
255                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
256                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
257                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
258                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
259                         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,
260                         0, 0, 2, 224, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 36, 0, 0,
261                         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,
262                         0, 3, 232, 0, 0, 0,
263                 ];
264                 let rapid_sync = RapidGossipSync::new(&network_graph);
265                 let update_result = rapid_sync.update_network_graph(&example_input[..]);
266                 assert!(update_result.is_err());
267                 if let Err(GraphSyncError::DecodeError(DecodeError::ShortRead)) = update_result {
268                         // this is the expected error type
269                 } else {
270                         panic!("Unexpected update result: {:?}", update_result)
271                 }
272         }
273
274         #[test]
275         fn incremental_only_update_fails_without_prior_announcements() {
276                 let incremental_update_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, 229, 183, 167,
279                         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,
280                         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,
281                         68, 226, 0, 6, 11, 0, 1, 128,
282                 ];
283
284                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
285                 let network_graph = NetworkGraph::new(block_hash);
286
287                 assert_eq!(network_graph.read_only().channels().len(), 0);
288
289                 let rapid_sync = RapidGossipSync::new(&network_graph);
290                 let update_result = rapid_sync.update_network_graph(&incremental_update_input[..]);
291                 assert!(update_result.is_err());
292                 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
293                         assert_eq!(lightning_error.err, "Couldn't find channel for update");
294                 } else {
295                         panic!("Unexpected update result: {:?}", update_result)
296                 }
297         }
298
299         #[test]
300         fn incremental_only_update_fails_without_prior_updates() {
301                 let announced_update_input = vec![
302                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
303                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
304                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
305                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
306                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
307                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
308                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
309                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
310                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
311                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
312                         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,
313                         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,
314                         2, 68, 226, 0, 6, 11, 0, 1, 128,
315                 ];
316
317                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
318                 let network_graph = NetworkGraph::new(block_hash);
319
320                 assert_eq!(network_graph.read_only().channels().len(), 0);
321
322                 let rapid_sync = RapidGossipSync::new(&network_graph);
323                 let update_result = rapid_sync.update_network_graph(&announced_update_input[..]);
324                 assert!(update_result.is_err());
325                 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
326                         assert_eq!(
327                                 lightning_error.err,
328                                 "Couldn't find previous directional data for update"
329                         );
330                 } else {
331                         panic!("Unexpected update result: {:?}", update_result)
332                 }
333         }
334
335         #[test]
336         fn incremental_only_update_fails_without_prior_same_direction_updates() {
337                 let initialization_input = vec![
338                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
339                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
340                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
341                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
342                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
343                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
344                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
345                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
346                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
347                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
348                         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,
349                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
350                         0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
351                 ];
352
353                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
354                 let network_graph = NetworkGraph::new(block_hash);
355
356                 assert_eq!(network_graph.read_only().channels().len(), 0);
357
358                 let rapid_sync = RapidGossipSync::new(&network_graph);
359                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
360                 if initialization_result.is_err() {
361                         panic!(
362                                 "Unexpected initialization result: {:?}",
363                                 initialization_result
364                         )
365                 }
366
367                 assert_eq!(network_graph.read_only().channels().len(), 2);
368                 let initialized = network_graph.to_string();
369                 assert!(initialized
370                         .contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643"));
371                 assert!(initialized
372                         .contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b"));
373                 assert!(initialized
374                         .contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432"));
375                 assert!(initialized
376                         .contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61"));
377                 assert!(initialized.contains("619737530008010752"));
378                 assert!(initialized.contains("783241506229452801"));
379
380                 let opposite_direction_incremental_update_input = vec![
381                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
382                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
383                         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,
384                         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,
385                         68, 226, 0, 6, 11, 0, 1, 128,
386                 ];
387                 let update_result = rapid_sync.update_network_graph(&opposite_direction_incremental_update_input[..]);
388                 assert!(update_result.is_err());
389                 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
390                         assert_eq!(
391                                 lightning_error.err,
392                                 "Couldn't find previous directional data for update"
393                         );
394                 } else {
395                         panic!("Unexpected update result: {:?}", update_result)
396                 }
397         }
398
399         #[test]
400         fn incremental_update_succeeds_with_prior_announcements_and_full_updates() {
401                 let initialization_input = vec![
402                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
403                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
404                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
405                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
406                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
407                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
408                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
409                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
410                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
411                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
412                         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,
413                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
414                         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,
415                         68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
416                         25, 192,
417                 ];
418
419                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
420                 let network_graph = NetworkGraph::new(block_hash);
421
422                 assert_eq!(network_graph.read_only().channels().len(), 0);
423
424                 let rapid_sync = RapidGossipSync::new(&network_graph);
425                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
426                 assert!(initialization_result.is_ok());
427
428                 let single_direction_incremental_update_input = vec![
429                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
430                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
431                         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,
432                         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,
433                         68, 226, 0, 6, 11, 0, 1, 128,
434                 ];
435                 let update_result = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
436                 if update_result.is_err() {
437                         panic!("Unexpected update result: {:?}", update_result)
438                 }
439
440                 assert_eq!(network_graph.read_only().channels().len(), 2);
441                 let after = network_graph.to_string();
442                 assert!(
443                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
444                 );
445                 assert!(
446                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
447                 );
448                 assert!(
449                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
450                 );
451                 assert!(
452                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
453                 );
454                 assert!(after.contains("619737530008010752"));
455                 assert!(after.contains("783241506229452801"));
456         }
457
458         #[test]
459         fn full_update_succeeds() {
460                 let valid_input = vec![
461                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
462                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
463                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
464                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
465                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
466                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
467                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
468                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
469                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
470                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
471                         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,
472                         0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
473                         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,
474                         0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
475                         0, 0, 1,
476                 ];
477
478                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
479                 let network_graph = NetworkGraph::new(block_hash);
480
481                 assert_eq!(network_graph.read_only().channels().len(), 0);
482
483                 let rapid_sync = RapidGossipSync::new(&network_graph);
484                 let update_result = rapid_sync.update_network_graph(&valid_input[..]);
485                 if update_result.is_err() {
486                         panic!("Unexpected update result: {:?}", update_result)
487                 }
488
489                 assert_eq!(network_graph.read_only().channels().len(), 2);
490                 let after = network_graph.to_string();
491                 assert!(
492                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
493                 );
494                 assert!(
495                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
496                 );
497                 assert!(
498                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
499                 );
500                 assert!(
501                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
502                 );
503                 assert!(after.contains("619737530008010752"));
504                 assert!(after.contains("783241506229452801"));
505         }
506 }