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