gossipd: wire up infrastructure to generate query_short_channel_ids msg.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
7ee5da858c
commit
4d8b29089b
143
gossipd/gossip.c
143
gossipd/gossip.c
|
@ -228,6 +228,9 @@ struct peer {
|
|||
/* Is it time to continue the staggered broadcast? */
|
||||
bool gossip_sync;
|
||||
|
||||
/* How many query responses are we expecting? */
|
||||
size_t num_scid_queries_outstanding;
|
||||
|
||||
/* Only one of these is set: */
|
||||
struct local_peer_state *local;
|
||||
struct daemon_conn *remote;
|
||||
|
@ -348,6 +351,7 @@ static struct peer *new_peer(const tal_t *ctx,
|
|||
peer->scid_query_idx = 0;
|
||||
peer->scid_query_nodes = NULL;
|
||||
peer->scid_query_nodes_idx = 0;
|
||||
peer->num_scid_queries_outstanding = 0;
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
@ -403,6 +407,30 @@ static void reached_peer(struct peer *peer, struct io_conn *conn)
|
|||
tal_free(r);
|
||||
}
|
||||
|
||||
static u8 *encode_short_channel_ids_start(const tal_t *ctx)
|
||||
{
|
||||
/* BOLT #7:
|
||||
*
|
||||
* Encoding types:
|
||||
* * `0`: uncompressed array of `short_channel_id` types, in ascending
|
||||
* order.
|
||||
*/
|
||||
u8 *encoded = tal_arr(tmpctx, u8, 0);
|
||||
towire_u8(&encoded, 0);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static void encode_add_short_channel_id(u8 **encoded,
|
||||
const struct short_channel_id *scid)
|
||||
{
|
||||
towire_short_channel_id(encoded, scid);
|
||||
}
|
||||
|
||||
static bool encode_short_channel_ids_end(u8 **encoded, size_t max_bytes)
|
||||
{
|
||||
return tal_len(*encoded) <= max_bytes;
|
||||
}
|
||||
|
||||
static void queue_peer_msg(struct peer *peer, const u8 *msg TAKES)
|
||||
{
|
||||
if (peer->local) {
|
||||
|
@ -820,6 +848,34 @@ static void handle_pong(struct peer *peer, const u8 *pong)
|
|||
tal_len(pong))));
|
||||
}
|
||||
|
||||
static void handle_reply_short_channel_ids_end(struct peer *peer, u8 *msg)
|
||||
{
|
||||
struct bitcoin_blkid chain;
|
||||
u8 complete;
|
||||
|
||||
if (!fromwire_reply_short_channel_ids_end(msg, &chain, &complete)) {
|
||||
peer_error(peer, "Bad reply_short_channel_ids_end %s",
|
||||
tal_hex(tmpctx, msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!structeq(&peer->daemon->rstate->chain_hash, &chain)) {
|
||||
peer_error(peer, "reply_short_channel_ids_end for bad chain: %s",
|
||||
tal_hex(tmpctx, msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (peer->num_scid_queries_outstanding == 0) {
|
||||
peer_error(peer, "unexpected reply_short_channel_ids_end: %s",
|
||||
tal_hex(tmpctx, msg));
|
||||
return;
|
||||
}
|
||||
|
||||
peer->num_scid_queries_outstanding--;
|
||||
msg = towire_gossip_scids_reply(msg, true, complete);
|
||||
daemon_conn_send(&peer->daemon->master, take(msg));
|
||||
}
|
||||
|
||||
/* If master asks us to release peer, we attach this destructor in case it
|
||||
* dies while we're waiting for it to finish IO */
|
||||
static void fail_release(struct peer *peer)
|
||||
|
@ -903,6 +959,10 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
|
|||
handle_query_short_channel_ids(peer, msg);
|
||||
return peer_next_in(conn, peer);
|
||||
|
||||
case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
|
||||
handle_reply_short_channel_ids_end(peer, msg);
|
||||
return peer_next_in(conn, peer);
|
||||
|
||||
case WIRE_OPEN_CHANNEL:
|
||||
case WIRE_CHANNEL_REESTABLISH:
|
||||
case WIRE_ACCEPT_CHANNEL:
|
||||
|
@ -927,7 +987,6 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
|
|||
/* This will wait. */
|
||||
return peer_next_in(conn, peer);
|
||||
|
||||
case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
|
||||
case WIRE_QUERY_CHANNEL_RANGE:
|
||||
case WIRE_REPLY_CHANNEL_RANGE:
|
||||
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
||||
|
@ -1037,7 +1096,7 @@ static bool create_next_scid_reply(struct peer *peer)
|
|||
struct chan *chan;
|
||||
|
||||
chan = get_channel(rstate, &peer->scid_queries[i]);
|
||||
if (!chan || is_chan_public(chan))
|
||||
if (!chan || !is_chan_public(chan))
|
||||
continue;
|
||||
|
||||
queue_peer_msg(peer, chan->channel_announce);
|
||||
|
@ -1336,6 +1395,8 @@ static struct io_plan *owner_msg_in(struct io_conn *conn,
|
|||
queue_peer_msg(peer, take(err));
|
||||
} else if (type == WIRE_QUERY_SHORT_CHANNEL_IDS) {
|
||||
handle_query_short_channel_ids(peer, dc->msg_in);
|
||||
} else if (type == WIRE_REPLY_SHORT_CHANNEL_IDS_END) {
|
||||
handle_reply_short_channel_ids_end(peer, dc->msg_in);
|
||||
} else if (type == WIRE_GOSSIP_GET_UPDATE) {
|
||||
handle_get_update(peer, dc->msg_in);
|
||||
} else if (type == WIRE_GOSSIP_LOCAL_ADD_CHANNEL) {
|
||||
|
@ -1751,6 +1812,7 @@ static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon,
|
|||
return daemon_conn_read_next(conn, &daemon->master);
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon,
|
||||
const u8 *msg)
|
||||
{
|
||||
|
@ -1793,6 +1855,67 @@ out:
|
|||
return daemon_conn_read_next(conn, &daemon->master);
|
||||
}
|
||||
|
||||
static struct io_plan *query_scids_req(struct io_conn *conn,
|
||||
struct daemon *daemon,
|
||||
const u8 *msg)
|
||||
{
|
||||
struct pubkey id;
|
||||
struct short_channel_id *scids;
|
||||
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))
|
||||
master_badmsg(WIRE_GOSSIP_QUERY_SCIDS, msg);
|
||||
|
||||
peer = find_peer(daemon, &id);
|
||||
if (!peer) {
|
||||
status_broken("query_scids: unknown peer %s",
|
||||
type_to_string(tmpctx, struct pubkey, &id));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!feature_offered(peer->lfeatures, LOCAL_GOSSIP_QUERIES)) {
|
||||
status_broken("query_scids: no gossip_query support in peer %s",
|
||||
type_to_string(tmpctx, struct pubkey, &id));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
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));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
msg = towire_query_short_channel_ids(NULL, &daemon->rstate->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);
|
||||
|
||||
fail:
|
||||
daemon_conn_send(&daemon->master,
|
||||
take(towire_gossip_scids_reply(NULL, false, false)));
|
||||
goto out;
|
||||
}
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
static int make_listen_fd(int domain, void *addr, socklen_t len, bool mayfail)
|
||||
{
|
||||
int fd = socket(domain, SOCK_STREAM, 0);
|
||||
|
@ -2966,9 +3089,6 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
|
|||
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
|
||||
return getchannels_req(conn, daemon, daemon->master.msg_in);
|
||||
|
||||
case WIRE_GOSSIP_PING:
|
||||
return ping_req(conn, daemon, daemon->master.msg_in);
|
||||
|
||||
case WIRE_GOSSIP_RESOLVE_CHANNEL_REQUEST:
|
||||
return resolve_channel_req(conn, daemon, daemon->master.msg_in);
|
||||
|
||||
|
@ -3008,6 +3128,18 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
|
|||
case WIRE_GOSSIP_LOCAL_CHANNEL_CLOSE:
|
||||
return handle_local_channel_close(conn, daemon, master->msg_in);
|
||||
|
||||
#if DEVELOPER
|
||||
case WIRE_GOSSIP_PING:
|
||||
return ping_req(conn, daemon, daemon->master.msg_in);
|
||||
|
||||
case WIRE_GOSSIP_QUERY_SCIDS:
|
||||
return query_scids_req(conn, daemon, daemon->master.msg_in);
|
||||
#else
|
||||
case WIRE_GOSSIP_PING:
|
||||
case WIRE_GOSSIP_QUERY_SCIDS:
|
||||
break;
|
||||
#endif /* !DEVELOPER */
|
||||
|
||||
/* We send these, we don't receive them */
|
||||
case WIRE_GOSSIPCTL_ACTIVATE_REPLY:
|
||||
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
|
||||
|
@ -3017,6 +3149,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
|
|||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||
case WIRE_GOSSIP_GETPEERS_REPLY:
|
||||
case WIRE_GOSSIP_PING_REPLY:
|
||||
case WIRE_GOSSIP_SCIDS_REPLY:
|
||||
case WIRE_GOSSIP_RESOLVE_CHANNEL_REPLY:
|
||||
case WIRE_GOSSIP_PEER_CONNECTED:
|
||||
case WIRE_GOSSIPCTL_CONNECT_TO_PEER_RESULT:
|
||||
|
|
|
@ -155,6 +155,17 @@ gossip_ping_reply,,sent,bool
|
|||
# 0 == no pong expected
|
||||
gossip_ping_reply,,totlen,u16
|
||||
|
||||
# Test of query_short_channel_ids. Master->gossipd
|
||||
gossip_query_scids,3031
|
||||
gossip_query_scids,,id,struct pubkey
|
||||
gossip_query_scids,,num_ids,u16
|
||||
gossip_query_scids,,ids,num_ids*struct short_channel_id
|
||||
|
||||
# Gossipd -> master
|
||||
gossip_scids_reply,3131
|
||||
gossip_scids_reply,,ok,bool
|
||||
gossip_scids_reply,,complete,bool
|
||||
|
||||
# Given a short_channel_id, return the endpoints
|
||||
gossip_resolve_channel_request,3009
|
||||
gossip_resolve_channel_request,,channel_id,struct short_channel_id
|
||||
|
|
|
|
@ -136,6 +136,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
|||
case WIRE_GOSSIP_OUTPOINT_SPENT:
|
||||
case WIRE_GOSSIP_ROUTING_FAILURE:
|
||||
case WIRE_GOSSIP_MARK_CHANNEL_UNROUTABLE:
|
||||
case WIRE_GOSSIP_QUERY_SCIDS:
|
||||
case WIRE_GOSSIPCTL_PEER_DISCONNECT:
|
||||
case WIRE_GOSSIPCTL_PEER_IMPORTANT:
|
||||
case WIRE_GOSSIPCTL_PEER_DISCONNECTED:
|
||||
|
@ -147,6 +148,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
|||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||
case WIRE_GOSSIP_GETPEERS_REPLY:
|
||||
case WIRE_GOSSIP_PING_REPLY:
|
||||
case WIRE_GOSSIP_SCIDS_REPLY:
|
||||
case WIRE_GOSSIP_RESOLVE_CHANNEL_REPLY:
|
||||
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
|
||||
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
|
||||
|
|
Loading…
Reference in New Issue