Remove empty match arm during prefix check
[rust-lightning] / lightning-rapid-gossip-sync / src / processing.rs
1 use core::cmp::max;
2 use core::ops::Deref;
3 use core::sync::atomic::Ordering;
4
5 use bitcoin::BlockHash;
6 use bitcoin::secp256k1::PublicKey;
7
8 use lightning::ln::msgs::{
9         DecodeError, ErrorAction, LightningError, UnsignedChannelUpdate,
10 };
11 use lightning::routing::gossip::NetworkGraph;
12 use lightning::util::logger::Logger;
13 use lightning::util::ser::{BigSize, Readable};
14 use lightning::io;
15
16 use crate::error::GraphSyncError;
17 use crate::RapidGossipSync;
18
19 #[cfg(not(feature = "std"))]
20 use alloc::{vec::Vec, borrow::ToOwned};
21
22 /// The purpose of this prefix is to identify the serialization format, should other rapid gossip
23 /// sync formats arise in the future.
24 ///
25 /// The fourth byte is the protocol version in case our format gets updated.
26 const GOSSIP_PREFIX: [u8; 4] = [76, 68, 75, 1];
27
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;
31
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>(
34                 &self,
35                 mut read_cursor: &mut R,
36         ) -> Result<u32, GraphSyncError> {
37                 let mut prefix = [0u8; 4];
38                 read_cursor.read_exact(&mut prefix)?;
39
40                 if prefix != GOSSIP_PREFIX {
41                         return Err(DecodeError::UnknownVersion.into());
42                 }
43
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);
48
49                 let node_id_count: u32 = Readable::read(read_cursor)?;
50                 let mut node_ids: Vec<PublicKey> = Vec::with_capacity(core::cmp::min(
51                         node_id_count,
52                         MAX_INITIAL_NODE_ID_VECTOR_CAPACITY,
53                 ) as usize);
54                 for _ in 0..node_id_count {
55                         let current_node_id = Readable::read(read_cursor)?;
56                         node_ids.push(current_node_id);
57                 }
58
59                 let network_graph = &self.network_graph;
60
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)?;
65
66                         // handle SCID
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;
72
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());
77                         };
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];
80
81                         let announcement_result = network_graph.add_channel_from_partial_announcement(
82                                 short_channel_id,
83                                 backdated_timestamp as u64,
84                                 features,
85                                 node_id_1,
86                                 node_id_2,
87                         );
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
91                                 } else {
92                                         return Err(lightning_error.into());
93                                 }
94                         }
95                 }
96
97                 previous_scid = 0; // updates start at a new scid
98
99                 let update_count: u32 = Readable::read(read_cursor)?;
100                 if update_count == 0 {
101                         return Ok(latest_seen_timestamp);
102                 }
103
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)?;
110
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;
117
118                         let channel_flags: u8 = Readable::read(read_cursor)?;
119
120                         // flags are always sent in full, and hence always need updating
121                         let standard_channel_flags = channel_flags & 0b_0000_0011;
122
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 {
126                                         chain_hash,
127                                         short_channel_id,
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(),
136                                 }
137                         } else {
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
141                                         .channels()
142                                         .get(&short_channel_id)
143                                         .ok_or(LightningError {
144                                                 err: "Couldn't find channel for update".to_owned(),
145                                                 action: ErrorAction::IgnoreError,
146                                         })?;
147
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,
153                                         })?;
154
155                                 UnsignedChannelUpdate {
156                                         chain_hash,
157                                         short_channel_id,
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(),
166                                 }
167                         };
168
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;
172                         }
173
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;
177                         }
178
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;
182                         }
183
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;
187                         }
188
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;
192                         }
193
194                         match network_graph.update_channel_unsigned(&synthetic_update) {
195                                 Ok(_) => {},
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()),
200                         }
201                 }
202
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)
206         }
207 }
208
209 #[cfg(test)]
210 mod tests {
211         use bitcoin::blockdata::constants::genesis_block;
212         use bitcoin::Network;
213
214         use lightning::ln::msgs::DecodeError;
215         use lightning::routing::gossip::NetworkGraph;
216         use lightning::util::test_utils::TestLogger;
217
218         use crate::error::GraphSyncError;
219         use crate::RapidGossipSync;
220
221         #[test]
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);
226
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,
241                         0, 3, 232, 0, 0, 0,
242                 ];
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
248                 } else {
249                         panic!("Unexpected update result: {:?}", update_result)
250                 }
251         }
252
253         #[test]
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,
261                 ];
262
263                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
264                 let logger = TestLogger::new();
265                 let network_graph = NetworkGraph::new(block_hash, &logger);
266
267                 assert_eq!(network_graph.read_only().channels().len(), 0);
268
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");
274                 } else {
275                         panic!("Unexpected update result: {:?}", update_result)
276                 }
277         }
278
279         #[test]
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,
295                 ];
296
297                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
298                 let logger = TestLogger::new();
299                 let network_graph = NetworkGraph::new(block_hash, &logger);
300
301                 assert_eq!(network_graph.read_only().channels().len(), 0);
302
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 {
307                         assert_eq!(
308                                 lightning_error.err,
309                                 "Couldn't find previous directional data for update"
310                         );
311                 } else {
312                         panic!("Unexpected update result: {:?}", update_result)
313                 }
314         }
315
316         #[test]
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,
332                 ];
333
334                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
335                 let logger = TestLogger::new();
336                 let network_graph = NetworkGraph::new(block_hash, &logger);
337
338                 assert_eq!(network_graph.read_only().channels().len(), 0);
339
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() {
343                         panic!(
344                                 "Unexpected initialization result: {:?}",
345                                 initialization_result
346                         )
347                 }
348
349                 assert_eq!(network_graph.read_only().channels().len(), 2);
350                 let initialized = network_graph.to_string();
351                 assert!(initialized
352                         .contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643"));
353                 assert!(initialized
354                         .contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b"));
355                 assert!(initialized
356                         .contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432"));
357                 assert!(initialized
358                         .contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61"));
359                 assert!(initialized.contains("619737530008010752"));
360                 assert!(initialized.contains("783241506229452801"));
361
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,
368                 ];
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 {
372                         assert_eq!(
373                                 lightning_error.err,
374                                 "Couldn't find previous directional data for update"
375                         );
376                 } else {
377                         panic!("Unexpected update result: {:?}", update_result)
378                 }
379         }
380
381         #[test]
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,
398                         25, 192,
399                 ];
400
401                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
402                 let logger = TestLogger::new();
403                 let network_graph = NetworkGraph::new(block_hash, &logger);
404
405                 assert_eq!(network_graph.read_only().channels().len(), 0);
406
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());
410
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,
417                 ];
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)
421                 }
422
423                 assert_eq!(network_graph.read_only().channels().len(), 2);
424                 let after = network_graph.to_string();
425                 assert!(
426                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
427                 );
428                 assert!(
429                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
430                 );
431                 assert!(
432                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
433                 );
434                 assert!(
435                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
436                 );
437                 assert!(after.contains("619737530008010752"));
438                 assert!(after.contains("783241506229452801"));
439         }
440
441         #[test]
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,
458                         25, 192,
459                 ];
460
461                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
462                 let logger = TestLogger::new();
463                 let network_graph = NetworkGraph::new(block_hash, &logger);
464
465                 assert_eq!(network_graph.read_only().channels().len(), 0);
466
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());
470
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,
477                 ];
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());
483         }
484
485         #[test]
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,
502                         0, 0, 1,
503                 ];
504
505                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
506                 let logger = TestLogger::new();
507                 let network_graph = NetworkGraph::new(block_hash, &logger);
508
509                 assert_eq!(network_graph.read_only().channels().len(), 0);
510
511                 let rapid_sync = RapidGossipSync::new(&network_graph);
512                 let update_result = rapid_sync.update_network_graph(&valid_input[..]);
513                 if update_result.is_err() {
514                         panic!("Unexpected update result: {:?}", update_result)
515                 }
516
517                 assert_eq!(network_graph.read_only().channels().len(), 2);
518                 let after = network_graph.to_string();
519                 assert!(
520                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
521                 );
522                 assert!(
523                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
524                 );
525                 assert!(
526                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
527                 );
528                 assert!(
529                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
530                 );
531                 assert!(after.contains("619737530008010752"));
532                 assert!(after.contains("783241506229452801"));
533         }
534
535         #[test]
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,
552                         0, 0, 1,
553                 ];
554
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[..]);
560
561                 assert!(update_result.is_err());
562
563                 if let Err(GraphSyncError::DecodeError(DecodeError::UnknownVersion)) = update_result {
564                         // this is the expected error type
565                 } else {
566                         panic!("Unexpected update result: {:?}", update_result)
567                 }
568         }
569 }