Skip to content

Commit 7815965

Browse files
committed
Comment cleanup for handling query_channel_range
Cleans up NetGraphMsgHandler::handle_query_channel_range
1 parent f4adb9f commit 7815965

File tree

2 files changed

+59
-17
lines changed

2 files changed

+59
-17
lines changed

lightning/src/routing/network_graph.rs

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -317,23 +317,26 @@ impl<C: Deref + Sync + Send, L: Deref + Sync + Send> RoutingMessageHandler for N
317317
Ok(())
318318
}
319319

320-
/// Processes a query from a peer by finding channels whose funding UTXOs
320+
/// Processes a query from a peer by finding announced/public channels whose funding UTXOs
321321
/// are in the specified block range. Due to message size limits, large range
322322
/// queries may result in several reply messages. This implementation enqueues
323-
/// all reply messages into pending events.
323+
/// all reply messages into pending events. Each message will allocate just under 65KiB. A full
324+
/// sync of the public routing table with 128k channels will generated 16 messages and allocate ~1MB.
325+
/// Logic can be changed to reduce allocation if/when a full sync of the routing table impacts
326+
/// memory constrained systems.
324327
fn handle_query_channel_range(&self, their_node_id: &PublicKey, msg: QueryChannelRange) -> Result<(), LightningError> {
325328
log_debug!(self.logger, "Handling query_channel_range peer={}, first_blocknum={}, number_of_blocks={}", log_pubkey!(their_node_id), msg.first_blocknum, msg.number_of_blocks);
326329

327330
let network_graph = self.network_graph.read().unwrap();
328331

329-
let start_scid = scid_from_parts(msg.first_blocknum as u64, 0, 0);
332+
let inclusive_start_scid = scid_from_parts(msg.first_blocknum as u64, 0, 0);
330333

331-
// We receive valid queries with end_blocknum that would overflow SCID conversion.
332-
// Manually cap the ending block to avoid this overflow.
334+
// We might receive valid queries with end_blocknum that would overflow SCID conversion.
335+
// If so, we manually cap the ending block to avoid this overflow.
333336
let exclusive_end_scid = scid_from_parts(cmp::min(msg.end_blocknum() as u64, MAX_SCID_BLOCK), 0, 0);
334337

335338
// Per spec, we must reply to a query. Send an empty message when things are invalid.
336-
if msg.chain_hash != network_graph.genesis_hash || start_scid.is_err() || exclusive_end_scid.is_err() {
339+
if msg.chain_hash != network_graph.genesis_hash || inclusive_start_scid.is_err() || exclusive_end_scid.is_err() || msg.number_of_blocks == 0 {
337340
let mut pending_events = self.pending_events.lock().unwrap();
338341
pending_events.push(MessageSendEvent::SendReplyChannelRange {
339342
node_id: their_node_id.clone(),
@@ -345,14 +348,17 @@ impl<C: Deref + Sync + Send, L: Deref + Sync + Send> RoutingMessageHandler for N
345348
short_channel_ids: vec![],
346349
}
347350
});
348-
return Ok(());
351+
return Err(LightningError {
352+
err: String::from("query_channel_range could not be processed"),
353+
action: ErrorAction::IgnoreError,
354+
});
349355
}
350356

351357
// Creates channel batches. We are not checking if the channel is routable
352358
// (has at least one update). A peer may still want to know the channel
353359
// exists even if its not yet routable.
354360
let mut batches: Vec<Vec<u64>> = vec![Vec::with_capacity(MAX_SCIDS_PER_REPLY)];
355-
for (_, ref chan) in network_graph.get_channels().range(start_scid.unwrap()..exclusive_end_scid.unwrap()) {
361+
for (_, ref chan) in network_graph.get_channels().range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) {
356362
if let Some(chan_announcement) = &chan.announcement_message {
357363
// Construct a new batch if last one is full
358364
if batches.last().unwrap().len() == batches.last().unwrap().capacity() {
@@ -374,12 +380,12 @@ impl<C: Deref + Sync + Send, L: Deref + Sync + Send> RoutingMessageHandler for N
374380
msg.first_blocknum
375381
}
376382
// Subsequent replies must be >= the last sent first_blocknum. Use the first block
377-
// in the new batch.
383+
// in the new batch. Batches beyond the first one cannot be empty.
378384
else {
379385
block_from_scid(batch.first().unwrap())
380386
};
381387

382-
// Per spec, the last end_block needs to be >= the query's end_block. Last
388+
// Per spec, the last end_blocknum needs to be >= the query's end_blocknum. Last
383389
// reply calculates difference between the query's end_blocknum and the start of the reply.
384390
// Overflow safe since end_blocknum=msg.first_block_num+msg.number_of_blocks and first_blocknum
385391
// will be either msg.first_blocknum or a higher block height.
@@ -2231,7 +2237,7 @@ mod tests {
22312237
};
22322238
}
22332239

2234-
// Empty reply when number_of_blocks=0
2240+
// Error when number_of_blocks=0
22352241
do_handling_query_channel_range(
22362242
&net_graph_msg_handler,
22372243
&node_id_2,
@@ -2240,6 +2246,7 @@ mod tests {
22402246
first_blocknum: 0,
22412247
number_of_blocks: 0,
22422248
},
2249+
false,
22432250
vec![ReplyChannelRange {
22442251
chain_hash: chain_hash.clone(),
22452252
first_blocknum: 0,
@@ -2249,7 +2256,7 @@ mod tests {
22492256
}]
22502257
);
22512258

2252-
// Empty when wrong chain
2259+
// Error when wrong chain
22532260
do_handling_query_channel_range(
22542261
&net_graph_msg_handler,
22552262
&node_id_2,
@@ -2258,6 +2265,7 @@ mod tests {
22582265
first_blocknum: 0,
22592266
number_of_blocks: 0xffff_ffff,
22602267
},
2268+
false,
22612269
vec![ReplyChannelRange {
22622270
chain_hash: genesis_block(Network::Bitcoin).header.block_hash(),
22632271
first_blocknum: 0,
@@ -2267,7 +2275,7 @@ mod tests {
22672275
}]
22682276
);
22692277

2270-
// Empty reply when first_blocknum > 0xffffff
2278+
// Error when first_blocknum > 0xffffff
22712279
do_handling_query_channel_range(
22722280
&net_graph_msg_handler,
22732281
&node_id_2,
@@ -2276,6 +2284,7 @@ mod tests {
22762284
first_blocknum: 0x01000000,
22772285
number_of_blocks: 0xffff_ffff,
22782286
},
2287+
false,
22792288
vec![ReplyChannelRange {
22802289
chain_hash: chain_hash.clone(),
22812290
first_blocknum: 0x01000000,
@@ -2285,8 +2294,7 @@ mod tests {
22852294
}]
22862295
);
22872296

2288-
// Empty reply when max valid SCID block num.
2289-
// Unlike prior test this is a valid query but no results are found
2297+
// Empty reply when max valid SCID block num
22902298
do_handling_query_channel_range(
22912299
&net_graph_msg_handler,
22922300
&node_id_2,
@@ -2295,6 +2303,7 @@ mod tests {
22952303
first_blocknum: 0xffffff,
22962304
number_of_blocks: 1,
22972305
},
2306+
true,
22982307
vec![
22992308
ReplyChannelRange {
23002309
chain_hash: chain_hash.clone(),
@@ -2315,6 +2324,7 @@ mod tests {
23152324
first_blocknum: 0x00800000,
23162325
number_of_blocks: 1000,
23172326
},
2327+
true,
23182328
vec![
23192329
ReplyChannelRange {
23202330
chain_hash: chain_hash.clone(),
@@ -2335,6 +2345,7 @@ mod tests {
23352345
first_blocknum: 0xfe0000,
23362346
number_of_blocks: 0xffffffff,
23372347
},
2348+
true,
23382349
vec![
23392350
ReplyChannelRange {
23402351
chain_hash: chain_hash.clone(),
@@ -2348,6 +2359,29 @@ mod tests {
23482359
]
23492360
);
23502361

2362+
// Single block exactly full
2363+
do_handling_query_channel_range(
2364+
&net_graph_msg_handler,
2365+
&node_id_2,
2366+
QueryChannelRange {
2367+
chain_hash: chain_hash.clone(),
2368+
first_blocknum: 100000,
2369+
number_of_blocks: 8000,
2370+
},
2371+
true,
2372+
vec![
2373+
ReplyChannelRange {
2374+
chain_hash: chain_hash.clone(),
2375+
first_blocknum: 100000,
2376+
number_of_blocks: 8000,
2377+
sync_complete: true,
2378+
short_channel_ids: (100000..=107999)
2379+
.map(|block| scid_from_parts(block, 0, 0).unwrap())
2380+
.collect(),
2381+
},
2382+
]
2383+
);
2384+
23512385
// Multiple split on new block
23522386
do_handling_query_channel_range(
23532387
&net_graph_msg_handler,
@@ -2357,6 +2391,7 @@ mod tests {
23572391
first_blocknum: 100000,
23582392
number_of_blocks: 8001,
23592393
},
2394+
true,
23602395
vec![
23612396
ReplyChannelRange {
23622397
chain_hash: chain_hash.clone(),
@@ -2388,6 +2423,7 @@ mod tests {
23882423
first_blocknum: 100002,
23892424
number_of_blocks: 8000,
23902425
},
2426+
true,
23912427
vec![
23922428
ReplyChannelRange {
23932429
chain_hash: chain_hash.clone(),
@@ -2416,10 +2452,16 @@ mod tests {
24162452
net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
24172453
test_node_id: &PublicKey,
24182454
msg: QueryChannelRange,
2455+
expected_ok: bool,
24192456
expected_replies: Vec<ReplyChannelRange>
24202457
) {
24212458
let result = net_graph_msg_handler.handle_query_channel_range(test_node_id, msg);
2422-
assert!(result.is_ok());
2459+
2460+
if expected_ok {
2461+
assert!(result.is_ok());
2462+
} else {
2463+
assert!(result.is_err());
2464+
}
24232465

24242466
let events = net_graph_msg_handler.get_and_clear_pending_msg_events();
24252467
assert_eq!(events.len(), expected_replies.len());

lightning/src/util/events.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ pub enum MessageSendEvent {
362362
/// The query_short_channel_ids which should be sent.
363363
msg: msgs::QueryShortChannelIds,
364364
},
365-
/// Sends a reply to a channel range query. This may be one of several events
365+
/// Sends a reply to a channel range query. This may be one of several SendReplyChannelRange events
366366
/// emitted during processing of the query.
367367
SendReplyChannelRange {
368368
/// The node_id of this message recipient

0 commit comments

Comments
 (0)