]> git.bitcoin.ninja Git - rust-lightning/blob - lightning-rapid-gossip-sync/src/processing.rs
3e001ec45c4be1aa7becbaa6da9f9158f3d217fa
[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
76                         if max(node_id_1_index.0, node_id_2_index.0) >= node_id_count as u64 {
77                                 return Err(DecodeError::InvalidValue.into());
78                         };
79                         let node_id_1 = node_ids[node_id_1_index.0 as usize];
80                         let node_id_2 = node_ids[node_id_2_index.0 as usize];
81
82                         let announcement_result = network_graph.add_channel_from_partial_announcement(
83                                 short_channel_id,
84                                 backdated_timestamp as u64,
85                                 features,
86                                 node_id_1,
87                                 node_id_2,
88                         );
89                         if let Err(lightning_error) = announcement_result {
90                                 if let ErrorAction::IgnoreDuplicateGossip = lightning_error.action {
91                                         // everything is fine, just a duplicate channel announcement
92                                 } else {
93                                         return Err(lightning_error.into());
94                                 }
95                         }
96                 }
97
98                 previous_scid = 0; // updates start at a new scid
99
100                 let update_count: u32 = Readable::read(read_cursor)?;
101                 if update_count == 0 {
102                         return Ok(latest_seen_timestamp);
103                 }
104
105                 // obtain default values for non-incremental updates
106                 let default_cltv_expiry_delta: u16 = Readable::read(&mut read_cursor)?;
107                 let default_htlc_minimum_msat: u64 = Readable::read(&mut read_cursor)?;
108                 let default_fee_base_msat: u32 = Readable::read(&mut read_cursor)?;
109                 let default_fee_proportional_millionths: u32 = Readable::read(&mut read_cursor)?;
110                 let default_htlc_maximum_msat: u64 = Readable::read(&mut read_cursor)?;
111
112                 for _ in 0..update_count {
113                         let scid_delta: BigSize = Readable::read(read_cursor)?;
114                         let short_channel_id = previous_scid
115                                 .checked_add(scid_delta.0)
116                                 .ok_or(DecodeError::InvalidValue)?;
117                         previous_scid = short_channel_id;
118
119                         let channel_flags: u8 = Readable::read(read_cursor)?;
120
121                         // flags are always sent in full, and hence always need updating
122                         let standard_channel_flags = channel_flags & 0b_0000_0011;
123
124                         let mut synthetic_update = UnsignedChannelUpdate {
125                                 chain_hash,
126                                 short_channel_id,
127                                 timestamp: backdated_timestamp,
128                                 flags: standard_channel_flags,
129                                 cltv_expiry_delta: default_cltv_expiry_delta,
130                                 htlc_minimum_msat: default_htlc_minimum_msat,
131                                 htlc_maximum_msat: default_htlc_maximum_msat,
132                                 fee_base_msat: default_fee_base_msat,
133                                 fee_proportional_millionths: default_fee_proportional_millionths,
134                                 excess_data: Vec::new(),
135                         };
136
137                         let mut skip_update_for_unknown_channel = false;
138
139                         if (channel_flags & 0b_1000_0000) != 0 {
140                                 // incremental update, field flags will indicate mutated values
141                                 let read_only_network_graph = network_graph.read_only();
142                                 if let Some(channel) = read_only_network_graph
143                                         .channels()
144                                         .get(&short_channel_id) {
145
146                                         let directional_info = channel
147                                                 .get_directional_info(channel_flags)
148                                                 .ok_or(LightningError {
149                                                         err: "Couldn't find previous directional data for update".to_owned(),
150                                                         action: ErrorAction::IgnoreError,
151                                                 })?;
152
153                                         synthetic_update.cltv_expiry_delta = directional_info.cltv_expiry_delta;
154                                         synthetic_update.htlc_minimum_msat = directional_info.htlc_minimum_msat;
155                                         synthetic_update.htlc_maximum_msat = directional_info.htlc_maximum_msat;
156                                         synthetic_update.fee_base_msat = directional_info.fees.base_msat;
157                                         synthetic_update.fee_proportional_millionths = directional_info.fees.proportional_millionths;
158
159                                 } else {
160                                         skip_update_for_unknown_channel = true;
161                                 }
162                         };
163
164                         if channel_flags & 0b_0100_0000 > 0 {
165                                 let cltv_expiry_delta: u16 = Readable::read(read_cursor)?;
166                                 synthetic_update.cltv_expiry_delta = cltv_expiry_delta;
167                         }
168
169                         if channel_flags & 0b_0010_0000 > 0 {
170                                 let htlc_minimum_msat: u64 = Readable::read(read_cursor)?;
171                                 synthetic_update.htlc_minimum_msat = htlc_minimum_msat;
172                         }
173
174                         if channel_flags & 0b_0001_0000 > 0 {
175                                 let fee_base_msat: u32 = Readable::read(read_cursor)?;
176                                 synthetic_update.fee_base_msat = fee_base_msat;
177                         }
178
179                         if channel_flags & 0b_0000_1000 > 0 {
180                                 let fee_proportional_millionths: u32 = Readable::read(read_cursor)?;
181                                 synthetic_update.fee_proportional_millionths = fee_proportional_millionths;
182                         }
183
184                         if channel_flags & 0b_0000_0100 > 0 {
185                                 let htlc_maximum_msat: u64 = Readable::read(read_cursor)?;
186                                 synthetic_update.htlc_maximum_msat = htlc_maximum_msat;
187                         }
188
189                         if skip_update_for_unknown_channel {
190                                 continue;
191                         }
192
193                         match network_graph.update_channel_unsigned(&synthetic_update) {
194                                 Ok(_) => {},
195                                 Err(LightningError { action: ErrorAction::IgnoreDuplicateGossip, .. }) => {},
196                                 Err(LightningError { action: ErrorAction::IgnoreAndLog(_), .. }) => {},
197                                 Err(LightningError { action: ErrorAction::IgnoreError, .. }) => {},
198                                 Err(e) => return Err(e.into()),
199                         }
200                 }
201
202                 self.network_graph.set_last_rapid_gossip_sync_timestamp(latest_seen_timestamp);
203                 self.is_initial_sync_complete.store(true, Ordering::Release);
204                 Ok(latest_seen_timestamp)
205         }
206 }
207
208 #[cfg(test)]
209 mod tests {
210         use bitcoin::blockdata::constants::genesis_block;
211         use bitcoin::Network;
212
213         use lightning::ln::msgs::DecodeError;
214         use lightning::routing::gossip::NetworkGraph;
215         use lightning::util::test_utils::TestLogger;
216
217         use crate::error::GraphSyncError;
218         use crate::RapidGossipSync;
219
220         #[test]
221         fn network_graph_fails_to_update_from_clipped_input() {
222                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
223                 let logger = TestLogger::new();
224                 let network_graph = NetworkGraph::new(block_hash, &logger);
225
226                 let example_input = vec![
227                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
228                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
229                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
230                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
231                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
232                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
233                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
234                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
235                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
236                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
237                         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,
238                         0, 0, 2, 224, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 36, 0, 0,
239                         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,
240                         0, 3, 232, 0, 0, 0,
241                 ];
242                 let rapid_sync = RapidGossipSync::new(&network_graph);
243                 let update_result = rapid_sync.update_network_graph(&example_input[..]);
244                 assert!(update_result.is_err());
245                 if let Err(GraphSyncError::DecodeError(DecodeError::ShortRead)) = update_result {
246                         // this is the expected error type
247                 } else {
248                         panic!("Unexpected update result: {:?}", update_result)
249                 }
250         }
251
252         #[test]
253         fn incremental_only_update_ignores_missing_channel() {
254                 let incremental_update_input = vec![
255                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
256                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
257                         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,
258                         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,
259                         68, 226, 0, 6, 11, 0, 1, 128,
260                 ];
261
262                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
263                 let logger = TestLogger::new();
264                 let network_graph = NetworkGraph::new(block_hash, &logger);
265
266                 assert_eq!(network_graph.read_only().channels().len(), 0);
267
268                 let rapid_sync = RapidGossipSync::new(&network_graph);
269                 let update_result = rapid_sync.update_network_graph(&incremental_update_input[..]);
270                 assert!(update_result.is_ok());
271         }
272
273         #[test]
274         fn incremental_only_update_fails_without_prior_updates() {
275                 let announced_update_input = vec![
276                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
277                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
278                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
279                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
280                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
281                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
282                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
283                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
284                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
285                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
286                         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,
287                         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,
288                         2, 68, 226, 0, 6, 11, 0, 1, 128,
289                 ];
290
291                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
292                 let logger = TestLogger::new();
293                 let network_graph = NetworkGraph::new(block_hash, &logger);
294
295                 assert_eq!(network_graph.read_only().channels().len(), 0);
296
297                 let rapid_sync = RapidGossipSync::new(&network_graph);
298                 let update_result = rapid_sync.update_network_graph(&announced_update_input[..]);
299                 assert!(update_result.is_err());
300                 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
301                         assert_eq!(
302                                 lightning_error.err,
303                                 "Couldn't find previous directional data for update"
304                         );
305                 } else {
306                         panic!("Unexpected update result: {:?}", update_result)
307                 }
308         }
309
310         #[test]
311         fn incremental_only_update_fails_without_prior_same_direction_updates() {
312                 let initialization_input = vec![
313                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
314                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
315                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
316                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
317                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
318                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
319                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
320                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
321                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
322                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
323                         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,
324                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 25, 0, 0,
325                         0, 1, 0, 0, 0, 125, 255, 2, 68, 226, 0, 6, 11, 0, 1, 5, 0, 0, 0, 0, 29, 129, 25, 192,
326                 ];
327
328                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
329                 let logger = TestLogger::new();
330                 let network_graph = NetworkGraph::new(block_hash, &logger);
331
332                 assert_eq!(network_graph.read_only().channels().len(), 0);
333
334                 let rapid_sync = RapidGossipSync::new(&network_graph);
335                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
336                 if initialization_result.is_err() {
337                         panic!(
338                                 "Unexpected initialization result: {:?}",
339                                 initialization_result
340                         )
341                 }
342
343                 assert_eq!(network_graph.read_only().channels().len(), 2);
344                 let initialized = network_graph.to_string();
345                 assert!(initialized
346                         .contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643"));
347                 assert!(initialized
348                         .contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b"));
349                 assert!(initialized
350                         .contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432"));
351                 assert!(initialized
352                         .contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61"));
353                 assert!(initialized.contains("619737530008010752"));
354                 assert!(initialized.contains("783241506229452801"));
355
356                 let opposite_direction_incremental_update_input = vec![
357                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
358                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
359                         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,
360                         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,
361                         68, 226, 0, 6, 11, 0, 1, 128,
362                 ];
363                 let update_result = rapid_sync.update_network_graph(&opposite_direction_incremental_update_input[..]);
364                 assert!(update_result.is_err());
365                 if let Err(GraphSyncError::LightningError(lightning_error)) = update_result {
366                         assert_eq!(
367                                 lightning_error.err,
368                                 "Couldn't find previous directional data for update"
369                         );
370                 } else {
371                         panic!("Unexpected update result: {:?}", update_result)
372                 }
373         }
374
375         #[test]
376         fn incremental_update_succeeds_with_prior_announcements_and_full_updates() {
377                 let initialization_input = vec![
378                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
379                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
380                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
381                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
382                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
383                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
384                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
385                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
386                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
387                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
388                         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,
389                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
390                         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,
391                         68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
392                         25, 192,
393                 ];
394
395                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
396                 let logger = TestLogger::new();
397                 let network_graph = NetworkGraph::new(block_hash, &logger);
398
399                 assert_eq!(network_graph.read_only().channels().len(), 0);
400
401                 let rapid_sync = RapidGossipSync::new(&network_graph);
402                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
403                 assert!(initialization_result.is_ok());
404
405                 let single_direction_incremental_update_input = vec![
406                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
407                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
408                         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,
409                         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,
410                         68, 226, 0, 6, 11, 0, 1, 128,
411                 ];
412                 let update_result = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
413                 if update_result.is_err() {
414                         panic!("Unexpected update result: {:?}", update_result)
415                 }
416
417                 assert_eq!(network_graph.read_only().channels().len(), 2);
418                 let after = network_graph.to_string();
419                 assert!(
420                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
421                 );
422                 assert!(
423                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
424                 );
425                 assert!(
426                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
427                 );
428                 assert!(
429                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
430                 );
431                 assert!(after.contains("619737530008010752"));
432                 assert!(after.contains("783241506229452801"));
433         }
434
435         #[test]
436         fn update_succeeds_when_duplicate_gossip_is_applied() {
437                 let initialization_input = vec![
438                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
439                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
440                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
441                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
442                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
443                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
444                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
445                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
446                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
447                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
448                         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,
449                         0, 0, 0, 1, 0, 0, 0, 0, 58, 85, 116, 216, 255, 8, 153, 192, 0, 2, 27, 0, 0, 56, 0, 0,
450                         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,
451                         68, 226, 0, 6, 11, 0, 1, 4, 0, 0, 0, 0, 29, 129, 25, 192, 0, 5, 0, 0, 0, 0, 29, 129,
452                         25, 192,
453                 ];
454
455                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
456                 let logger = TestLogger::new();
457                 let network_graph = NetworkGraph::new(block_hash, &logger);
458
459                 assert_eq!(network_graph.read_only().channels().len(), 0);
460
461                 let rapid_sync = RapidGossipSync::new(&network_graph);
462                 let initialization_result = rapid_sync.update_network_graph(&initialization_input[..]);
463                 assert!(initialization_result.is_ok());
464
465                 let single_direction_incremental_update_input = vec![
466                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
467                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 229, 183, 167,
468                         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,
469                         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,
470                         68, 226, 0, 6, 11, 0, 1, 128,
471                 ];
472                 let update_result_1 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
473                 // Apply duplicate update
474                 let update_result_2 = rapid_sync.update_network_graph(&single_direction_incremental_update_input[..]);
475                 assert!(update_result_1.is_ok());
476                 assert!(update_result_2.is_ok());
477         }
478
479         #[test]
480         fn full_update_succeeds() {
481                 let valid_input = vec![
482                         76, 68, 75, 1, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
483                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
484                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
485                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
486                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
487                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
488                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
489                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
490                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
491                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
492                         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,
493                         0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
494                         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,
495                         0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
496                         0, 0, 1,
497                 ];
498
499                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
500                 let logger = TestLogger::new();
501                 let network_graph = NetworkGraph::new(block_hash, &logger);
502
503                 assert_eq!(network_graph.read_only().channels().len(), 0);
504
505                 let rapid_sync = RapidGossipSync::new(&network_graph);
506                 let update_result = rapid_sync.update_network_graph(&valid_input[..]);
507                 if update_result.is_err() {
508                         panic!("Unexpected update result: {:?}", update_result)
509                 }
510
511                 assert_eq!(network_graph.read_only().channels().len(), 2);
512                 let after = network_graph.to_string();
513                 assert!(
514                         after.contains("021607cfce19a4c5e7e6e738663dfafbbbac262e4ff76c2c9b30dbeefc35c00643")
515                 );
516                 assert!(
517                         after.contains("02247d9db0dfafea745ef8c9e161eb322f73ac3f8858d8730b6fd97254747ce76b")
518                 );
519                 assert!(
520                         after.contains("029e01f279986acc83ba235d46d80aede0b7595f410353b93a8ab540bb677f4432")
521                 );
522                 assert!(
523                         after.contains("02c913118a8895b9e29c89af6e20ed00d95a1f64e4952edbafa84d048f26804c61")
524                 );
525                 assert!(after.contains("619737530008010752"));
526                 assert!(after.contains("783241506229452801"));
527         }
528
529         #[test]
530         pub fn update_fails_with_unknown_version() {
531                 let unknown_version_input = vec![
532                         76, 68, 75, 2, 111, 226, 140, 10, 182, 241, 179, 114, 193, 166, 162, 70, 174, 99, 247,
533                         79, 147, 30, 131, 101, 225, 90, 8, 156, 104, 214, 25, 0, 0, 0, 0, 0, 97, 227, 98, 218,
534                         0, 0, 0, 4, 2, 22, 7, 207, 206, 25, 164, 197, 231, 230, 231, 56, 102, 61, 250, 251,
535                         187, 172, 38, 46, 79, 247, 108, 44, 155, 48, 219, 238, 252, 53, 192, 6, 67, 2, 36, 125,
536                         157, 176, 223, 175, 234, 116, 94, 248, 201, 225, 97, 235, 50, 47, 115, 172, 63, 136,
537                         88, 216, 115, 11, 111, 217, 114, 84, 116, 124, 231, 107, 2, 158, 1, 242, 121, 152, 106,
538                         204, 131, 186, 35, 93, 70, 216, 10, 237, 224, 183, 89, 95, 65, 3, 83, 185, 58, 138,
539                         181, 64, 187, 103, 127, 68, 50, 2, 201, 19, 17, 138, 136, 149, 185, 226, 156, 137, 175,
540                         110, 32, 237, 0, 217, 90, 31, 100, 228, 149, 46, 219, 175, 168, 77, 4, 143, 38, 128,
541                         76, 97, 0, 0, 0, 2, 0, 0, 255, 8, 153, 192, 0, 2, 27, 0, 0, 0, 1, 0, 0, 255, 2, 68,
542                         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,
543                         0, 0, 0, 1, 0, 0, 0, 0, 29, 129, 25, 192, 255, 8, 153, 192, 0, 2, 27, 0, 0, 60, 0, 0,
544                         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,
545                         0, 0, 1, 0, 0, 0, 125, 0, 0, 0, 0, 58, 85, 116, 216, 255, 2, 68, 226, 0, 6, 11, 0, 1,
546                         0, 0, 1,
547                 ];
548
549                 let block_hash = genesis_block(Network::Bitcoin).block_hash();
550                 let logger = TestLogger::new();
551                 let network_graph = NetworkGraph::new(block_hash, &logger);
552                 let rapid_sync = RapidGossipSync::new(&network_graph);
553                 let update_result = rapid_sync.update_network_graph(&unknown_version_input[..]);
554
555                 assert!(update_result.is_err());
556
557                 if let Err(GraphSyncError::DecodeError(DecodeError::UnknownVersion)) = update_result {
558                         // this is the expected error type
559                 } else {
560                         panic!("Unexpected update result: {:?}", update_result)
561                 }
562         }
563 }