mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
gossipd: use straight counter instead of bitmap for query_channel_range replies.
The spec (since d4bafcb67dcf1e4de4d16224ea4de6b543ae73bf in March 2020) requires that reply_channel_range be in order (and all implementations did this anyway). But when I tried this, I found that LND doesn't (always) obey this, since don't divide on block boundaries. So we have to loosen the constraints here a little. We got rid of the old LND compat handling though, since everyone should now be upgraded (there are CVEs out for older LNDs). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Removed: Support for receiving full gossip from ancient LND nodes.
This commit is contained in:
parent
4745e7e3d0
commit
59f23bf23c
@ -606,7 +606,7 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn,
|
||||
peer->scid_query_nodes = NULL;
|
||||
peer->scid_query_nodes_idx = 0;
|
||||
peer->scid_query_outstanding = false;
|
||||
peer->query_channel_blocks = NULL;
|
||||
peer->query_channel_scids = NULL;
|
||||
peer->query_channel_range_cb = NULL;
|
||||
peer->num_pings_outstanding = 0;
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define LIGHTNING_GOSSIPD_GOSSIPD_H
|
||||
#include "config.h"
|
||||
#include <bitcoin/block.h>
|
||||
#include <ccan/bitmap/bitmap.h>
|
||||
#include <ccan/list/list.h>
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/timer/timer.h>
|
||||
@ -95,11 +94,9 @@ struct peer {
|
||||
/* How many pongs are we expecting? */
|
||||
size_t num_pings_outstanding;
|
||||
|
||||
/* Map of outstanding channel_range requests. */
|
||||
bitmap *query_channel_blocks;
|
||||
/* What we're querying: [range_first_blocknum, range_end_blocknum) */
|
||||
u32 range_first_blocknum, range_end_blocknum;
|
||||
u32 range_blocks_remaining;
|
||||
u32 range_prev_end_blocknum;
|
||||
struct short_channel_id *query_channel_scids;
|
||||
struct channel_update_timestamps *query_channel_timestamps;
|
||||
void (*query_channel_range_cb)(struct peer *peer,
|
||||
|
@ -639,7 +639,6 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
|
||||
struct short_channel_id *scids;
|
||||
struct channel_update_timestamps *ts;
|
||||
size_t n;
|
||||
unsigned long b;
|
||||
void (*cb)(struct peer *peer,
|
||||
u32 first_blocknum, u32 number_of_blocks,
|
||||
const struct short_channel_id *scids,
|
||||
@ -662,7 +661,7 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
|
||||
tal_hex(tmpctx, msg));
|
||||
}
|
||||
|
||||
if (!peer->query_channel_blocks) {
|
||||
if (!peer->query_channel_scids) {
|
||||
return towire_errorfmt(peer, NULL,
|
||||
"reply_channel_range without query: %s",
|
||||
tal_hex(tmpctx, msg));
|
||||
@ -733,27 +732,20 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
|
||||
&& first_blocknum + number_of_blocks == peer->range_end_blocknum
|
||||
&& !complete
|
||||
&& tal_bytelen(msg) == 64046) {
|
||||
status_debug("LND reply_channel_range detected: futzing");
|
||||
} else {
|
||||
/* We keep a bitmap of what blocks have been covered by replies: bit 0
|
||||
* represents block peer->range_first_blocknum */
|
||||
b = bitmap_ffs(peer->query_channel_blocks,
|
||||
start - peer->range_first_blocknum,
|
||||
end - peer->range_first_blocknum);
|
||||
if (b != end - peer->range_first_blocknum) {
|
||||
return towire_errorfmt(peer, NULL,
|
||||
"reply_channel_range %u+%u already have block %lu",
|
||||
first_blocknum, number_of_blocks,
|
||||
peer->range_first_blocknum + b);
|
||||
}
|
||||
|
||||
/* Mark that short_channel_ids for this block have been received */
|
||||
bitmap_fill_range(peer->query_channel_blocks,
|
||||
start - peer->range_first_blocknum,
|
||||
end - peer->range_first_blocknum);
|
||||
peer->range_blocks_remaining -= end - start;
|
||||
status_unusual("Old LND reply_channel_range detected: result will be truncated!");
|
||||
}
|
||||
|
||||
/* They're supposed to send them in order, but LND actually
|
||||
* can overlap. */
|
||||
if (first_blocknum != peer->range_prev_end_blocknum + 1
|
||||
&& first_blocknum != peer->range_prev_end_blocknum) {
|
||||
return towire_errorfmt(peer, NULL,
|
||||
"reply_channel_range %u+%u previous end was block %u",
|
||||
first_blocknum, number_of_blocks,
|
||||
peer->range_prev_end_blocknum);
|
||||
}
|
||||
peer->range_prev_end_blocknum = end;
|
||||
|
||||
/* Add scids */
|
||||
n = tal_count(peer->query_channel_scids);
|
||||
tal_resize(&peer->query_channel_scids, n + tal_count(scids));
|
||||
@ -782,18 +774,16 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
|
||||
memcpy(peer->query_channel_timestamps + n, ts, tal_bytelen(ts));
|
||||
|
||||
/* Still more to go? */
|
||||
if (peer->range_blocks_remaining)
|
||||
if (peer->range_prev_end_blocknum < peer->range_end_blocknum)
|
||||
return NULL;
|
||||
|
||||
/* Clear these immediately in case cb want to queue more */
|
||||
scids = tal_steal(tmpctx, peer->query_channel_scids);
|
||||
ts = tal_steal(tmpctx, peer->query_channel_timestamps);
|
||||
cb = peer->query_channel_range_cb;
|
||||
tal_steal(tmpctx, peer->query_channel_blocks);
|
||||
|
||||
peer->query_channel_scids = NULL;
|
||||
peer->query_channel_timestamps = NULL;
|
||||
peer->query_channel_blocks = NULL;
|
||||
peer->query_channel_range_cb = NULL;
|
||||
|
||||
cb(peer, first_blocknum, number_of_blocks, scids, ts, complete);
|
||||
@ -1028,16 +1018,9 @@ bool query_channel_range(struct daemon *daemon,
|
||||
|
||||
assert((qflags & ~(QUERY_ADD_TIMESTAMPS|QUERY_ADD_CHECKSUMS)) == 0);
|
||||
assert(peer->gossip_queries_feature);
|
||||
assert(!peer->query_channel_blocks);
|
||||
assert(!peer->query_channel_scids);
|
||||
assert(!peer->query_channel_range_cb);
|
||||
|
||||
/* Check for overflow on 32-bit machines! */
|
||||
if (BITMAP_NWORDS(number_of_blocks) < number_of_blocks / BITMAP_WORD_BITS) {
|
||||
status_broken("query_channel_range: huge number_of_blocks (%u) not supported",
|
||||
number_of_blocks);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (qflags) {
|
||||
tlvs = tlv_query_channel_range_tlvs_new(tmpctx);
|
||||
tlvs->query_option = tal(tlvs, bigsize_t);
|
||||
@ -1054,9 +1037,7 @@ bool query_channel_range(struct daemon *daemon,
|
||||
queue_peer_msg(peer, take(msg));
|
||||
peer->range_first_blocknum = first_blocknum;
|
||||
peer->range_end_blocknum = first_blocknum + number_of_blocks;
|
||||
peer->range_blocks_remaining = number_of_blocks;
|
||||
peer->query_channel_blocks = tal_arrz(peer, bitmap,
|
||||
BITMAP_NWORDS(number_of_blocks));
|
||||
peer->range_prev_end_blocknum = first_blocknum-1;
|
||||
peer->query_channel_scids = tal_arr(peer, struct short_channel_id, 0);
|
||||
peer->query_channel_timestamps
|
||||
= tal_arr(peer, struct channel_update_timestamps, 0);
|
||||
|
@ -296,7 +296,7 @@ static bool peer_has_gossip_queries(const struct peer *peer)
|
||||
static bool peer_can_take_range_query(const struct peer *peer)
|
||||
{
|
||||
return peer->gossip_queries_feature
|
||||
&& !peer->query_channel_blocks;
|
||||
&& !peer->query_channel_scids;
|
||||
}
|
||||
|
||||
static bool peer_can_take_scid_query(const struct peer *peer)
|
||||
|
Loading…
Reference in New Issue
Block a user