mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
gossipd: prepare for internally-generated short-channel-id queries.
Up until now we only generated these in dev mode for testing. Hoist into common code, turn counter into a flag (we're only allowed one!) and note if query is internal or not. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
21c920a8e8
commit
5ef7aa70d2
1 changed files with 78 additions and 56 deletions
|
@ -132,7 +132,7 @@ struct peer {
|
||||||
/* The two features gossip cares about (so far) */
|
/* The two features gossip cares about (so far) */
|
||||||
bool gossip_queries_feature, initial_routing_sync_feature;
|
bool gossip_queries_feature, initial_routing_sync_feature;
|
||||||
|
|
||||||
/* Are there outstanding queries on short_channel_ids? */
|
/* Are there outstanding responses for queries on short_channel_ids? */
|
||||||
const struct short_channel_id *scid_queries;
|
const struct short_channel_id *scid_queries;
|
||||||
size_t scid_query_idx;
|
size_t scid_query_idx;
|
||||||
|
|
||||||
|
@ -140,8 +140,9 @@ struct peer {
|
||||||
struct node_id *scid_query_nodes;
|
struct node_id *scid_query_nodes;
|
||||||
size_t scid_query_nodes_idx;
|
size_t scid_query_nodes_idx;
|
||||||
|
|
||||||
/* How many query responses are we expecting? */
|
/* Do we have an scid_query outstanding? Was it internal? */
|
||||||
size_t num_scid_queries_outstanding;
|
bool scid_query_outstanding;
|
||||||
|
bool scid_query_was_internal;
|
||||||
|
|
||||||
/* How many pongs are we expecting? */
|
/* How many pongs are we expecting? */
|
||||||
size_t num_pings_outstanding;
|
size_t num_pings_outstanding;
|
||||||
|
@ -516,6 +517,61 @@ static void maybe_send_own_node_announce(struct daemon *daemon)
|
||||||
daemon->rstate->local_channel_announced = false;
|
daemon->rstate->local_channel_announced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Query this peer for these short-channel-ids. */
|
||||||
|
static bool query_short_channel_ids(struct daemon *daemon,
|
||||||
|
struct peer *peer,
|
||||||
|
const struct short_channel_id *scids,
|
||||||
|
bool internal)
|
||||||
|
{
|
||||||
|
u8 *encoded, *msg;
|
||||||
|
|
||||||
|
/* BOLT #7:
|
||||||
|
*
|
||||||
|
* 1. type: 261 (`query_short_channel_ids`) (`gossip_queries`)
|
||||||
|
* 2. data:
|
||||||
|
* * [`32`:`chain_hash`]
|
||||||
|
* * [`2`:`len`]
|
||||||
|
* * [`len`:`encoded_short_ids`]
|
||||||
|
*/
|
||||||
|
const size_t reply_overhead = 32 + 2;
|
||||||
|
const size_t max_encoded_bytes = 65535 - 2 - reply_overhead;
|
||||||
|
|
||||||
|
/* Can't query if they don't have gossip_queries_feature */
|
||||||
|
if (!peer->gossip_queries_feature)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* BOLT #7:
|
||||||
|
*
|
||||||
|
* The sender:
|
||||||
|
* - MUST NOT send `query_short_channel_ids` if it has sent a previous
|
||||||
|
* `query_short_channel_ids` to this peer and not received
|
||||||
|
* `reply_short_channel_ids_end`.
|
||||||
|
*/
|
||||||
|
if (peer->scid_query_outstanding)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
encoded = encode_short_channel_ids_start(tmpctx);
|
||||||
|
for (size_t i = 0; i < tal_count(scids); i++)
|
||||||
|
encode_add_short_channel_id(&encoded, &scids[i]);
|
||||||
|
|
||||||
|
if (!encode_short_channel_ids_end(&encoded, max_encoded_bytes)) {
|
||||||
|
status_broken("query_short_channel_ids: %zu is too many",
|
||||||
|
tal_count(scids));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = towire_query_short_channel_ids(NULL, &daemon->chain_hash,
|
||||||
|
encoded);
|
||||||
|
queue_peer_msg(peer, take(msg));
|
||||||
|
peer->scid_query_outstanding = true;
|
||||||
|
peer->scid_query_was_internal = internal;
|
||||||
|
|
||||||
|
status_trace("%s: sending query for %zu scids",
|
||||||
|
type_to_string(tmpctx, struct node_id, &peer->id),
|
||||||
|
tal_count(scids));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*~Routines to handle gossip messages from peer, forwarded by subdaemons.
|
/*~Routines to handle gossip messages from peer, forwarded by subdaemons.
|
||||||
*-----------------------------------------------------------------------
|
*-----------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
@ -981,17 +1037,22 @@ static u8 *handle_reply_short_channel_ids_end(struct peer *peer, const u8 *msg)
|
||||||
tal_hex(tmpctx, msg));
|
tal_hex(tmpctx, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peer->num_scid_queries_outstanding == 0) {
|
if (!peer->scid_query_outstanding) {
|
||||||
return towire_errorfmt(peer, NULL,
|
return towire_errorfmt(peer, NULL,
|
||||||
"unexpected reply_short_channel_ids_end: %s",
|
"unexpected reply_short_channel_ids_end: %s",
|
||||||
tal_hex(tmpctx, msg));
|
tal_hex(tmpctx, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
peer->num_scid_queries_outstanding--;
|
peer->scid_query_outstanding = false;
|
||||||
/* We tell lightningd: this is because we currently only ask for
|
|
||||||
* query_short_channel_ids when lightningd asks. */
|
/* If it wasn't generated by us, it's the dev interface from lightningd
|
||||||
msg = towire_gossip_scids_reply(msg, true, complete);
|
*/
|
||||||
daemon_conn_send(peer->daemon->master, take(msg));
|
if (!peer->scid_query_was_internal) {
|
||||||
|
msg = towire_gossip_scids_reply(msg, true, complete);
|
||||||
|
daemon_conn_send(peer->daemon->master, take(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All good, no error. */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1625,7 +1686,7 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn,
|
||||||
peer->scid_query_idx = 0;
|
peer->scid_query_idx = 0;
|
||||||
peer->scid_query_nodes = NULL;
|
peer->scid_query_nodes = NULL;
|
||||||
peer->scid_query_nodes_idx = 0;
|
peer->scid_query_nodes_idx = 0;
|
||||||
peer->num_scid_queries_outstanding = 0;
|
peer->scid_query_outstanding = false;
|
||||||
peer->query_channel_blocks = NULL;
|
peer->query_channel_blocks = NULL;
|
||||||
peer->num_pings_outstanding = 0;
|
peer->num_pings_outstanding = 0;
|
||||||
|
|
||||||
|
@ -2280,8 +2341,6 @@ static struct io_plan *get_incoming_channels(struct io_conn *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEVELOPER
|
#if DEVELOPER
|
||||||
/* FIXME: One day this will be called internally; for now it's just for
|
|
||||||
* testing with dev_query_scids. */
|
|
||||||
static struct io_plan *query_scids_req(struct io_conn *conn,
|
static struct io_plan *query_scids_req(struct io_conn *conn,
|
||||||
struct daemon *daemon,
|
struct daemon *daemon,
|
||||||
const u8 *msg)
|
const u8 *msg)
|
||||||
|
@ -2289,17 +2348,6 @@ static struct io_plan *query_scids_req(struct io_conn *conn,
|
||||||
struct node_id id;
|
struct node_id id;
|
||||||
struct short_channel_id *scids;
|
struct short_channel_id *scids;
|
||||||
struct peer *peer;
|
struct peer *peer;
|
||||||
u8 *encoded;
|
|
||||||
/* BOLT #7:
|
|
||||||
*
|
|
||||||
* 1. type: 261 (`query_short_channel_ids`) (`gossip_queries`)
|
|
||||||
* 2. data:
|
|
||||||
* * [`32`:`chain_hash`]
|
|
||||||
* * [`2`:`len`]
|
|
||||||
* * [`len`:`encoded_short_ids`]
|
|
||||||
*/
|
|
||||||
const size_t reply_overhead = 32 + 2;
|
|
||||||
const size_t max_encoded_bytes = 65535 - 2 - reply_overhead;
|
|
||||||
|
|
||||||
if (!fromwire_gossip_query_scids(msg, msg, &id, &scids))
|
if (!fromwire_gossip_query_scids(msg, msg, &id, &scids))
|
||||||
master_badmsg(WIRE_GOSSIP_QUERY_SCIDS, msg);
|
master_badmsg(WIRE_GOSSIP_QUERY_SCIDS, msg);
|
||||||
|
@ -2308,40 +2356,14 @@ static struct io_plan *query_scids_req(struct io_conn *conn,
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
status_broken("query_scids: unknown peer %s",
|
status_broken("query_scids: unknown peer %s",
|
||||||
type_to_string(tmpctx, struct node_id, &id));
|
type_to_string(tmpctx, struct node_id, &id));
|
||||||
goto fail;
|
daemon_conn_send(daemon->master,
|
||||||
}
|
take(towire_gossip_scids_reply(NULL,
|
||||||
|
false, false)));
|
||||||
if (!peer->gossip_queries_feature) {
|
} else if (!query_short_channel_ids(daemon, peer, scids, false))
|
||||||
status_broken("query_scids: no gossip_query support in peer %s",
|
daemon_conn_send(daemon->master,
|
||||||
type_to_string(tmpctx, struct node_id, &id));
|
take(towire_gossip_scids_reply(NULL,
|
||||||
goto fail;
|
false, false)));
|
||||||
}
|
|
||||||
|
|
||||||
encoded = encode_short_channel_ids_start(tmpctx);
|
|
||||||
for (size_t i = 0; i < tal_count(scids); i++)
|
|
||||||
encode_add_short_channel_id(&encoded, &scids[i]);
|
|
||||||
|
|
||||||
/* Because this is a dev command, we simply say this case is
|
|
||||||
* "too hard". */
|
|
||||||
if (!encode_short_channel_ids_end(&encoded, max_encoded_bytes)) {
|
|
||||||
status_broken("query_short_channel_ids: %zu is too many",
|
|
||||||
tal_count(scids));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = towire_query_short_channel_ids(NULL, &daemon->chain_hash,
|
|
||||||
encoded);
|
|
||||||
queue_peer_msg(peer, take(msg));
|
|
||||||
peer->num_scid_queries_outstanding++;
|
|
||||||
|
|
||||||
status_trace("sending query for %zu scids", tal_count(scids));
|
|
||||||
out:
|
|
||||||
return daemon_conn_read_next(conn, daemon->master);
|
return daemon_conn_read_next(conn, daemon->master);
|
||||||
|
|
||||||
fail:
|
|
||||||
daemon_conn_send(daemon->master,
|
|
||||||
take(towire_gossip_scids_reply(NULL, false, false)));
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BOLT #7:
|
/* BOLT #7:
|
||||||
|
|
Loading…
Add table
Reference in a new issue