Skip to content

Commit dff5c89

Browse files
endothermicdevrustyrussell
authored andcommitted
gossipd: seeker: select random peer and tell lightningd
This does not validate a node announcement and address, but it does select a node at random from the gossmap and asks lightningd to attempt a connection to it.
1 parent 7fc214a commit dff5c89

File tree

3 files changed

+103
-12
lines changed

3 files changed

+103
-12
lines changed

gossipd/seeker.c

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <ccan/asort/asort.h>
66
#include <ccan/intmap/intmap.h>
77
#include <ccan/tal/str/str.h>
8+
#include <common/daemon_conn.h>
89
#include <common/decode_array.h>
910
#include <common/gossmap.h>
1011
#include <common/memleak.h>
@@ -13,6 +14,7 @@
1314
#include <common/status.h>
1415
#include <common/timeout.h>
1516
#include <gossipd/gossipd.h>
17+
#include <gossipd/gossipd_wiregen.h>
1618
#include <gossipd/gossmap_manage.h>
1719
#include <gossipd/queries.h>
1820
#include <gossipd/seeker.h>
@@ -963,18 +965,81 @@ static bool seek_any_unknown_nodes(struct seeker *seeker)
963965
return true;
964966
}
965967

968+
struct node_and_addrs {
969+
struct node_id *id;
970+
struct wireaddr *addrs;
971+
};
972+
973+
/* Find a random node with an address in the announcement. */
974+
static struct node_and_addrs *get_random_node(const tal_t *ctx,
975+
struct seeker *seeker)
976+
{
977+
struct gossmap *gossmap = gossmap_manage_get_gossmap(seeker->daemon->gm);
978+
if (gossmap_num_nodes(gossmap) < 1)
979+
return NULL;
980+
u32 max_idx = gossmap_max_node_idx(gossmap);
981+
if (max_idx < 1)
982+
return NULL;
983+
984+
struct gossmap_node *random_node;
985+
struct node_and_addrs *found_node = NULL;
986+
for (int i = 0; i<20; i++) {
987+
u32 random = pseudorand(max_idx);
988+
random_node = gossmap_node_byidx(gossmap, random);
989+
if (!random_node) {
990+
continue;
991+
}
992+
found_node = tal(ctx, struct node_and_addrs);
993+
found_node->id = tal(found_node, struct node_id);
994+
gossmap_node_get_id(gossmap, random_node, found_node->id);
995+
if (node_id_eq(found_node->id, &seeker->daemon->id)) {
996+
found_node = tal_free(found_node);
997+
continue;
998+
}
999+
found_node->addrs =
1000+
gossmap_manage_get_node_addresses(found_node,
1001+
seeker->daemon->gm,
1002+
found_node->id);
1003+
if (!found_node->addrs || tal_count(found_node->addrs) == 0) {
1004+
found_node = tal_free(found_node);
1005+
continue;
1006+
}
1007+
1008+
break;
1009+
}
1010+
1011+
return found_node;
1012+
1013+
}
1014+
9661015
/* Ask lightningd for more peers if we're short on gossip streamers. */
9671016
static void maybe_get_new_peer(struct seeker *seeker)
9681017
{
9691018
size_t connected_peers = peer_node_id_map_count(seeker->daemon->peers);
970-
if (connected_peers < tal_count(seeker->gossiper)) {
971-
status_debug("seeker: have only %zu connected peers."
972-
" Should connect to more.",
973-
connected_peers);
9741019

1020+
if (connected_peers >= tal_count(seeker->gossiper))
1021+
return;
1022+
1023+
status_debug("seeker: need more peers for gossip (have %zu)",
1024+
connected_peers);
1025+
1026+
const struct node_and_addrs *random_node;
1027+
random_node = get_random_node(tmpctx, seeker);
1028+
if (!random_node) {
1029+
status_debug("seeker: no more potential peers found");
1030+
return;
9751031
}
976-
/* TODO: find random node announcement, see if we can connect,
977-
* ask lightningd to connect via towire_gossipd_connect_to_peer. */
1032+
1033+
if(!random_node->id)
1034+
status_broken("seeker: random gossip node missing node_id");
1035+
1036+
if(!random_node->addrs || tal_count(random_node->addrs) == 0)
1037+
status_broken("seeker: random gossip node missing address");
1038+
1039+
u8 *msg = towire_gossipd_connect_to_peer(NULL, random_node->id,
1040+
random_node->addrs);
1041+
daemon_conn_send(seeker->daemon->master, take(msg));
1042+
tal_free(random_node);
9781043
}
9791044

9801045
/* Periodic timer to see how our gossip is going. */
@@ -1001,7 +1066,6 @@ static void seeker_check(struct seeker *seeker)
10011066
check_probe(seeker, peer_gossip_probe_nannounces);
10021067
break;
10031068
case NORMAL:
1004-
/* FIXME: maybe_get_more_peers(seeker); */
10051069
maybe_get_new_peer(seeker);
10061070
maybe_rotate_gossipers(seeker);
10071071
if (!seek_any_unknown_scids(seeker)

gossipd/test/run-next_block_range.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ bool blinding_next_path_privkey(const struct privkey *e UNNEEDED,
2727
const struct sha256 *h UNNEEDED,
2828
struct privkey *next UNNEEDED)
2929
{ fprintf(stderr, "blinding_next_path_privkey called!\n"); abort(); }
30+
/* Generated stub for daemon_conn_send */
31+
void daemon_conn_send(struct daemon_conn *dc UNNEEDED, const u8 *msg UNNEEDED)
32+
{ fprintf(stderr, "daemon_conn_send called!\n"); abort(); }
3033
/* Generated stub for find_peer */
3134
struct peer *find_peer(struct daemon *daemon UNNEEDED, const struct node_id *id UNNEEDED)
3235
{ fprintf(stderr, "find_peer called!\n"); abort(); }
@@ -62,12 +65,22 @@ struct gossmap_chan *gossmap_find_chan(const struct gossmap *map UNNEEDED,
6265
/* Generated stub for gossmap_manage_get_gossmap */
6366
struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm UNNEEDED)
6467
{ fprintf(stderr, "gossmap_manage_get_gossmap called!\n"); abort(); }
68+
/* Generated stub for gossmap_manage_get_node_addresses */
69+
struct wireaddr *gossmap_manage_get_node_addresses(const tal_t *ctx UNNEEDED,
70+
struct gossmap_manage *gm UNNEEDED,
71+
const struct node_id *node_id UNNEEDED)
72+
{ fprintf(stderr, "gossmap_manage_get_node_addresses called!\n"); abort(); }
6573
/* Generated stub for gossmap_max_node_idx */
6674
u32 gossmap_max_node_idx(const struct gossmap *map UNNEEDED)
6775
{ fprintf(stderr, "gossmap_max_node_idx called!\n"); abort(); }
6876
/* Generated stub for gossmap_node_byidx */
6977
struct gossmap_node *gossmap_node_byidx(const struct gossmap *map UNNEEDED, u32 idx UNNEEDED)
7078
{ fprintf(stderr, "gossmap_node_byidx called!\n"); abort(); }
79+
/* Generated stub for gossmap_node_get_id */
80+
void gossmap_node_get_id(const struct gossmap *map UNNEEDED,
81+
const struct gossmap_node *node UNNEEDED,
82+
struct node_id *id UNNEEDED)
83+
{ fprintf(stderr, "gossmap_node_get_id called!\n"); abort(); }
7184
/* Generated stub for gossmap_nth_chan */
7285
struct gossmap_chan *gossmap_nth_chan(const struct gossmap *map UNNEEDED,
7386
const struct gossmap_node *node UNNEEDED,
@@ -79,6 +92,9 @@ struct gossmap_node *gossmap_nth_node(const struct gossmap *map UNNEEDED,
7992
const struct gossmap_chan *chan UNNEEDED,
8093
int n UNNEEDED)
8194
{ fprintf(stderr, "gossmap_nth_node called!\n"); abort(); }
95+
/* Generated stub for gossmap_num_nodes */
96+
size_t gossmap_num_nodes(const struct gossmap *map UNNEEDED)
97+
{ fprintf(stderr, "gossmap_num_nodes called!\n"); abort(); }
8298
/* Generated stub for memleak_scan_intmap_ */
8399
void memleak_scan_intmap_(struct htable *memtable UNNEEDED, const struct intmap *m UNNEEDED)
84100
{ fprintf(stderr, "memleak_scan_intmap_ called!\n"); abort(); }
@@ -125,6 +141,9 @@ void status_fmt(enum log_level level UNNEEDED,
125141
const char *fmt UNNEEDED, ...)
126142

127143
{ fprintf(stderr, "status_fmt called!\n"); abort(); }
144+
/* Generated stub for towire_gossipd_connect_to_peer */
145+
u8 *towire_gossipd_connect_to_peer(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED, const struct wireaddr *addrs UNNEEDED)
146+
{ fprintf(stderr, "towire_gossipd_connect_to_peer called!\n"); abort(); }
128147
/* Generated stub for towire_sciddir_or_pubkey */
129148
void towire_sciddir_or_pubkey(u8 **pptr UNNEEDED,
130149
const struct sciddir_or_pubkey *sciddpk UNNEEDED)

lightningd/gossip_control.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,21 @@ static void handle_connect_to_peer(struct subd *gossip, const u8 *msg)
177177
{
178178
struct node_id *id = tal(tmpctx, struct node_id);
179179
struct wireaddr *addrs;
180-
if (!fromwire_gossipd_connect_to_peer(tmpctx, msg, id, &addrs))
180+
if (!fromwire_gossipd_connect_to_peer(tmpctx, msg, id, &addrs)) {
181181
log_broken(gossip->ld->log, "malformed peer connect request"
182182
" from gossipd %s", tal_hex(msg, msg));
183-
else
184-
log_debug(gossip->ld->log, "asked to connect to %s",
185-
fmt_node_id(msg, id));
186-
/* TODO: send node_id and address to connectd. */
183+
return;
184+
}
185+
log_debug(gossip->ld->log, "attempting connection to %s "
186+
"for additional gossip", fmt_node_id(tmpctx, id));
187+
u8 *connectmsg;
188+
connectmsg = towire_connectd_connect_to_peer(NULL,
189+
id,
190+
addrs,
191+
NULL, //addrhint,
192+
false, //dns_fallback
193+
true); //transient
194+
subd_send_msg(gossip->ld->connectd, take(connectmsg));
187195
}
188196

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

0 commit comments

Comments
 (0)