@@ -5,10 +5,8 @@ use core::sync::atomic::Ordering;
5
5
use bitcoin:: blockdata:: constants:: ChainHash ;
6
6
use bitcoin:: secp256k1:: PublicKey ;
7
7
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 } ;
12
10
use lightning:: util:: logger:: Logger ;
13
11
use lightning:: { log_debug, log_warn, log_trace, log_given_level, log_gossip} ;
14
12
use lightning:: util:: ser:: { BigSize , Readable } ;
@@ -21,12 +19,14 @@ use std::time::{SystemTime, UNIX_EPOCH};
21
19
22
20
#[ cfg( all( not( feature = "std" ) , not( test) ) ) ]
23
21
use alloc:: { vec:: Vec , borrow:: ToOwned } ;
22
+ use lightning:: ln:: features:: NodeFeatures ;
23
+ use lightning:: util:: hash_tables:: HashMap ;
24
24
25
25
/// The purpose of this prefix is to identify the serialization format, should other rapid gossip
26
26
/// sync formats arise in the future.
27
27
///
28
28
/// 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 ] ;
30
30
31
31
/// Maximum vector allocation capacity for distinct node IDs. This constraint is necessary to
32
32
/// 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
59
59
current_time_unix : Option < u64 >
60
60
) -> Result < u32 , GraphSyncError > {
61
61
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 ] ;
64
64
65
- if prefix != GOSSIP_PREFIX {
65
+ read_cursor. read_exact ( & mut protocol_prefix) ?;
66
+ if protocol_prefix != GOSSIP_PREFIX {
66
67
return Err ( DecodeError :: UnknownVersion . into ( ) ) ;
67
68
}
68
69
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
+
69
78
let chain_hash: ChainHash = Readable :: read ( read_cursor) ?;
70
79
let ng_chain_hash = self . network_graph . get_chain_hash ( ) ;
71
80
if chain_hash != ng_chain_hash {
@@ -88,14 +97,84 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
88
97
// backdate the applied timestamp by a week
89
98
let backdated_timestamp = latest_seen_timestamp. saturating_sub ( 24 * 3600 * 7 ) ;
90
99
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
+
91
109
let node_id_count: u32 = Readable :: read ( read_cursor) ?;
92
110
let mut node_ids: Vec < PublicKey > = Vec :: with_capacity ( core:: cmp:: min (
93
111
node_id_count,
94
112
MAX_INITIAL_NODE_ID_VECTOR_CAPACITY ,
95
113
) as usize ) ;
114
+ let mut node_modifications: HashMap < PublicKey , UnsignedNodeAnnouncement > = HashMap :: default ( ) ;
96
115
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
+ }
99
178
}
100
179
101
180
let network_graph = & self . network_graph ;
@@ -114,6 +193,7 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
114
193
115
194
let node_id_1_index: BigSize = Readable :: read ( read_cursor) ?;
116
195
let node_id_2_index: BigSize = Readable :: read ( read_cursor) ?;
196
+ let has_additional_data = ( node_id_2_index. 0 & ( 1 << 63 ) ) > 0 ;
117
197
118
198
if max ( node_id_1_index. 0 , node_id_2_index. 0 ) >= node_id_count as u64 {
119
199
return Err ( DecodeError :: InvalidValue . into ( ) ) ;
@@ -139,6 +219,18 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
139
219
return Err ( lightning_error. into ( ) ) ;
140
220
}
141
221
}
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
+ }
142
234
}
143
235
144
236
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
157
249
let default_fee_proportional_millionths: u32 = Readable :: read ( & mut read_cursor) ?;
158
250
let default_htlc_maximum_msat: u64 = Readable :: read ( & mut read_cursor) ?;
159
251
252
+ let mut previous_channel_direction = None ;
253
+
160
254
for _ in 0 ..update_count {
161
255
let scid_delta: BigSize = Readable :: read ( read_cursor) ?;
162
256
let short_channel_id = previous_scid
@@ -166,6 +260,18 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
166
260
167
261
let channel_flags: u8 = Readable :: read ( read_cursor) ?;
168
262
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
+
169
275
// flags are always sent in full, and hence always need updating
170
276
let standard_channel_flags = channel_flags & 0b_0000_0011 ;
171
277
@@ -265,7 +371,7 @@ mod tests {
265
371
#[ cfg( feature = "std" ) ]
266
372
use lightning:: ln:: msgs:: DecodeError ;
267
373
268
- use lightning:: routing:: gossip:: NetworkGraph ;
374
+ use lightning:: routing:: gossip:: { NetworkGraph , NodeId } ;
269
375
use lightning:: util:: test_utils:: TestLogger ;
270
376
271
377
use crate :: processing:: STALE_RGS_UPDATE_AGE_LIMIT_SECS ;
@@ -322,6 +428,42 @@ mod tests {
322
428
}
323
429
}
324
430
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
+
325
467
#[ test]
326
468
#[ cfg( feature = "std" ) ]
327
469
fn incremental_only_update_ignores_missing_channel ( ) {
@@ -645,7 +787,7 @@ mod tests {
645
787
#[ cfg( feature = "std" ) ]
646
788
pub fn update_fails_with_unknown_version ( ) {
647
789
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 ,
649
791
79 , 147 , 30 , 131 , 101 , 225 , 90 , 8 , 156 , 104 , 214 , 25 , 0 , 0 , 0 , 0 , 0 , 97 , 227 , 98 , 218 ,
650
792
0 , 0 , 0 , 4 , 2 , 22 , 7 , 207 , 206 , 25 , 164 , 197 , 231 , 230 , 231 , 56 , 102 , 61 , 250 , 251 ,
651
793
187 , 172 , 38 , 46 , 79 , 247 , 108 , 44 , 155 , 48 , 219 , 238 , 252 , 53 , 192 , 6 , 67 , 2 , 36 , 125 ,
0 commit comments