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