mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-23 00:54:20 +01:00
gossipd: handle query_channel_range
We send them all the short_channel_ids we have in a given range. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
120
gossipd/gossip.c
120
gossipd/gossip.c
@@ -911,6 +911,121 @@ static void handle_gossip_timestamp_filter(struct peer *peer, u8 *msg)
|
|||||||
peer->broadcast_index = 0;
|
peer->broadcast_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reply_channel_range(struct peer *peer,
|
||||||
|
u32 first_blocknum, u32 number_of_blocks,
|
||||||
|
const u8 *encoded)
|
||||||
|
{
|
||||||
|
/* BOLT #7:
|
||||||
|
*
|
||||||
|
* - For each `reply_channel_range`:
|
||||||
|
* - MUST set with `chain_hash` equal to that of `query_channel_range`,
|
||||||
|
* - MUST encode a `short_channel_id` for every open channel it
|
||||||
|
* knows in blocks `first_blocknum` to `first_blocknum` plus
|
||||||
|
* `number_of_blocks` minus one.
|
||||||
|
* - MUST limit `number_of_blocks` to the maximum number of blocks
|
||||||
|
* whose results could fit in `encoded_short_ids`
|
||||||
|
* - if does not maintain up-to-date channel information for
|
||||||
|
* `chain_hash`:
|
||||||
|
* - MUST set `complete` to 0.
|
||||||
|
* - otherwise:
|
||||||
|
* - SHOULD set `complete` to 1.
|
||||||
|
*/
|
||||||
|
u8 *msg = towire_reply_channel_range(NULL,
|
||||||
|
&peer->daemon->rstate->chain_hash,
|
||||||
|
first_blocknum,
|
||||||
|
number_of_blocks,
|
||||||
|
1, encoded);
|
||||||
|
queue_peer_msg(peer, take(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void queue_channel_ranges(struct peer *peer,
|
||||||
|
u32 first_blocknum, u32 number_of_blocks)
|
||||||
|
{
|
||||||
|
struct routing_state *rstate = peer->daemon->rstate;
|
||||||
|
u8 *encoded = encode_short_channel_ids_start(tmpctx);
|
||||||
|
struct short_channel_id scid;
|
||||||
|
|
||||||
|
/* BOLT #7:
|
||||||
|
*
|
||||||
|
* 1. type: 264 (`reply_channel_range`) (`gossip_queries`)
|
||||||
|
* 2. data:
|
||||||
|
* * [`32`:`chain_hash`]
|
||||||
|
* * [`4`:`first_blocknum`]
|
||||||
|
* * [`4`:`number_of_blocks`]
|
||||||
|
* * [`1`:`complete`]
|
||||||
|
* * [`2`:`len`]
|
||||||
|
* * [`len`:`encoded_short_ids`]
|
||||||
|
*/
|
||||||
|
const size_t reply_overhead = 32 + 4 + 4 + 1 + 2;
|
||||||
|
const size_t max_encoded_bytes = 65535 - 2 - reply_overhead;
|
||||||
|
|
||||||
|
/* Avoid underflow: we don't use block 0 anyway */
|
||||||
|
if (first_blocknum == 0)
|
||||||
|
mk_short_channel_id(&scid, 1, 0, 0);
|
||||||
|
else
|
||||||
|
mk_short_channel_id(&scid, first_blocknum, 0, 0);
|
||||||
|
scid.u64--;
|
||||||
|
|
||||||
|
while (uintmap_after(&rstate->chanmap, &scid.u64)) {
|
||||||
|
u32 blocknum = short_channel_id_blocknum(&scid);
|
||||||
|
if (blocknum >= first_blocknum + number_of_blocks)
|
||||||
|
break;
|
||||||
|
|
||||||
|
encode_add_short_channel_id(&encoded, &scid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encode_short_channel_ids_end(&encoded, max_encoded_bytes)) {
|
||||||
|
reply_channel_range(peer, first_blocknum, number_of_blocks,
|
||||||
|
encoded);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It wouldn't all fit: divide in half */
|
||||||
|
/* We assume we can always send one block! */
|
||||||
|
if (number_of_blocks <= 1) {
|
||||||
|
/* We always assume we can send 1 blocks worth */
|
||||||
|
status_broken("Could not fit scids for single block %u",
|
||||||
|
first_blocknum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
status_debug("queue_channel_ranges full: splitting %u+%u and %u+%u",
|
||||||
|
first_blocknum,
|
||||||
|
number_of_blocks / 2,
|
||||||
|
first_blocknum + number_of_blocks / 2,
|
||||||
|
number_of_blocks - number_of_blocks / 2);
|
||||||
|
queue_channel_ranges(peer, first_blocknum, number_of_blocks / 2);
|
||||||
|
queue_channel_ranges(peer, first_blocknum + number_of_blocks / 2,
|
||||||
|
number_of_blocks - number_of_blocks / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_query_channel_range(struct peer *peer, u8 *msg)
|
||||||
|
{
|
||||||
|
struct bitcoin_blkid chain_hash;
|
||||||
|
u32 first_blocknum, number_of_blocks;
|
||||||
|
|
||||||
|
if (!fromwire_query_channel_range(msg, &chain_hash,
|
||||||
|
&first_blocknum, &number_of_blocks)) {
|
||||||
|
peer_error(peer, "Bad query_channel_range %s",
|
||||||
|
tal_hex(tmpctx, msg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!structeq(&peer->daemon->rstate->chain_hash, &chain_hash)) {
|
||||||
|
status_trace("%s sent query_channel_range chainhash %s",
|
||||||
|
type_to_string(tmpctx, struct pubkey, &peer->id),
|
||||||
|
type_to_string(tmpctx, struct bitcoin_blkid,
|
||||||
|
&chain_hash));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_blocknum + number_of_blocks < first_blocknum) {
|
||||||
|
peer_error(peer, "query_channel_range overflow %u+%u",
|
||||||
|
first_blocknum, number_of_blocks);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queue_channel_ranges(peer, first_blocknum, number_of_blocks);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_ping(struct peer *peer, u8 *ping)
|
static void handle_ping(struct peer *peer, u8 *ping)
|
||||||
{
|
{
|
||||||
u8 *pong;
|
u8 *pong;
|
||||||
@@ -1057,6 +1172,10 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
|
|||||||
handle_gossip_timestamp_filter(peer, msg);
|
handle_gossip_timestamp_filter(peer, msg);
|
||||||
return peer_next_in(conn, peer);
|
return peer_next_in(conn, peer);
|
||||||
|
|
||||||
|
case WIRE_QUERY_CHANNEL_RANGE:
|
||||||
|
handle_query_channel_range(peer, msg);
|
||||||
|
return peer_next_in(conn, peer);
|
||||||
|
|
||||||
case WIRE_OPEN_CHANNEL:
|
case WIRE_OPEN_CHANNEL:
|
||||||
case WIRE_CHANNEL_REESTABLISH:
|
case WIRE_CHANNEL_REESTABLISH:
|
||||||
case WIRE_ACCEPT_CHANNEL:
|
case WIRE_ACCEPT_CHANNEL:
|
||||||
@@ -1081,7 +1200,6 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
|
|||||||
/* This will wait. */
|
/* This will wait. */
|
||||||
return peer_next_in(conn, peer);
|
return peer_next_in(conn, peer);
|
||||||
|
|
||||||
case WIRE_QUERY_CHANNEL_RANGE:
|
|
||||||
case WIRE_REPLY_CHANNEL_RANGE:
|
case WIRE_REPLY_CHANNEL_RANGE:
|
||||||
/* FIXME: Implement */
|
/* FIXME: Implement */
|
||||||
return peer_next_in(conn, peer);
|
return peer_next_in(conn, peer);
|
||||||
|
|||||||
Reference in New Issue
Block a user