mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
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:
committed by
neil saitug
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
|
/* This injects it into the routing code in routing.c; it should not
|
||||||
* reject it! */
|
* reject it! */
|
||||||
err = handle_node_announcement(daemon->rstate, take(nannounce), NULL);
|
err = handle_node_announcement(daemon->rstate, take(nannounce),
|
||||||
|
NULL, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
"rejected own node announcement: %s",
|
"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:
|
case WIRE_NODE_ANNOUNCEMENT:
|
||||||
if (!routing_add_node_announcement(rstate,
|
if (!routing_add_node_announcement(rstate,
|
||||||
take(msg), gs->len,
|
take(msg), gs->len,
|
||||||
NULL)) {
|
NULL, NULL)) {
|
||||||
bad = "Bad node_announcement";
|
bad = "Bad node_announcement";
|
||||||
goto badmsg;
|
goto badmsg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -395,6 +395,18 @@ out:
|
|||||||
return true;
|
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
|
/*~ 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
|
* gossip, or a request for information. We deliberately use non-overlapping
|
||||||
* message types so we can distinguish them. */
|
* 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);
|
err = handle_channel_update_msg(peer, msg);
|
||||||
goto handled_relay;
|
goto handled_relay;
|
||||||
case WIRE_NODE_ANNOUNCEMENT:
|
case WIRE_NODE_ANNOUNCEMENT:
|
||||||
err = handle_node_announcement(peer->daemon->rstate, msg, peer);
|
err = handle_node_announce(peer, msg);
|
||||||
goto handled_relay;
|
goto handled_relay;
|
||||||
case WIRE_QUERY_CHANNEL_RANGE:
|
case WIRE_QUERY_CHANNEL_RANGE:
|
||||||
err = handle_query_channel_range(peer, msg);
|
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,
|
if (!routing_add_node_announcement(rstate,
|
||||||
pna->node_announcement,
|
pna->node_announcement,
|
||||||
pna->index,
|
pna->index,
|
||||||
pna->peer_softref))
|
pna->peer_softref, NULL))
|
||||||
status_unusual("pending node_announcement %s too old?",
|
status_unusual("pending node_announcement %s too old?",
|
||||||
tal_hex(tmpctx, pna->node_announcement));
|
tal_hex(tmpctx, pna->node_announcement));
|
||||||
/* Never send this again. */
|
/* 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,
|
bool routing_add_node_announcement(struct routing_state *rstate,
|
||||||
const u8 *msg TAKES,
|
const u8 *msg TAKES,
|
||||||
u32 index,
|
u32 index,
|
||||||
struct peer *peer)
|
struct peer *peer,
|
||||||
|
bool *was_unknown)
|
||||||
{
|
{
|
||||||
struct node *node;
|
struct node *node;
|
||||||
secp256k1_ecdsa_signature signature;
|
secp256k1_ecdsa_signature signature;
|
||||||
@@ -2400,6 +2401,9 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
|||||||
u8 alias[32];
|
u8 alias[32];
|
||||||
u8 *features, *addresses;
|
u8 *features, *addresses;
|
||||||
|
|
||||||
|
if (was_unknown)
|
||||||
|
*was_unknown = false;
|
||||||
|
|
||||||
/* Make sure we own msg, even if we don't save it. */
|
/* Make sure we own msg, even if we don't save it. */
|
||||||
if (taken(msg))
|
if (taken(msg))
|
||||||
tal_steal(tmpctx, 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,
|
pna = pending_node_map_get(rstate->pending_node_map,
|
||||||
&node_id);
|
&node_id);
|
||||||
if (!pna) {
|
if (!pna) {
|
||||||
|
if (was_unknown)
|
||||||
|
*was_unknown = true;
|
||||||
bad_gossip_order(msg, peer,
|
bad_gossip_order(msg, peer,
|
||||||
type_to_string(tmpctx, struct node_id,
|
type_to_string(tmpctx, struct node_id,
|
||||||
&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,
|
u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann,
|
||||||
struct peer *peer)
|
struct peer *peer, bool *was_unknown)
|
||||||
{
|
{
|
||||||
u8 *serialized;
|
u8 *serialized;
|
||||||
struct sha256_double hash;
|
struct sha256_double hash;
|
||||||
@@ -2538,6 +2544,9 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann,
|
|||||||
struct wireaddr *wireaddrs;
|
struct wireaddr *wireaddrs;
|
||||||
size_t len = tal_count(node_ann);
|
size_t len = tal_count(node_ann);
|
||||||
|
|
||||||
|
if (was_unknown)
|
||||||
|
*was_unknown = false;
|
||||||
|
|
||||||
serialized = tal_dup_arr(tmpctx, u8, node_ann, len, 0);
|
serialized = tal_dup_arr(tmpctx, u8, node_ann, len, 0);
|
||||||
if (!fromwire_node_announcement(tmpctx, serialized,
|
if (!fromwire_node_announcement(tmpctx, serialized,
|
||||||
&signature, &features, ×tamp,
|
&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. */
|
/* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -392,9 +392,11 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
|
|||||||
struct peer *peer,
|
struct peer *peer,
|
||||||
struct short_channel_id *unknown_scid);
|
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,
|
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() */
|
/* Get a node: use this instead of node_map_get() */
|
||||||
struct node *get_node(struct routing_state *rstate,
|
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,
|
bool routing_add_node_announcement(struct routing_state *rstate,
|
||||||
const u8 *msg TAKES,
|
const u8 *msg TAKES,
|
||||||
u32 index,
|
u32 index,
|
||||||
struct peer *peer);
|
struct peer *peer,
|
||||||
|
bool *was_unknown);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -96,6 +96,10 @@ struct seeker {
|
|||||||
u8 *nannounce_query_flags;
|
u8 *nannounce_query_flags;
|
||||||
size_t nannounce_offset;
|
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 */
|
/* Peers we've asked to stream us gossip */
|
||||||
struct peer *gossiper_softref[3];
|
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++)
|
for (size_t i = 0; i < ARRAY_SIZE(seeker->gossiper_softref); i++)
|
||||||
seeker->gossiper_softref[i] = NULL;
|
seeker->gossiper_softref[i] = NULL;
|
||||||
seeker->preferred_peer_softref = NULL;
|
seeker->preferred_peer_softref = NULL;
|
||||||
|
seeker->unknown_nodes = false;
|
||||||
set_state(seeker, STARTING_UP);
|
set_state(seeker, STARTING_UP);
|
||||||
begin_check_timer(seeker);
|
begin_check_timer(seeker);
|
||||||
memleak_add_helper(seeker, memleak_help_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;
|
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);
|
clear_softref(seeker, &seeker->random_peer_softref);
|
||||||
return peer;
|
return peer;
|
||||||
}
|
}
|
||||||
@@ -409,6 +419,7 @@ static bool seek_any_stale_scids(struct seeker *seeker)
|
|||||||
return true;
|
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
|
/* Returns true and sets first_blocknum and number_of_blocks if
|
||||||
* there's more to find. */
|
* there's more to find. */
|
||||||
static bool next_block_range(struct seeker *seeker,
|
static bool next_block_range(struct seeker *seeker,
|
||||||
@@ -846,6 +857,16 @@ set_gossiper:
|
|||||||
enable_gossip_stream(seeker, peer);
|
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. */
|
/* Periodic timer to see how our gossip is going. */
|
||||||
static void seeker_check(struct seeker *seeker)
|
static void seeker_check(struct seeker *seeker)
|
||||||
{
|
{
|
||||||
@@ -867,8 +888,9 @@ static void seeker_check(struct seeker *seeker)
|
|||||||
break;
|
break;
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
maybe_rotate_gossipers(seeker);
|
maybe_rotate_gossipers(seeker);
|
||||||
if (!seek_any_unknown_scids(seeker))
|
if (!seek_any_unknown_scids(seeker)
|
||||||
seek_any_stale_scids(seeker);
|
&& !seek_any_stale_scids(seeker))
|
||||||
|
seek_any_unknown_nodes(seeker);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,3 +975,10 @@ void query_unknown_channel(struct daemon *daemon,
|
|||||||
if (!add_unknown_scid(daemon->seeker, id, peer))
|
if (!add_unknown_scid(daemon->seeker, id, peer))
|
||||||
return;
|
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,
|
struct peer *peer,
|
||||||
const struct short_channel_id *id);
|
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);
|
void seeker_setup_peer_gossip(struct seeker *seeker, struct peer *peer);
|
||||||
|
|
||||||
bool remove_unknown_scid(struct seeker *seeker,
|
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(); }
|
{ fprintf(stderr, "handle_channel_update called!\n"); abort(); }
|
||||||
/* Generated stub for handle_node_announcement */
|
/* Generated stub for handle_node_announcement */
|
||||||
u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED,
|
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(); }
|
{ fprintf(stderr, "handle_node_announcement called!\n"); abort(); }
|
||||||
/* Generated stub for master_badmsg */
|
/* Generated stub for master_badmsg */
|
||||||
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
|
||||||
|
|||||||
Reference in New Issue
Block a user