@@ -5,10 +5,8 @@ use core::sync::atomic::Ordering;
55use bitcoin:: blockdata:: constants:: ChainHash ;
66use bitcoin:: secp256k1:: PublicKey ;
77
8- use lightning:: ln:: msgs:: {
9- DecodeError , ErrorAction , LightningError , UnsignedChannelUpdate ,
10- } ;
11- use lightning:: routing:: gossip:: NetworkGraph ;
8+ use lightning:: ln:: msgs:: { DecodeError , ErrorAction , LightningError , SocketAddress , UnsignedChannelUpdate , UnsignedNodeAnnouncement } ;
9+ use lightning:: routing:: gossip:: { NetworkGraph , NodeAlias , NodeId } ;
1210use lightning:: util:: logger:: Logger ;
1311use lightning:: { log_debug, log_warn, log_trace, log_given_level, log_gossip} ;
1412use lightning:: util:: ser:: { BigSize , Readable } ;
@@ -21,12 +19,14 @@ use std::time::{SystemTime, UNIX_EPOCH};
2119
2220#[ cfg( all( not( feature = "std" ) , not( test) ) ) ]
2321use alloc:: { vec:: Vec , borrow:: ToOwned } ;
22+ use lightning:: ln:: features:: NodeFeatures ;
23+ use lightning:: util:: hash_tables:: HashMap ;
2424
2525/// The purpose of this prefix is to identify the serialization format, should other rapid gossip
2626/// sync formats arise in the future.
2727///
2828/// The fourth byte is the protocol version in case our format gets updated.
29- const GOSSIP_PREFIX : [ u8 ; 4 ] = [ 76 , 68 , 75 , 1 ] ;
29+ const GOSSIP_PREFIX : [ u8 ; 3 ] = [ 76 , 68 , 75 ] ;
3030
3131/// Maximum vector allocation capacity for distinct node IDs. This constraint is necessary to
3232/// avoid malicious updates being able to trigger excessive memory allocation.
@@ -59,13 +59,22 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
5959 current_time_unix : Option < u64 >
6060 ) -> Result < u32 , GraphSyncError > {
6161 log_trace ! ( self . logger, "Processing RGS data..." ) ;
62- let mut prefix = [ 0u8 ; 4 ] ;
63- read_cursor . read_exact ( & mut prefix ) ? ;
62+ let mut protocol_prefix = [ 0u8 ; 3 ] ;
63+ let mut version_prefix = [ 0u8 ; 1 ] ;
6464
65- if prefix != GOSSIP_PREFIX {
65+ read_cursor. read_exact ( & mut protocol_prefix) ?;
66+ if protocol_prefix != GOSSIP_PREFIX {
6667 return Err ( DecodeError :: UnknownVersion . into ( ) ) ;
6768 }
6869
70+ read_cursor. read_exact ( & mut version_prefix) ?;
71+ let version = version_prefix[ 0 ] ;
72+ if version != 1 && version != 2 {
73+ return Err ( DecodeError :: UnknownVersion . into ( ) ) ;
74+ }
75+
76+ let parse_node_details = version == 2 ;
77+
6978 let chain_hash: ChainHash = Readable :: read ( read_cursor) ?;
7079 let ng_chain_hash = self . network_graph . get_chain_hash ( ) ;
7180 if chain_hash != ng_chain_hash {
@@ -88,14 +97,84 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
8897 // backdate the applied timestamp by a week
8998 let backdated_timestamp = latest_seen_timestamp. saturating_sub ( 24 * 3600 * 7 ) ;
9099
100+ let mut default_node_features = Vec :: new ( ) ;
101+ if parse_node_details {
102+ let default_feature_count: u8 = Readable :: read ( read_cursor) ?;
103+ for _ in 0 ..default_feature_count {
104+ let current_default_feature: NodeFeatures = Readable :: read ( read_cursor) ?;
105+ default_node_features. push ( current_default_feature) ;
106+ }
107+ } ;
108+
91109 let node_id_count: u32 = Readable :: read ( read_cursor) ?;
92110 let mut node_ids: Vec < PublicKey > = Vec :: with_capacity ( core:: cmp:: min (
93111 node_id_count,
94112 MAX_INITIAL_NODE_ID_VECTOR_CAPACITY ,
95113 ) as usize ) ;
114+ let mut node_modifications: HashMap < PublicKey , UnsignedNodeAnnouncement > = HashMap :: default ( ) ;
96115 for _ in 0 ..node_id_count {
97- let current_node_id = Readable :: read ( read_cursor) ?;
98- node_ids. push ( current_node_id) ;
116+ if parse_node_details {
117+ let mut pubkey_bytes = [ 0u8 ; 33 ] ;
118+ read_cursor. read_exact ( & mut pubkey_bytes) ?;
119+ let node_detail_flag = pubkey_bytes[ 0 ] ;
120+ let has_address_details = ( node_detail_flag & ( 1 << 2 ) ) > 0 ;
121+ let feature_detail_marker = ( node_detail_flag & ( 0b111 << 3 ) ) >> 3 ;
122+ let has_additional_data = ( node_detail_flag & ( 1 << 7 ) ) > 0 ;
123+ let key_parity = node_detail_flag & 0b_0000_0011 ;
124+ pubkey_bytes[ 0 ] = key_parity;
125+ let current_node_id = PublicKey :: from_slice ( & pubkey_bytes) . unwrap ( ) ;
126+ node_ids. push ( current_node_id) ;
127+
128+ let mut unsigned_node_announcement = UnsignedNodeAnnouncement {
129+ features : NodeFeatures :: empty ( ) ,
130+ timestamp : 0 ,
131+ node_id : NodeId :: from_pubkey ( & current_node_id) ,
132+ rgb : [ 0 , 0 , 0 ] ,
133+ alias : NodeAlias ( [ 0u8 ; 32 ] ) ,
134+ addresses : Vec :: new ( ) ,
135+ excess_address_data : Vec :: new ( ) ,
136+ excess_data : Vec :: new ( ) ,
137+ } ;
138+
139+ if has_address_details {
140+ let address_count: u8 = Readable :: read ( read_cursor) ?;
141+ let mut node_addresses: Vec < SocketAddress > = Vec :: new ( ) ;
142+ for _ in 0 ..address_count {
143+ let current_byte_count: u8 = Readable :: read ( read_cursor) ?;
144+ let mut address_bytes = vec ! [ 0u8 ; current_byte_count as usize ] ;
145+ read_cursor. read_exact ( & mut address_bytes) . unwrap ( ) ;
146+
147+ let mut address_cursor = io:: Cursor :: new ( & address_bytes) ;
148+ if let Ok ( current_address) = Readable :: read ( & mut address_cursor) {
149+ node_addresses. push ( current_address) ;
150+ }
151+ }
152+ unsigned_node_announcement. addresses = node_addresses;
153+ }
154+
155+ if feature_detail_marker > 0 {
156+ if feature_detail_marker < 7 {
157+ let feature_index = ( feature_detail_marker - 1 ) as usize ;
158+ unsigned_node_announcement. features = default_node_features[ feature_index] . clone ( ) ;
159+ } else {
160+ let node_features: NodeFeatures = Readable :: read ( read_cursor) ?;
161+ unsigned_node_announcement. features = node_features;
162+ }
163+ }
164+
165+ if feature_detail_marker > 0 || has_address_details {
166+ node_modifications. insert ( current_node_id, unsigned_node_announcement) ;
167+ }
168+
169+ if has_additional_data {
170+ // forwards compatibility
171+ let _additional_data: Vec < u8 > = Readable :: read ( read_cursor) ?;
172+ }
173+
174+ } else {
175+ let current_node_id = Readable :: read ( read_cursor) ?;
176+ node_ids. push ( current_node_id) ;
177+ }
99178 }
100179
101180 let network_graph = & self . network_graph ;
@@ -114,6 +193,7 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
114193
115194 let node_id_1_index: BigSize = Readable :: read ( read_cursor) ?;
116195 let node_id_2_index: BigSize = Readable :: read ( read_cursor) ?;
196+ let has_additional_data = ( node_id_2_index. 0 & ( 1 << 63 ) ) > 0 ;
117197
118198 if max ( node_id_1_index. 0 , node_id_2_index. 0 ) >= node_id_count as u64 {
119199 return Err ( DecodeError :: InvalidValue . into ( ) ) ;
@@ -139,6 +219,18 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
139219 return Err ( lightning_error. into ( ) ) ;
140220 }
141221 }
222+
223+ if version >= 2 && has_additional_data {
224+ // forwards compatibility
225+ let _additional_data: Vec < u8 > = Readable :: read ( read_cursor) ?;
226+ }
227+
228+ if let Some ( modification) = node_modifications. remove ( & node_id_1) {
229+ network_graph. update_node_from_unsigned_announcement ( & modification) ?;
230+ }
231+ if let Some ( modification) = node_modifications. remove ( & node_id_2) {
232+ network_graph. update_node_from_unsigned_announcement ( & modification) ?;
233+ }
142234 }
143235
144236 previous_scid = 0 ; // updates start at a new scid
@@ -157,6 +249,8 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
157249 let default_fee_proportional_millionths: u32 = Readable :: read ( & mut read_cursor) ?;
158250 let default_htlc_maximum_msat: u64 = Readable :: read ( & mut read_cursor) ?;
159251
252+ let mut previous_channel_direction = None ;
253+
160254 for _ in 0 ..update_count {
161255 let scid_delta: BigSize = Readable :: read ( read_cursor) ?;
162256 let short_channel_id = previous_scid
@@ -166,6 +260,18 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
166260
167261 let channel_flags: u8 = Readable :: read ( read_cursor) ?;
168262
263+ if version >= 2 {
264+ let direction = ( channel_flags & 1 ) == 1 ;
265+ let is_same_direction_update = Some ( direction) == previous_channel_direction;
266+ previous_channel_direction = Some ( direction) ;
267+
268+ if scid_delta. 0 == 0 && is_same_direction_update {
269+ // this is additional data for forwards compatibility
270+ let _additional_data: Vec < u8 > = Readable :: read ( read_cursor) ?;
271+ continue ;
272+ }
273+ }
274+
169275 // flags are always sent in full, and hence always need updating
170276 let standard_channel_flags = channel_flags & 0b_0000_0011 ;
171277
@@ -265,7 +371,7 @@ mod tests {
265371 #[ cfg( feature = "std" ) ]
266372 use lightning:: ln:: msgs:: DecodeError ;
267373
268- use lightning:: routing:: gossip:: NetworkGraph ;
374+ use lightning:: routing:: gossip:: { NetworkGraph , NodeId } ;
269375 use lightning:: util:: test_utils:: TestLogger ;
270376
271377 use crate :: processing:: STALE_RGS_UPDATE_AGE_LIMIT_SECS ;
@@ -322,6 +428,42 @@ mod tests {
322428 }
323429 }
324430
431+ #[ test]
432+ fn node_data_update_succeeds_with_v2 ( ) {
433+ let logger = TestLogger :: new ( ) ;
434+ let network_graph = NetworkGraph :: new ( Network :: Bitcoin , & logger) ;
435+
436+ let example_input = vec ! [
437+ 76 , 68 , 75 , 2 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 , 174 , 99 , 247 ,
438+ 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 102 , 87 , 151 , 80 ,
439+ 1 , 0 , 2 , 23 , 48 , 0 , 0 , 0 , 3 , 15 , 27 , 132 , 197 , 86 , 123 , 18 , 100 , 64 , 153 , 93 , 62 , 213 ,
440+ 170 , 186 , 5 , 101 , 215 , 30 , 24 , 52 , 96 , 72 , 25 , 255 , 156 , 23 , 245 , 233 , 213 , 221 , 7 , 143 ,
441+ 5 , 14 , 5 , 10 , 103 , 111 , 111 , 103 , 108 , 101 , 46 , 99 , 111 , 109 , 1 , 187 , 13 , 3 , 1 , 2 , 3 , 4 ,
442+ 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 38 , 4 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
443+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 2 , 3 , 0 , 4 , 7 , 1 , 127 , 0 , 0 , 1 , 37 , 163 ,
444+ 19 , 2 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 5 , 57 , 2 , 77 , 75 , 108 , 209 , 54 ,
445+ 16 , 50 , 202 , 155 , 210 , 174 , 185 , 217 , 0 , 170 , 77 , 69 , 217 , 234 , 216 , 10 , 201 , 66 , 51 ,
446+ 116 , 196 , 81 , 167 , 37 , 77 , 7 , 102 , 2 , 83 , 31 , 230 , 6 , 129 , 52 , 80 , 61 , 39 , 35 , 19 , 50 ,
447+ 39 , 200 , 103 , 172 , 143 , 166 , 200 , 60 , 83 , 126 , 154 , 68 , 195 , 197 , 189 , 189 , 203 , 31 ,
448+ 227 , 55 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
449+ 6 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1
450+ ] ;
451+
452+ let rapid_sync = RapidGossipSync :: new ( & network_graph, & logger) ;
453+ let update_result = rapid_sync. update_network_graph_no_std ( & example_input[ ..] , None ) ;
454+ assert ! ( update_result. is_ok( ) ) ;
455+
456+ let read_only_graph = network_graph. read_only ( ) ;
457+ let nodes = read_only_graph. nodes ( ) ;
458+ assert_eq ! ( nodes. len( ) , 2 ) ;
459+
460+ let node_id = NodeId :: from_slice ( & [ 3 , 27 , 132 , 197 , 86 , 123 , 18 , 100 , 64 , 153 , 93 , 62 , 213 , 170 , 186 , 5 , 101 , 215 , 30 , 24 , 52 , 96 , 72 , 25 , 255 , 156 , 23 , 245 , 233 , 213 , 221 , 7 , 143 ] ) . unwrap ( ) ;
461+ let node = nodes. get ( & node_id) . unwrap ( ) ;
462+ let announcement_info = node. announcement_info . as_ref ( ) . unwrap ( ) ;
463+ let addresses = announcement_info. addresses ( ) ;
464+ assert_eq ! ( addresses. len( ) , 5 ) ;
465+ }
466+
325467 #[ test]
326468 #[ cfg( feature = "std" ) ]
327469 fn incremental_only_update_ignores_missing_channel ( ) {
@@ -645,7 +787,7 @@ mod tests {
645787 #[ cfg( feature = "std" ) ]
646788 pub fn update_fails_with_unknown_version ( ) {
647789 let unknown_version_input = vec ! [
648- 76 , 68 , 75 , 2 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 , 174 , 99 , 247 ,
790+ 76 , 68 , 75 , 3 , 111 , 226 , 140 , 10 , 182 , 241 , 179 , 114 , 193 , 166 , 162 , 70 , 174 , 99 , 247 ,
649791 79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 97 , 227 , 98 , 218 ,
650792 0 , 0 , 0 , 4 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 , 231 , 230 , 231 , 56 , 102 , 61 , 250 , 251 ,
651793 187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 , 238 , 252 , 53 , 192 , 6 , 67 , 2 , 36 , 125 ,
0 commit comments