Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seeker autoconnect #7798

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
78 changes: 71 additions & 7 deletions gossipd/seeker.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <ccan/asort/asort.h>
#include <ccan/intmap/intmap.h>
#include <ccan/tal/str/str.h>
#include <common/daemon_conn.h>
#include <common/decode_array.h>
#include <common/gossmap.h>
#include <common/memleak.h>
Expand All @@ -13,6 +14,7 @@
#include <common/status.h>
#include <common/timeout.h>
#include <gossipd/gossipd.h>
#include <gossipd/gossipd_wiregen.h>
#include <gossipd/gossmap_manage.h>
#include <gossipd/queries.h>
#include <gossipd/seeker.h>
Expand Down Expand Up @@ -963,18 +965,81 @@ static bool seek_any_unknown_nodes(struct seeker *seeker)
return true;
}

struct node_and_addrs {
struct node_id *id;
struct wireaddr *addrs;
};

/* Find a random node with an address in the announcement. */
static struct node_and_addrs *get_random_node(const tal_t *ctx,
struct seeker *seeker)
{
struct gossmap *gossmap = gossmap_manage_get_gossmap(seeker->daemon->gm);
Comment on lines +974 to +977
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better done by providing a "struct gossmap_node *gossmap_random_node(const struct gossmap *map);" in gossmap.c, which can use nodeidx_htable_pick. Then iterate until NULL, or you find one with an address.

if (gossmap_num_nodes(gossmap) < 1)
return NULL;
u32 max_idx = gossmap_max_node_idx(gossmap);
if (max_idx < 1)
return NULL;

struct gossmap_node *random_node;
struct node_and_addrs *found_node = NULL;
for (int i = 0; i<20; i++) {
u32 random = pseudorand(max_idx);
random_node = gossmap_node_byidx(gossmap, random);
if (!random_node) {
continue;
}
found_node = tal(ctx, struct node_and_addrs);
found_node->id = tal(found_node, struct node_id);
gossmap_node_get_id(gossmap, random_node, found_node->id);
if (node_id_eq(found_node->id, &seeker->daemon->id)) {
found_node = tal_free(found_node);
continue;
}
found_node->addrs =
gossmap_manage_get_node_addresses(found_node,
seeker->daemon->gm,
found_node->id);
if (!found_node->addrs || tal_count(found_node->addrs) == 0) {
found_node = tal_free(found_node);
continue;
}

break;
}

return found_node;

}

/* Ask lightningd for more peers if we're short on gossip streamers. */
static void maybe_get_new_peer(struct seeker *seeker)
{
size_t connected_peers = peer_node_id_map_count(seeker->daemon->peers);
if (connected_peers < ARRAY_SIZE(seeker->gossiper)) {
status_debug("seeker: have only %zu connected peers."
" Should connect to more.",
connected_peers);

if (connected_peers >= ARRAY_SIZE(seeker->gossiper))
return;

status_debug("seeker: need more peers for gossip (have %zu)",
connected_peers);

const struct node_and_addrs *random_node;
random_node = get_random_node(tmpctx, seeker);
if (!random_node) {
status_debug("seeker: no more potential peers found");
return;
}
/* TODO: find random node announcement, see if we can connect,
* ask lightningd to connect via towire_gossipd_connect_to_peer. */

if(!random_node->id)
status_broken("seeker: random gossip node missing node_id");

if(!random_node->addrs || tal_count(random_node->addrs) == 0)
status_broken("seeker: random gossip node missing address");

u8 *msg = towire_gossipd_connect_to_peer(NULL, random_node->id,
random_node->addrs);
daemon_conn_send(seeker->daemon->master, take(msg));
tal_free(random_node);
Comment on lines +1036 to +1042
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify: don't hand addrs here, since connectd already has that logic internally.

}

/* Periodic timer to see how our gossip is going. */
Expand All @@ -1001,7 +1066,6 @@ static void seeker_check(struct seeker *seeker)
check_probe(seeker, peer_gossip_probe_nannounces);
break;
case NORMAL:
/* FIXME: maybe_get_more_peers(seeker); */
maybe_get_new_peer(seeker);
maybe_rotate_gossipers(seeker);
if (!seek_any_unknown_scids(seeker)
Expand Down
19 changes: 19 additions & 0 deletions gossipd/test/run-next_block_range.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ bool blinding_next_path_privkey(const struct privkey *e UNNEEDED,
const struct sha256 *h UNNEEDED,
struct privkey *next UNNEEDED)
{ fprintf(stderr, "blinding_next_path_privkey called!\n"); abort(); }
/* Generated stub for daemon_conn_send */
void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED)
{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); }
/* Generated stub for find_peer */
struct peer *find_peer(struct daemon *daemon UNNEEDED, const struct node_id *id UNNEEDED)
{ fprintf(stderr, "find_peer called!\n"); abort(); }
Expand Down Expand Up @@ -62,12 +65,22 @@ struct gossmap_chan *gossmap_find_chan(const struct gossmap *map UNNEEDED,
/* Generated stub for gossmap_manage_get_gossmap */
struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm UNNEEDED)
{ fprintf(stderr, "gossmap_manage_get_gossmap called!\n"); abort(); }
/* Generated stub for gossmap_manage_get_node_addresses */
struct wireaddr *gossmap_manage_get_node_addresses(const tal_t *ctx UNNEEDED,
struct gossmap_manage *gm UNNEEDED,
const struct node_id *node_id UNNEEDED)
{ fprintf(stderr, "gossmap_manage_get_node_addresses called!\n"); abort(); }
/* Generated stub for gossmap_max_node_idx */
u32 gossmap_max_node_idx(const struct gossmap *map UNNEEDED)
{ fprintf(stderr, "gossmap_max_node_idx called!\n"); abort(); }
/* Generated stub for gossmap_node_byidx */
struct gossmap_node *gossmap_node_byidx(const struct gossmap *map UNNEEDED, u32 idx UNNEEDED)
{ fprintf(stderr, "gossmap_node_byidx called!\n"); abort(); }
/* Generated stub for gossmap_node_get_id */
void gossmap_node_get_id(const struct gossmap *map UNNEEDED,
const struct gossmap_node *node UNNEEDED,
struct node_id *id UNNEEDED)
{ fprintf(stderr, "gossmap_node_get_id called!\n"); abort(); }
/* Generated stub for gossmap_nth_chan */
struct gossmap_chan *gossmap_nth_chan(const struct gossmap *map UNNEEDED,
const struct gossmap_node *node UNNEEDED,
Expand All @@ -79,6 +92,9 @@ struct gossmap_node *gossmap_nth_node(const struct gossmap *map UNNEEDED,
const struct gossmap_chan *chan UNNEEDED,
int n UNNEEDED)
{ fprintf(stderr, "gossmap_nth_node called!\n"); abort(); }
/* Generated stub for gossmap_num_nodes */
size_t gossmap_num_nodes(const struct gossmap *map UNNEEDED)
{ fprintf(stderr, "gossmap_num_nodes called!\n"); abort(); }
/* Generated stub for memleak_scan_intmap_ */
void memleak_scan_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED)
{ fprintf(stderr, "memleak_scan_intmap_ called!\n"); abort(); }
Expand Down Expand Up @@ -125,6 +141,9 @@ void status_fmt(enum log_level level UNNEEDED,
const char *fmt UNNEEDED, ...)

{ fprintf(stderr, "status_fmt called!\n"); abort(); }
/* Generated stub for towire_gossipd_connect_to_peer */
u8 *towire_gossipd_connect_to_peer(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const struct wireaddr *addrs UNNEEDED)
{ fprintf(stderr, "towire_gossipd_connect_to_peer called!\n"); abort(); }
/* Generated stub for towire_sciddir_or_pubkey */
void towire_sciddir_or_pubkey(u8 **pptr UNNEEDED,
const struct sciddir_or_pubkey *sciddpk UNNEEDED)
Expand Down
18 changes: 13 additions & 5 deletions lightningd/gossip_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,21 @@ static void handle_connect_to_peer(struct subd *gossip, const u8 *msg)
{
struct node_id *id = tal(tmpctx, struct node_id);
struct wireaddr *addrs;
if (!fromwire_gossipd_connect_to_peer(tmpctx, msg, id, &addrs))
if (!fromwire_gossipd_connect_to_peer(tmpctx, msg, id, &addrs)) {
log_broken(gossip->ld->log, "malformed peer connect request"
" from gossipd %s", tal_hex(msg, msg));
else
log_debug(gossip->ld->log, "asked to connect to %s",
fmt_node_id(msg, &id));
/* TODO: send node_id and address to connectd. */
return;
}
log_debug(gossip->ld->log, "attempting connection to %s "
"for additional gossip", fmt_node_id(tmpctx, id));
u8 *connectmsg;
connectmsg = towire_connectd_connect_to_peer(NULL,
id,
addrs,
NULL, //addrhint,
false, //dns_fallback
true); //transient
subd_send_msg(gossip->ld->connectd, take(connectmsg));
}

static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
Expand Down