seeker: start doing a channel probe if we see unknown node_announcement msgs.
It usually means we're missing something, but there's no way to ask what. Simply start a broad scid probe. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
f7cffbad98
commit
a1644c1b6e
|
@ -202,7 +202,8 @@ static void update_own_node_announcement(struct daemon *daemon)
|
|||
|
||||
/* This injects it into the routing code in routing.c; it should not
|
||||
* reject it! */
|
||||
err = handle_node_announcement(daemon->rstate, take(nannounce), NULL);
|
||||
err = handle_node_announcement(daemon->rstate, take(nannounce),
|
||||
NULL, NULL);
|
||||
if (err)
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"rejected own node announcement: %s",
|
||||
|
|
|
@ -721,7 +721,7 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
|||
case WIRE_NODE_ANNOUNCEMENT:
|
||||
if (!routing_add_node_announcement(rstate,
|
||||
take(msg), gs->len,
|
||||
NULL)) {
|
||||
NULL, NULL)) {
|
||||
bad = "Bad node_announcement";
|
||||
goto badmsg;
|
||||
}
|
||||
|
|
|
@ -395,6 +395,18 @@ out:
|
|||
return true;
|
||||
}
|
||||
|
||||
static u8 *handle_node_announce(struct peer *peer, const u8 *msg)
|
||||
{
|
||||
bool was_unknown = false;
|
||||
u8 *err;
|
||||
|
||||
err = handle_node_announcement(peer->daemon->rstate, msg, peer,
|
||||
&was_unknown);
|
||||
if (was_unknown)
|
||||
query_unknown_node(peer->daemon->seeker, peer);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*~ This is where the per-peer daemons send us messages. It's either forwarded
|
||||
* gossip, or a request for information. We deliberately use non-overlapping
|
||||
* message types so we can distinguish them. */
|
||||
|
@ -414,7 +426,7 @@ static struct io_plan *peer_msg_in(struct io_conn *conn,
|
|||
err = handle_channel_update_msg(peer, msg);
|
||||
goto handled_relay;
|
||||
case WIRE_NODE_ANNOUNCEMENT:
|
||||
err = handle_node_announcement(peer->daemon->rstate, msg, peer);
|
||||
err = handle_node_announce(peer, msg);
|
||||
goto handled_relay;
|
||||
case WIRE_QUERY_CHANNEL_RANGE:
|
||||
err = handle_query_channel_range(peer, msg);
|
||||
|
|
|
@ -1517,7 +1517,7 @@ static void process_pending_node_announcement(struct routing_state *rstate,
|
|||
if (!routing_add_node_announcement(rstate,
|
||||
pna->node_announcement,
|
||||
pna->index,
|
||||
pna->peer_softref))
|
||||
pna->peer_softref, NULL))
|
||||
status_unusual("pending node_announcement %s too old?",
|
||||
tal_hex(tmpctx, pna->node_announcement));
|
||||
/* Never send this again. */
|
||||
|
@ -2390,7 +2390,8 @@ struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser)
|
|||
bool routing_add_node_announcement(struct routing_state *rstate,
|
||||
const u8 *msg TAKES,
|
||||
u32 index,
|
||||
struct peer *peer)
|
||||
struct peer *peer,
|
||||
bool *was_unknown)
|
||||
{
|
||||
struct node *node;
|
||||
secp256k1_ecdsa_signature signature;
|
||||
|
@ -2400,6 +2401,9 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
|||
u8 alias[32];
|
||||
u8 *features, *addresses;
|
||||
|
||||
if (was_unknown)
|
||||
*was_unknown = false;
|
||||
|
||||
/* Make sure we own msg, even if we don't save it. */
|
||||
if (taken(msg))
|
||||
tal_steal(tmpctx, msg);
|
||||
|
@ -2442,6 +2446,8 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
|||
pna = pending_node_map_get(rstate->pending_node_map,
|
||||
&node_id);
|
||||
if (!pna) {
|
||||
if (was_unknown)
|
||||
*was_unknown = true;
|
||||
bad_gossip_order(msg, peer,
|
||||
type_to_string(tmpctx, struct node_id,
|
||||
&node_id));
|
||||
|
@ -2525,7 +2531,7 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
|||
}
|
||||
|
||||
u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann,
|
||||
struct peer *peer)
|
||||
struct peer *peer, bool *was_unknown)
|
||||
{
|
||||
u8 *serialized;
|
||||
struct sha256_double hash;
|
||||
|
@ -2538,6 +2544,9 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann,
|
|||
struct wireaddr *wireaddrs;
|
||||
size_t len = tal_count(node_ann);
|
||||
|
||||
if (was_unknown)
|
||||
*was_unknown = false;
|
||||
|
||||
serialized = tal_dup_arr(tmpctx, u8, node_ann, len, 0);
|
||||
if (!fromwire_node_announcement(tmpctx, serialized,
|
||||
&signature, &features, ×tamp,
|
||||
|
@ -2613,7 +2622,7 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann,
|
|||
}
|
||||
|
||||
/* May still fail, if we don't know the node. */
|
||||
routing_add_node_announcement(rstate, serialized, 0, peer);
|
||||
routing_add_node_announcement(rstate, serialized, 0, peer, was_unknown);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -392,9 +392,11 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
|
|||
struct peer *peer,
|
||||
struct short_channel_id *unknown_scid);
|
||||
|
||||
/* Returns NULL if all OK, otherwise an error for the peer which sent. */
|
||||
/* Returns NULL if all OK, otherwise an error for the peer which sent.
|
||||
* If was_unknown is not NULL, sets it to true if that was the reason for
|
||||
* the error: the node was unknown to us. */
|
||||
u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node,
|
||||
struct peer *peer);
|
||||
struct peer *peer, bool *was_unknown);
|
||||
|
||||
/* Get a node: use this instead of node_map_get() */
|
||||
struct node *get_node(struct routing_state *rstate,
|
||||
|
@ -460,7 +462,8 @@ bool routing_add_channel_update(struct routing_state *rstate,
|
|||
bool routing_add_node_announcement(struct routing_state *rstate,
|
||||
const u8 *msg TAKES,
|
||||
u32 index,
|
||||
struct peer *peer);
|
||||
struct peer *peer,
|
||||
bool *was_unknown);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -96,6 +96,10 @@ struct seeker {
|
|||
u8 *nannounce_query_flags;
|
||||
size_t nannounce_offset;
|
||||
|
||||
/* Are there any node_ids we didn't know? Implies we're
|
||||
* missing channels. */
|
||||
bool unknown_nodes;
|
||||
|
||||
/* Peers we've asked to stream us gossip */
|
||||
struct peer *gossiper_softref[3];
|
||||
|
||||
|
@ -148,6 +152,7 @@ struct seeker *new_seeker(struct daemon *daemon)
|
|||
for (size_t i = 0; i < ARRAY_SIZE(seeker->gossiper_softref); i++)
|
||||
seeker->gossiper_softref[i] = NULL;
|
||||
seeker->preferred_peer_softref = NULL;
|
||||
seeker->unknown_nodes = false;
|
||||
set_state(seeker, STARTING_UP);
|
||||
begin_check_timer(seeker);
|
||||
memleak_add_helper(seeker, memleak_help_seeker);
|
||||
|
@ -186,7 +191,12 @@ static struct peer *random_seeker(struct seeker *seeker,
|
|||
{
|
||||
struct peer *peer = seeker->preferred_peer_softref;
|
||||
|
||||
if (peer && check_peer(peer)) {
|
||||
/* 80% chance of immediately choosing a peer who reported the missing
|
||||
* stuff: they presumably can tell us more about it. We don't
|
||||
* *always* choose it because it could be simply spamming us with
|
||||
* invalid announcements to get chosen, and we don't handle that case
|
||||
* well yet. */
|
||||
if (peer && check_peer(peer) && pseudorand(5) != 0) {
|
||||
clear_softref(seeker, &seeker->random_peer_softref);
|
||||
return peer;
|
||||
}
|
||||
|
@ -409,6 +419,7 @@ static bool seek_any_stale_scids(struct seeker *seeker)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* We can't ask for channels by node_id, so probe at random */
|
||||
/* Returns true and sets first_blocknum and number_of_blocks if
|
||||
* there's more to find. */
|
||||
static bool next_block_range(struct seeker *seeker,
|
||||
|
@ -846,6 +857,16 @@ set_gossiper:
|
|||
enable_gossip_stream(seeker, peer);
|
||||
}
|
||||
|
||||
static bool seek_any_unknown_nodes(struct seeker *seeker)
|
||||
{
|
||||
if (!seeker->unknown_nodes)
|
||||
return false;
|
||||
|
||||
seeker->unknown_nodes = false;
|
||||
probe_many_random_scids(seeker);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Periodic timer to see how our gossip is going. */
|
||||
static void seeker_check(struct seeker *seeker)
|
||||
{
|
||||
|
@ -867,8 +888,9 @@ static void seeker_check(struct seeker *seeker)
|
|||
break;
|
||||
case NORMAL:
|
||||
maybe_rotate_gossipers(seeker);
|
||||
if (!seek_any_unknown_scids(seeker))
|
||||
seek_any_stale_scids(seeker);
|
||||
if (!seek_any_unknown_scids(seeker)
|
||||
&& !seek_any_stale_scids(seeker))
|
||||
seek_any_unknown_nodes(seeker);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -953,3 +975,10 @@ void query_unknown_channel(struct daemon *daemon,
|
|||
if (!add_unknown_scid(daemon->seeker, id, peer))
|
||||
return;
|
||||
}
|
||||
|
||||
/* This peer told us about an unknown node. Start probing it. */
|
||||
void query_unknown_node(struct seeker *seeker, struct peer *peer)
|
||||
{
|
||||
seeker->unknown_nodes = true;
|
||||
set_preferred_peer(seeker, peer);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ void query_unknown_channel(struct daemon *daemon,
|
|||
struct peer *peer,
|
||||
const struct short_channel_id *id);
|
||||
|
||||
void query_unknown_node(struct seeker *seeker, struct peer *peer);
|
||||
|
||||
void seeker_setup_peer_gossip(struct seeker *seeker, struct peer *peer);
|
||||
|
||||
bool remove_unknown_scid(struct seeker *seeker,
|
||||
|
|
|
@ -58,7 +58,7 @@ u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *updat
|
|||
{ fprintf(stderr, "handle_channel_update called!\n"); abort(); }
|
||||
/* Generated stub for handle_node_announcement */
|
||||
u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED,
|
||||
struct peer *peer UNNEEDED)
|
||||
struct peer *peer UNNEEDED, bool *was_unknown UNNEEDED)
|
||||
{ fprintf(stderr, "handle_node_announcement called!\n"); abort(); }
|
||||
/* Generated stub for master_badmsg */
|
||||
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
||||
|
|
Loading…
Reference in New Issue