connectd: don't use gossip_getnodes_entry.

gossip_getnodes_entry was used by gossipd for reporting nodes, and for
reporting peers.  But the local_features field is only available for peers,
and most other fields are only available from node_announcement.

Note that the connectd change actually means we get less information
about peers: gossipd used to do the node lookup for peers and include the
node_announcement information if it had it.

Since generate_wire.py can't create arrays-of-arrays, we add a 'struct
peer_features' to encapsulate the two feature arrays for each peer, and
for convenience we add it to lightningd/gossip_msg.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2018-07-24 15:48:59 +09:30
parent c9435787cb
commit d241bd762c
8 changed files with 67 additions and 71 deletions

View File

@@ -1782,25 +1782,20 @@ static struct io_plan *peer_disconnected(struct io_conn *conn,
return daemon_conn_read_next(conn, &daemon->master); return daemon_conn_read_next(conn, &daemon->master);
} }
static void append_node(const struct gossip_getnodes_entry ***nodes, static void append_peer_features(const struct peer_features ***pf,
const struct pubkey *nodeid, const u8 *gfeatures,
const u8 *gfeatures, const u8 *lfeatures)
const u8 *lfeatures)
{ {
struct gossip_getnodes_entry *new; struct peer_features *new;
size_t num_nodes = tal_count(*nodes); size_t num_nodes = tal_count(*pf);
new = tal(*nodes, struct gossip_getnodes_entry); new = tal(*pf, struct peer_features);
new->nodeid = *nodeid; new->global_features = tal_dup_arr(new, u8, gfeatures,
new->global_features = tal_dup_arr(*nodes, u8, gfeatures,
tal_len(gfeatures), 0); tal_len(gfeatures), 0);
new->local_features = tal_dup_arr(*nodes, u8, lfeatures, new->local_features = tal_dup_arr(new, u8, lfeatures,
tal_len(lfeatures), 0); tal_len(lfeatures), 0);
/* FIXME: Don't use gossip_getnodes_entry. */ tal_resize(pf, num_nodes + 1);
new->last_timestamp = -1; (*pf)[num_nodes] = new;
new->addresses = NULL;
tal_resize(nodes, num_nodes + 1);
(*nodes)[num_nodes] = new;
} }
static struct io_plan *get_peers(struct io_conn *conn, static struct io_plan *get_peers(struct io_conn *conn,
@@ -1810,7 +1805,7 @@ static struct io_plan *get_peers(struct io_conn *conn,
size_t n = 0; size_t n = 0;
struct pubkey *id = tal_arr(conn, struct pubkey, n); struct pubkey *id = tal_arr(conn, struct pubkey, n);
struct wireaddr_internal *wireaddr = tal_arr(conn, struct wireaddr_internal, n); struct wireaddr_internal *wireaddr = tal_arr(conn, struct wireaddr_internal, n);
const struct gossip_getnodes_entry **nodes = tal_arr(conn, const struct gossip_getnodes_entry *, n); const struct peer_features **pf = tal_arr(conn, const struct peer_features *, n);
struct pubkey *specific_id; struct pubkey *specific_id;
if (!fromwire_connect_getpeers_request(msg, msg, &specific_id)) if (!fromwire_connect_getpeers_request(msg, msg, &specific_id))
@@ -1824,13 +1819,12 @@ static struct io_plan *get_peers(struct io_conn *conn,
id[n] = peer->id; id[n] = peer->id;
wireaddr[n] = peer->addr; wireaddr[n] = peer->addr;
append_node(&nodes, &peer->id, append_peer_features(&pf, peer->gfeatures, peer->lfeatures);
peer->gfeatures, peer->lfeatures);
n++; n++;
} }
daemon_conn_send(&daemon->master, daemon_conn_send(&daemon->master,
take(towire_connect_getpeers_reply(NULL, id, wireaddr, nodes))); take(towire_connect_getpeers_reply(NULL, id, wireaddr, pf)));
return daemon_conn_read_next(conn, &daemon->master); return daemon_conn_read_next(conn, &daemon->master);
} }

View File

@@ -117,7 +117,7 @@ connect_getpeers_reply,2111
connect_getpeers_reply,,num,u16 connect_getpeers_reply,,num,u16
connect_getpeers_reply,,id,num*struct pubkey connect_getpeers_reply,,id,num*struct pubkey
connect_getpeers_reply,,addr,num*struct wireaddr_internal connect_getpeers_reply,,addr,num*struct wireaddr_internal
connect_getpeers_reply,,nodes,num*struct gossip_getnodes_entry connect_getpeers_reply,,features,num*struct peer_features
# master->connectd: Request to disconnect from a peer. # master->connectd: Request to disconnect from a peer.
connectctl_peer_disconnect,2023 connectctl_peer_disconnect,2023
1 #include <common/cryptomsg.h>
117
118
119
120
121
122
123

View File

@@ -1446,7 +1446,6 @@ static struct io_plan *getchannels_req(struct io_conn *conn, struct daemon *daem
static void append_node(const struct gossip_getnodes_entry ***nodes, static void append_node(const struct gossip_getnodes_entry ***nodes,
const struct pubkey *nodeid, const struct pubkey *nodeid,
const u8 *gfeatures, const u8 *gfeatures,
const u8 *lfeatures,
/* If non-NULL, contains more information */ /* If non-NULL, contains more information */
const struct node *n) const struct node *n)
{ {
@@ -1457,8 +1456,6 @@ static void append_node(const struct gossip_getnodes_entry ***nodes,
new->nodeid = *nodeid; new->nodeid = *nodeid;
new->global_features = tal_dup_arr(*nodes, u8, gfeatures, new->global_features = tal_dup_arr(*nodes, u8, gfeatures,
tal_len(gfeatures), 0); tal_len(gfeatures), 0);
new->local_features = tal_dup_arr(*nodes, u8, lfeatures,
tal_len(lfeatures), 0);
if (!n || n->last_timestamp < 0) { if (!n || n->last_timestamp < 0) {
new->last_timestamp = -1; new->last_timestamp = -1;
new->addresses = NULL; new->addresses = NULL;
@@ -1486,12 +1483,12 @@ static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon,
if (id) { if (id) {
n = get_node(daemon->rstate, id); n = get_node(daemon->rstate, id);
if (n) if (n)
append_node(&nodes, id, n->gfeatures, NULL, n); append_node(&nodes, id, n->gfeatures, n);
} else { } else {
struct node_map_iter i; struct node_map_iter i;
n = node_map_first(daemon->rstate->nodes, &i); n = node_map_first(daemon->rstate->nodes, &i);
while (n != NULL) { while (n != NULL) {
append_node(&nodes, &n->id, n->gfeatures, NULL, n); append_node(&nodes, &n->id, n->gfeatures, n);
n = node_map_next(daemon->rstate->nodes, &i); n = node_map_next(daemon->rstate->nodes, &i);
} }
} }

View File

@@ -11,9 +11,6 @@ struct gossip_getnodes_entry *fromwire_gossip_getnodes_entry(const tal_t *ctx,
entry = tal(ctx, struct gossip_getnodes_entry); entry = tal(ctx, struct gossip_getnodes_entry);
fromwire_pubkey(pptr, max, &entry->nodeid); fromwire_pubkey(pptr, max, &entry->nodeid);
flen = fromwire_u16(pptr, max);
entry->local_features = tal_arr(entry, u8, flen);
fromwire_u8_array(pptr, max, entry->local_features, flen);
flen = fromwire_u16(pptr, max); flen = fromwire_u16(pptr, max);
entry->global_features = tal_arr(entry, u8, flen); entry->global_features = tal_arr(entry, u8, flen);
@@ -47,9 +44,6 @@ void towire_gossip_getnodes_entry(u8 **pptr,
{ {
u8 i, numaddresses = tal_count(entry->addresses); u8 i, numaddresses = tal_count(entry->addresses);
towire_pubkey(pptr, &entry->nodeid); towire_pubkey(pptr, &entry->nodeid);
towire_u16(pptr, tal_count(entry->local_features));
towire_u8_array(pptr, entry->local_features,
tal_count(entry->local_features));
towire_u16(pptr, tal_count(entry->global_features)); towire_u16(pptr, tal_count(entry->global_features));
towire_u8_array(pptr, entry->global_features, towire_u8_array(pptr, entry->global_features,
tal_count(entry->global_features)); tal_count(entry->global_features));
@@ -111,3 +105,27 @@ void towire_gossip_getchannels_entry(u8 **pptr,
towire_u32(pptr, entry->fee_per_millionth); towire_u32(pptr, entry->fee_per_millionth);
towire_u32(pptr, entry->delay); towire_u32(pptr, entry->delay);
} }
struct peer_features *
fromwire_peer_features(const tal_t *ctx, const u8 **pptr, size_t *max)
{
struct peer_features *pf = tal(ctx, struct peer_features);
size_t len;
len = fromwire_u16(pptr, max);
pf->local_features = tal_arr(pf, u8, len);
fromwire_u8_array(pptr, max, pf->local_features, len);
len = fromwire_u16(pptr, max);
pf->global_features = tal_arr(pf, u8, len);
fromwire_u8_array(pptr, max, pf->global_features, len);
return pf;
}
void towire_peer_features(u8 **pptr, const struct peer_features *pf)
{
towire_u16(pptr, tal_len(pf->local_features));
towire_u8_array(pptr, pf->local_features, tal_len(pf->local_features));
towire_u16(pptr, tal_len(pf->global_features));
towire_u8_array(pptr, pf->global_features, tal_len(pf->global_features));
}

View File

@@ -4,10 +4,14 @@
#include <bitcoin/pubkey.h> #include <bitcoin/pubkey.h>
#include <gossipd/routing.h> #include <gossipd/routing.h>
struct peer_features {
u8 *local_features;
u8 *global_features;
};
struct gossip_getnodes_entry { struct gossip_getnodes_entry {
struct pubkey nodeid; struct pubkey nodeid;
/* We'll only have non-empty local_features if it's a direct peer. */ u8 *global_features;
u8 *local_features, *global_features;
s64 last_timestamp; /* -1 means never: following fields ignored */ s64 last_timestamp; /* -1 means never: following fields ignored */
struct wireaddr *addresses; struct wireaddr *addresses;
u8 *alias; u8 *alias;
@@ -31,6 +35,10 @@ fromwire_gossip_getnodes_entry(const tal_t *ctx, const u8 **pptr, size_t *max);
void towire_gossip_getnodes_entry(u8 **pptr, void towire_gossip_getnodes_entry(u8 **pptr,
const struct gossip_getnodes_entry *entry); const struct gossip_getnodes_entry *entry);
struct peer_features *
fromwire_peer_features(const tal_t *ctx, const u8 **pptr, size_t *max);
void towire_peer_features(u8 **pptr, const struct peer_features *features);
void fromwire_route_hop(const u8 **pprt, size_t *max, struct route_hop *entry); void fromwire_route_hop(const u8 **pprt, size_t *max, struct route_hop *entry);
void towire_route_hop(u8 **pprt, const struct route_hop *entry); void towire_route_hop(u8 **pprt, const struct route_hop *entry);

View File

@@ -704,29 +704,16 @@ struct getpeers_args {
struct pubkey *specific_id; struct pubkey *specific_id;
}; };
static void json_add_node_decoration(struct json_result *response, static void json_add_features(struct json_result *response,
struct gossip_getnodes_entry *node) const struct peer_features *pf)
{ {
struct json_escaped *esc; json_add_hex(response, "global_features",
pf->global_features,
tal_len(pf->global_features));
if (node->local_features) json_add_hex(response, "local_features",
json_add_hex(response, "local_features", pf->local_features,
node->local_features, tal_len(pf->local_features));
tal_len(node->local_features));
if (node->global_features)
json_add_hex(response, "global_features",
node->global_features,
tal_len(node->global_features));
/* If node announcement hasn't been received yet, no alias information.
*/
if (node->last_timestamp < 0)
return;
esc = json_escape(NULL, (const char *)node->alias);
json_add_escaped_string(response, "alias", take(esc));
json_add_hex(response, "color", node->color, ARRAY_SIZE(node->color));
} }
static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg, static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg,
@@ -736,11 +723,11 @@ static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg,
/* This is a little sneaky... */ /* This is a little sneaky... */
struct pubkey *ids; struct pubkey *ids;
struct wireaddr_internal *addrs; struct wireaddr_internal *addrs;
struct gossip_getnodes_entry **nodes; struct peer_features **pf;
struct json_result *response = new_json_result(gpa->cmd); struct json_result *response = new_json_result(gpa->cmd);
struct peer *p; struct peer *p;
if (!fromwire_connect_getpeers_reply(msg, msg, &ids, &addrs, &nodes)) { if (!fromwire_connect_getpeers_reply(msg, msg, &ids, &addrs, &pf)) {
command_fail(gpa->cmd, LIGHTNINGD, command_fail(gpa->cmd, LIGHTNINGD,
"Bad response from connectd"); "Bad response from connectd");
return; return;
@@ -780,10 +767,10 @@ static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg,
json_array_end(response); json_array_end(response);
} }
/* Search gossip reply for this ID, to add extra info. */ /* Search connectd reply for this ID, to add extra info. */
for (size_t i = 0; i < tal_count(nodes); i++) { for (size_t i = 0; i < tal_count(ids); i++) {
if (pubkey_eq(&nodes[i]->nodeid, &p->id)) { if (pubkey_eq(&ids[i], &p->id)) {
json_add_node_decoration(response, nodes[i]); json_add_features(response, pf[i]);
break; break;
} }
} }
@@ -791,7 +778,6 @@ static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg,
json_array_start(response, "channels"); json_array_start(response, "channels");
json_add_uncommitted_channel(response, p->uncommitted_channel); json_add_uncommitted_channel(response, p->uncommitted_channel);
/* FIXME: Add their local and global features */
list_for_each(&p->channels, channel, list) { list_for_each(&p->channels, channel, list) {
struct channel_id cid; struct channel_id cid;
u64 our_reserve_msat = channel->channel_info.their_config.channel_reserve_satoshis * 1000; u64 our_reserve_msat = channel->channel_info.their_config.channel_reserve_satoshis * 1000;
@@ -919,7 +905,7 @@ static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg,
/* Fake state. */ /* Fake state. */
json_add_string(response, "state", "GOSSIPING"); json_add_string(response, "state", "GOSSIPING");
json_add_pubkey(response, "id", ids+i); json_add_pubkey(response, "id", ids+i);
json_add_node_decoration(response, nodes[i]); json_add_features(response, pf[i]);
json_array_start(response, "netaddr"); json_array_start(response, "netaddr");
if (addrs[i].itype != ADDR_INTERNAL_WIREADDR if (addrs[i].itype != ADDR_INTERNAL_WIREADDR
|| addrs[i].u.wireaddr.type != ADDR_TYPE_PADDING) || addrs[i].u.wireaddr.type != ADDR_TYPE_PADDING)

View File

@@ -31,6 +31,7 @@ type2size = {
# These struct array helpers require a context to allocate from. # These struct array helpers require a context to allocate from.
varlen_structs = [ varlen_structs = [
'peer_features',
'gossip_getnodes_entry', 'gossip_getnodes_entry',
'failed_htlc', 'failed_htlc',
'utxo', 'utxo',

View File

@@ -72,7 +72,7 @@ bool fromwire_connectctl_peer_disconnect_reply(const void *p UNNEEDED)
bool fromwire_connectctl_peer_disconnect_replyfail(const void *p UNNEEDED, bool *isconnected UNNEEDED) bool fromwire_connectctl_peer_disconnect_replyfail(const void *p UNNEEDED, bool *isconnected UNNEEDED)
{ fprintf(stderr, "fromwire_connectctl_peer_disconnect_replyfail called!\n"); abort(); } { fprintf(stderr, "fromwire_connectctl_peer_disconnect_replyfail called!\n"); abort(); }
/* Generated stub for fromwire_connect_getpeers_reply */ /* Generated stub for fromwire_connect_getpeers_reply */
bool fromwire_connect_getpeers_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey **id UNNEEDED, struct wireaddr_internal **addr UNNEEDED, struct gossip_getnodes_entry ***nodes UNNEEDED) bool fromwire_connect_getpeers_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey **id UNNEEDED, struct wireaddr_internal **addr UNNEEDED, struct peer_features ***features UNNEEDED)
{ fprintf(stderr, "fromwire_connect_getpeers_reply called!\n"); abort(); } { fprintf(stderr, "fromwire_connect_getpeers_reply called!\n"); abort(); }
/* Generated stub for fromwire_connect_peer_connected */ /* Generated stub for fromwire_connect_peer_connected */
bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED) bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED)
@@ -183,11 +183,6 @@ void invoices_waitone(const tal_t *ctx UNNEEDED,
void json_add_bool(struct json_result *result UNNEEDED, const char *fieldname UNNEEDED, void json_add_bool(struct json_result *result UNNEEDED, const char *fieldname UNNEEDED,
bool value UNNEEDED) bool value UNNEEDED)
{ fprintf(stderr, "json_add_bool called!\n"); abort(); } { fprintf(stderr, "json_add_bool called!\n"); abort(); }
/* Generated stub for json_add_escaped_string */
void json_add_escaped_string(struct json_result *result UNNEEDED,
const char *fieldname UNNEEDED,
const struct json_escaped *esc TAKES UNNEEDED)
{ fprintf(stderr, "json_add_escaped_string called!\n"); abort(); }
/* Generated stub for json_add_hex */ /* Generated stub for json_add_hex */
void json_add_hex(struct json_result *result UNNEEDED, const char *fieldname UNNEEDED, void json_add_hex(struct json_result *result UNNEEDED, const char *fieldname UNNEEDED,
const void *data UNNEEDED, size_t len UNNEEDED) const void *data UNNEEDED, size_t len UNNEEDED)
@@ -231,9 +226,6 @@ void json_array_end(struct json_result *ptr UNNEEDED)
/* Generated stub for json_array_start */ /* Generated stub for json_array_start */
void json_array_start(struct json_result *ptr UNNEEDED, const char *fieldname UNNEEDED) void json_array_start(struct json_result *ptr UNNEEDED, const char *fieldname UNNEEDED)
{ fprintf(stderr, "json_array_start called!\n"); abort(); } { fprintf(stderr, "json_array_start called!\n"); abort(); }
/* Generated stub for json_escape */
struct json_escaped *json_escape(const tal_t *ctx UNNEEDED, const char *str TAKES UNNEEDED)
{ fprintf(stderr, "json_escape called!\n"); abort(); }
/* Generated stub for json_escaped_string_ */ /* Generated stub for json_escaped_string_ */
struct json_escaped *json_escaped_string_(const tal_t *ctx UNNEEDED, struct json_escaped *json_escaped_string_(const tal_t *ctx UNNEEDED,
const void *bytes UNNEEDED, size_t len UNNEEDED) const void *bytes UNNEEDED, size_t len UNNEEDED)