Skip to content

Commit 0e590cb

Browse files
committed
Use the query start block for ReplyChannelRange response messages
C-Lightning versions prior to 0.10 (incorrectly) enforce that the reply_channel_range first_blocknum field is set to at least the value they sent in their query_channel_range message. Sending a 0 results in them responding with an Error message, closing open channels spuriously. This code is extracted from a previous version of the original query_channel_range PR in commit 44ba52c. The original commit is by `bmancini55 <[email protected]>`.
1 parent 4d1c1a3 commit 0e590cb

File tree

1 file changed

+28
-25
lines changed

1 file changed

+28
-25
lines changed

lightning/src/routing/network_graph.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -375,17 +375,20 @@ impl<C: Deref , L: Deref > RoutingMessageHandler for NetGraphMsgHandler<C, L> wh
375375
let batch_count = batches.len();
376376
for (batch_index, batch) in batches.into_iter().enumerate() {
377377
// Per spec, the initial first_blocknum needs to be <= the query's first_blocknum and subsequent
378-
// must be >= the prior reply. We'll simplify this by using zero since its still spec compliant and
379-
// sequence completion is now explicitly.
380-
let first_blocknum = 0;
378+
// must be >= the prior reply. We'll simplify this by using the query's first_blocknum since its
379+
// still spec compliant and sequence completion is now explicit.
380+
let first_blocknum = msg.first_blocknum;
381381

382-
// Per spec, the final end_blocknum needs to be >= the query's end_blocknum, so we'll use the
383-
// query's value. Prior batches must use the number of blocks that fit into the message. We'll
384-
// base this off the last SCID in the batch since we've somewhat abusing first_blocknum.
382+
// Per spec, the last end_block needs to be >= the query's end_blocknum. Last
383+
// reply calculates difference between the query's end_blocknum and the start of the reply.
384+
// Overflow safe since end_blocknum must be >= msg.first_block_num.
385385
let number_of_blocks = if batch_index == batch_count-1 {
386-
msg.end_blocknum()
387-
} else {
388-
block_from_scid(batch.last().unwrap()) + 1
386+
msg.end_blocknum() - first_blocknum
387+
}
388+
// Prior replies should use the number of blocks that fit into the reply. Overflow
389+
// safe since first_blocknum is always <= last SCID's block.
390+
else {
391+
block_from_scid(batch.last().unwrap()) - first_blocknum + 1
389392
};
390393

391394
// Only true for the last message in a sequence
@@ -2235,8 +2238,8 @@ mod tests {
22352238
vec![
22362239
ReplyChannelRange {
22372240
chain_hash: chain_hash.clone(),
2238-
first_blocknum: 0,
2239-
number_of_blocks: 0x01000000,
2241+
first_blocknum: 0xffffff,
2242+
number_of_blocks: 1,
22402243
sync_complete: true,
22412244
short_channel_ids: vec![]
22422245
},
@@ -2256,8 +2259,8 @@ mod tests {
22562259
vec![
22572260
ReplyChannelRange {
22582261
chain_hash: chain_hash.clone(),
2259-
first_blocknum: 0,
2260-
number_of_blocks: 2000,
2262+
first_blocknum: 1000,
2263+
number_of_blocks: 1000,
22612264
sync_complete: true,
22622265
short_channel_ids: vec![],
22632266
}
@@ -2277,8 +2280,8 @@ mod tests {
22772280
vec![
22782281
ReplyChannelRange {
22792282
chain_hash: chain_hash.clone(),
2280-
first_blocknum: 0,
2281-
number_of_blocks: 0xffffffff,
2283+
first_blocknum: 0xfe0000,
2284+
number_of_blocks: 0xffffffff - 0xfe0000,
22822285
sync_complete: true,
22832286
short_channel_ids: vec![
22842287
0xfffffe_ffffff_ffff, // max
@@ -2300,8 +2303,8 @@ mod tests {
23002303
vec![
23012304
ReplyChannelRange {
23022305
chain_hash: chain_hash.clone(),
2303-
first_blocknum: 0,
2304-
number_of_blocks: 108000,
2306+
first_blocknum: 100000,
2307+
number_of_blocks: 8000,
23052308
sync_complete: true,
23062309
short_channel_ids: (100000..=107999)
23072310
.map(|block| scid_from_parts(block, 0, 0).unwrap())
@@ -2323,17 +2326,17 @@ mod tests {
23232326
vec![
23242327
ReplyChannelRange {
23252328
chain_hash: chain_hash.clone(),
2326-
first_blocknum: 0,
2327-
number_of_blocks: 108000,
2329+
first_blocknum: 100000,
2330+
number_of_blocks: 8000,
23282331
sync_complete: false,
23292332
short_channel_ids: (100000..=107999)
23302333
.map(|block| scid_from_parts(block, 0, 0).unwrap())
23312334
.collect(),
23322335
},
23332336
ReplyChannelRange {
23342337
chain_hash: chain_hash.clone(),
2335-
first_blocknum: 0,
2336-
number_of_blocks: 108001,
2338+
first_blocknum: 100000,
2339+
number_of_blocks: 8001,
23372340
sync_complete: true,
23382341
short_channel_ids: vec![
23392342
scid_from_parts(108000, 0, 0).unwrap(),
@@ -2355,17 +2358,17 @@ mod tests {
23552358
vec![
23562359
ReplyChannelRange {
23572360
chain_hash: chain_hash.clone(),
2358-
first_blocknum: 0,
2359-
number_of_blocks: 108002,
2361+
first_blocknum: 100002,
2362+
number_of_blocks: 8000,
23602363
sync_complete: false,
23612364
short_channel_ids: (100002..=108001)
23622365
.map(|block| scid_from_parts(block, 0, 0).unwrap())
23632366
.collect(),
23642367
},
23652368
ReplyChannelRange {
23662369
chain_hash: chain_hash.clone(),
2367-
first_blocknum: 0,
2368-
number_of_blocks: 108002,
2370+
first_blocknum: 100002,
2371+
number_of_blocks: 8000,
23692372
sync_complete: true,
23702373
short_channel_ids: vec![
23712374
scid_from_parts(108001, 1, 0).unwrap(),

0 commit comments

Comments
 (0)