mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 18:57:06 +01:00
listpeers: expose peer features as 'local_features' and 'global_features'
For now, just the connected peers. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
7b735fbeee
commit
9fa738a741
5 changed files with 47 additions and 4 deletions
|
@ -2104,6 +2104,8 @@ 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 *lfeatures,
|
||||||
/* If non-NULL, contains more information */
|
/* If non-NULL, contains more information */
|
||||||
const struct node *n)
|
const struct node *n)
|
||||||
{
|
{
|
||||||
|
@ -2112,6 +2114,10 @@ static void append_node(const struct gossip_getnodes_entry ***nodes,
|
||||||
|
|
||||||
new = tal(*nodes, struct gossip_getnodes_entry);
|
new = tal(*nodes, struct gossip_getnodes_entry);
|
||||||
new->nodeid = *nodeid;
|
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) {
|
if (!n || n->last_timestamp < 0) {
|
||||||
new->last_timestamp = -1;
|
new->last_timestamp = -1;
|
||||||
new->addresses = NULL;
|
new->addresses = NULL;
|
||||||
|
@ -2140,13 +2146,15 @@ static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon,
|
||||||
for (size_t i = 0; i < tal_count(ids); i++) {
|
for (size_t i = 0; i < tal_count(ids); i++) {
|
||||||
n = get_node(daemon->rstate, &ids[i]);
|
n = get_node(daemon->rstate, &ids[i]);
|
||||||
if (n)
|
if (n)
|
||||||
append_node(&nodes, &ids[i], n);
|
/* FIXME: Keep global features from node_announcement! */
|
||||||
|
append_node(&nodes, &ids[i], NULL, NULL, 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);
|
/* FIXME: Keep global features from node_announcement! */
|
||||||
|
append_node(&nodes, &n->id, NULL, NULL, n);
|
||||||
n = node_map_next(daemon->rstate->nodes, &i);
|
n = node_map_next(daemon->rstate->nodes, &i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3433,7 +3441,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 *, 0);
|
const struct gossip_getnodes_entry **nodes = tal_arr(conn, const struct gossip_getnodes_entry *, n);
|
||||||
struct pubkey *specific_id = NULL;
|
struct pubkey *specific_id = NULL;
|
||||||
|
|
||||||
if (!fromwire_gossip_getpeers_request(msg, msg, &specific_id))
|
if (!fromwire_gossip_getpeers_request(msg, msg, &specific_id))
|
||||||
|
@ -3448,6 +3456,7 @@ 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_node(&nodes, &peer->id,
|
||||||
|
peer->gfeatures, peer->lfeatures,
|
||||||
get_node(daemon->rstate, &peer->id));
|
get_node(daemon->rstate, &peer->id));
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,19 @@ struct gossip_getnodes_entry *fromwire_gossip_getnodes_entry(const tal_t *ctx,
|
||||||
{
|
{
|
||||||
u8 numaddresses, i;
|
u8 numaddresses, i;
|
||||||
struct gossip_getnodes_entry *entry;
|
struct gossip_getnodes_entry *entry;
|
||||||
|
u16 flen;
|
||||||
|
|
||||||
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);
|
||||||
entry->last_timestamp = fromwire_u64(pptr, max);
|
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);
|
||||||
|
fromwire_u8_array(pptr, max, entry->global_features, flen);
|
||||||
|
|
||||||
|
entry->last_timestamp = fromwire_u64(pptr, max);
|
||||||
if (entry->last_timestamp < 0) {
|
if (entry->last_timestamp < 0) {
|
||||||
entry->addresses = NULL;
|
entry->addresses = NULL;
|
||||||
entry->alias = NULL;
|
entry->alias = NULL;
|
||||||
|
@ -30,6 +38,7 @@ struct gossip_getnodes_entry *fromwire_gossip_getnodes_entry(const tal_t *ctx,
|
||||||
entry->alias = tal_arr(entry, u8, fromwire_u8(pptr, max));
|
entry->alias = tal_arr(entry, u8, fromwire_u8(pptr, max));
|
||||||
fromwire(pptr, max, entry->alias, tal_len(entry->alias));
|
fromwire(pptr, max, entry->alias, tal_len(entry->alias));
|
||||||
fromwire(pptr, max, entry->color, sizeof(entry->color));
|
fromwire(pptr, max, entry->color, sizeof(entry->color));
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +47,12 @@ 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_u8_array(pptr, entry->global_features,
|
||||||
|
tal_count(entry->global_features));
|
||||||
towire_u64(pptr, entry->last_timestamp);
|
towire_u64(pptr, entry->last_timestamp);
|
||||||
|
|
||||||
if (entry->last_timestamp < 0)
|
if (entry->last_timestamp < 0)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
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 *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;
|
||||||
|
|
|
@ -708,6 +708,16 @@ static void json_add_node_decoration(struct json_result *response,
|
||||||
{
|
{
|
||||||
struct json_escaped *esc;
|
struct json_escaped *esc;
|
||||||
|
|
||||||
|
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 announcement hasn't been received yet, no alias information.
|
||||||
*/
|
*/
|
||||||
if (node->last_timestamp < 0)
|
if (node->last_timestamp < 0)
|
||||||
|
@ -780,6 +790,7 @@ static void gossipd_getpeers_complete(struct subd *gossip, 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;
|
||||||
|
|
|
@ -426,6 +426,12 @@ class LightningDTests(BaseLightningDTests):
|
||||||
.format(l1.daemon.lightning_dir, leaks))
|
.format(l1.daemon.lightning_dir, leaks))
|
||||||
l1.rpc.stop()
|
l1.rpc.stop()
|
||||||
|
|
||||||
|
def test_features(self):
|
||||||
|
l1, l2 = self.connect()
|
||||||
|
|
||||||
|
# LOCAL_INITIAL_ROUTING_SYNC + LOCAL_GOSSIP_QUERIES
|
||||||
|
assert l1.rpc.listpeers()['peers'][0]['local_features'] == '88'
|
||||||
|
|
||||||
def test_autocleaninvoice(self):
|
def test_autocleaninvoice(self):
|
||||||
l1 = self.node_factory.get_node()
|
l1 = self.node_factory.get_node()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue