Browse Source

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>
ppa-0.6.1
Rusty Russell 6 years ago
parent
commit
d241bd762c
  1. 32
      connectd/connect.c
  2. 2
      connectd/connect_wire.csv
  3. 7
      gossipd/gossip.c
  4. 30
      lightningd/gossip_msg.c
  5. 12
      lightningd/gossip_msg.h
  6. 44
      lightningd/peer_control.c
  7. 1
      tools/generate-wire.py
  8. 10
      wallet/test/run-wallet.c

32
connectd/connect.c

@ -1782,25 +1782,20 @@ static struct io_plan *peer_disconnected(struct io_conn *conn,
return daemon_conn_read_next(conn, &daemon->master);
}
static void append_node(const struct gossip_getnodes_entry ***nodes,
const struct pubkey *nodeid,
const u8 *gfeatures,
const u8 *lfeatures)
static void append_peer_features(const struct peer_features ***pf,
const u8 *gfeatures,
const u8 *lfeatures)
{
struct gossip_getnodes_entry *new;
size_t num_nodes = tal_count(*nodes);
struct peer_features *new;
size_t num_nodes = tal_count(*pf);
new = tal(*nodes, struct gossip_getnodes_entry);
new->nodeid = *nodeid;
new->global_features = tal_dup_arr(*nodes, u8, gfeatures,
new = tal(*pf, struct peer_features);
new->global_features = tal_dup_arr(new, u8, gfeatures,
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);
/* FIXME: Don't use gossip_getnodes_entry. */
new->last_timestamp = -1;
new->addresses = NULL;
tal_resize(nodes, num_nodes + 1);
(*nodes)[num_nodes] = new;
tal_resize(pf, num_nodes + 1);
(*pf)[num_nodes] = new;
}
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;
struct pubkey *id = tal_arr(conn, struct pubkey, 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;
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;
wireaddr[n] = peer->addr;
append_node(&nodes, &peer->id,
peer->gfeatures, peer->lfeatures);
append_peer_features(&pf, peer->gfeatures, peer->lfeatures);
n++;
}
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);
}

2
connectd/connect_wire.csv

@ -117,7 +117,7 @@ connect_getpeers_reply,2111
connect_getpeers_reply,,num,u16
connect_getpeers_reply,,id,num*struct pubkey
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.
connectctl_peer_disconnect,2023

Can't render this file because it has a wrong number of fields in line 5.

7
gossipd/gossip.c

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

30
lightningd/gossip_msg.c

@ -11,9 +11,6 @@ struct gossip_getnodes_entry *fromwire_gossip_getnodes_entry(const tal_t *ctx,
entry = tal(ctx, struct gossip_getnodes_entry);
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);
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);
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_u8_array(pptr, 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->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));
}

12
lightningd/gossip_msg.h

@ -4,10 +4,14 @@
#include <bitcoin/pubkey.h>
#include <gossipd/routing.h>
struct peer_features {
u8 *local_features;
u8 *global_features;
};
struct gossip_getnodes_entry {
struct pubkey nodeid;
/* We'll only have non-empty local_features if it's a direct peer. */
u8 *local_features, *global_features;
u8 *global_features;
s64 last_timestamp; /* -1 means never: following fields ignored */
struct wireaddr *addresses;
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,
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 towire_route_hop(u8 **pprt, const struct route_hop *entry);

44
lightningd/peer_control.c

@ -704,29 +704,16 @@ struct getpeers_args {
struct pubkey *specific_id;
};
static void json_add_node_decoration(struct json_result *response,
struct gossip_getnodes_entry *node)
static void json_add_features(struct json_result *response,
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",
node->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));
json_add_hex(response, "local_features",
pf->local_features,
tal_len(pf->local_features));
}
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... */
struct pubkey *ids;
struct wireaddr_internal *addrs;
struct gossip_getnodes_entry **nodes;
struct peer_features **pf;
struct json_result *response = new_json_result(gpa->cmd);
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,
"Bad response from connectd");
return;
@ -780,10 +767,10 @@ static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg,
json_array_end(response);
}
/* Search gossip reply for this ID, to add extra info. */
for (size_t i = 0; i < tal_count(nodes); i++) {
if (pubkey_eq(&nodes[i]->nodeid, &p->id)) {
json_add_node_decoration(response, nodes[i]);
/* Search connectd reply for this ID, to add extra info. */
for (size_t i = 0; i < tal_count(ids); i++) {
if (pubkey_eq(&ids[i], &p->id)) {
json_add_features(response, pf[i]);
break;
}
}
@ -791,7 +778,6 @@ static void connectd_getpeers_complete(struct subd *connectd, const u8 *msg,
json_array_start(response, "channels");
json_add_uncommitted_channel(response, p->uncommitted_channel);
/* FIXME: Add their local and global features */
list_for_each(&p->channels, channel, list) {
struct channel_id cid;
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. */
json_add_string(response, "state", "GOSSIPING");
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");
if (addrs[i].itype != ADDR_INTERNAL_WIREADDR
|| addrs[i].u.wireaddr.type != ADDR_TYPE_PADDING)

1
tools/generate-wire.py

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

10
wallet/test/run-wallet.c

@ -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)
{ fprintf(stderr, "fromwire_connectctl_peer_disconnect_replyfail called!\n"); abort(); }
/* 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(); }
/* 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)
@ -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,
bool value UNNEEDED)
{ 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 */
void json_add_hex(struct json_result *result UNNEEDED, const char *fieldname 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 */
void json_array_start(struct json_result *ptr UNNEEDED, const char *fieldname UNNEEDED)
{ 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_ */
struct json_escaped *json_escaped_string_(const tal_t *ctx UNNEEDED,
const void *bytes UNNEEDED, size_t len UNNEEDED)

Loading…
Cancel
Save