diff --git a/contrib/pylightning/lightning/lightning.py b/contrib/pylightning/lightning/lightning.py index 6697069e3..a6f050fc5 100644 --- a/contrib/pylightning/lightning/lightning.py +++ b/contrib/pylightning/lightning/lightning.py @@ -79,13 +79,12 @@ class LightningRpc(UnixDomainSocketRpc): """Get info about a specific peer, optionally with its log. """ if log_level: - peers = self.listpeers(log_level)['peers'] + peers = self.listpeers(peer_id, log_level)['peers'] else: - peers = self.listpeers()['peers'] - for p in peers: - if p['peerid'] == peer_id: - return p - return None + peers = self.listpeers(peer_id)['peers'] + if len(peers) == 0: + return None + return peers[0] def getlog(self, level=None): args = [] diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 6f4d45ddd..ec62d15ec 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -1733,11 +1733,14 @@ 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 *wireaddr = tal_arr(conn, struct wireaddr, n); + struct pubkey *specific_id = NULL; - if (!fromwire_gossip_getpeers_request(msg, NULL)) + if (!fromwire_gossip_getpeers_request(msg, msg, NULL, &specific_id)) master_badmsg(WIRE_GOSSIPCTL_PEER_ADDRHINT, msg); list_for_each(&daemon->peers, peer, list) { + if (specific_id && !pubkey_eq(specific_id, &peer->id)) + continue; tal_resize(&id, n+1); tal_resize(&wireaddr, n+1); diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index dfdc6f9a6..85ffa49d6 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -135,6 +135,9 @@ gossip_resolve_channel_reply,,keys,num_keys*struct pubkey # The main daemon asks for peers gossip_getpeers_request,3011 +# 0 or 1 +gossip_getpeers_request,,num,u16 +gossip_getpeers_request,,id,num*struct pubkey gossip_getpeers_reply,3111 gossip_getpeers_reply,,num,u16 diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index f4d9a4588..e985a6d99 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -790,6 +790,8 @@ struct getpeers_args { struct command *cmd; /* If non-NULL, they want logs too */ enum log_level *ll; + /* If set, only report on a specific id. */ + struct pubkey *specific_id; }; static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg, @@ -811,6 +813,9 @@ static void gossipd_getpeers_complete(struct subd *gossip, const u8 *msg, json_object_start(response, NULL); json_array_start(response, "peers"); list_for_each(&gpa->cmd->ld->peers, p, list) { + if (gpa->specific_id && !pubkey_eq(gpa->specific_id, &p->id)) + continue; + json_object_start(response, NULL); json_add_string(response, "state", peer_state_name(p->state)); json_array_start(response, "netaddr"); @@ -874,13 +879,27 @@ static void json_listpeers(struct command *cmd, { jsmntok_t *leveltok; struct getpeers_args *gpa = tal(cmd, struct getpeers_args); + jsmntok_t *idtok; gpa->cmd = cmd; - if (!json_get_params(buffer, params, "?level", &leveltok, NULL)) { + gpa->specific_id = NULL; + if (!json_get_params(buffer, params, + "?id", &idtok, + "?level", &leveltok, + NULL)) { command_fail(cmd, "Invalid arguments"); return; } + if (idtok) { + gpa->specific_id = tal_arr(cmd, struct pubkey, 1); + if (!json_tok_pubkey(buffer, idtok, gpa->specific_id)) { + command_fail(cmd, "id %.*s not valid", + idtok->end - idtok->start, + buffer + idtok->start); + return; + } + } if (leveltok) { gpa->ll = tal(gpa, enum log_level); if (json_tok_streq(buffer, leveltok, "debug")) @@ -900,7 +919,7 @@ static void json_listpeers(struct command *cmd, /* Get peers from gossipd. */ subd_req(cmd, cmd->ld->gossip, - take(towire_gossip_getpeers_request(cmd)), + take(towire_gossip_getpeers_request(cmd, gpa->specific_id)), -1, 0, gossipd_getpeers_complete, gpa); command_still_pending(cmd); }