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