Browse Source

gossipd: use timestamp information to detect stale scids.

Build up a map of short_channel_ids which we have old info for (only
if peer supports gossip_query_ex).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
committed by neil saitug
parent
commit
af3bc4d11f
  1. 74
      gossipd/seeker.c

74
gossipd/seeker.c

@ -53,6 +53,25 @@ static const struct short_channel_id *scid_pass(const struct short_channel_id *s
HTABLE_DEFINE_TYPE(struct short_channel_id,
scid_pass, hash_scid, short_channel_id_eq, scid_map);
/* A channel we have old timestamp(s) for */
struct stale_scid {
struct short_channel_id scid;
u8 query_flag;
};
static const struct short_channel_id *stale_scid_key(const struct stale_scid *s)
{
return &s->scid;
}
static bool stale_scid_eq_key(const struct stale_scid *s,
const struct short_channel_id *scid)
{
return short_channel_id_eq(&s->scid, scid);
}
HTABLE_DEFINE_TYPE(struct stale_scid,
stale_scid_key, hash_scid, stale_scid_eq_key, stale_scid_map);
/* Gossip we're seeking at the moment. */
struct seeker {
struct daemon *daemon;
@ -65,6 +84,9 @@ struct seeker {
/* Channels we've heard about, but don't know. */
struct scid_map unknown_scids;
/* Channels we've heard about newer timestamps for. */
struct stale_scid_map stale_scids;
/* Range of scid blocks we've probed. */
size_t scid_probe_start, scid_probe_end;
@ -106,6 +128,7 @@ static void memleak_help_seeker(struct htable *memtable,
struct seeker *seeker)
{
memleak_remove_htable(memtable, &seeker->unknown_scids.raw);
memleak_remove_htable(memtable, &seeker->stale_scids.raw);
}
#endif /* DEVELOPER */
@ -125,6 +148,7 @@ struct seeker *new_seeker(struct daemon *daemon, u32 timestamp)
seeker->daemon = daemon;
scid_map_init(&seeker->unknown_scids);
stale_scid_map_init(&seeker->stale_scids);
seeker->last_gossip_timestamp = timestamp;
set_state(seeker, STARTING_UP_NEED_PEER);
begin_check_timer(seeker);
@ -469,6 +493,51 @@ static void peer_gossip_probe_nannounces(struct seeker *seeker)
tal_count(seeker->nannounce_scids));
}
/* They have update with this timestamp: do we want it? */
static bool want_update(u32 timestamp, const struct half_chan *hc)
{
if (!is_halfchan_defined(hc))
return timestamp != 0;
return timestamp > hc->bcast.timestamp;
}
/* They gave us timestamps. Do we need updated versions? */
static void check_timestamps(struct seeker *seeker,
struct chan *c,
const struct channel_update_timestamps *ts)
{
struct stale_scid *stale;
u8 query_flag = 0;
/* BOLT #7:
* * `timestamp_node_id_1` is the timestamp of the `channel_update`
* for `node_id_1`, or 0 if there was no `channel_update` from that
* node.
* * `timestamp_node_id_2` is the timestamp of the `channel_update`
* for `node_id_2`, or 0 if there was no `channel_update` from that
* node.
*/
if (want_update(ts->timestamp_node_id_1, &c->half[0]))
query_flag |= SCID_QF_UPDATE1;
if (want_update(ts->timestamp_node_id_2, &c->half[1]))
query_flag |= SCID_QF_UPDATE2;
if (!query_flag)
return;
/* Add in flags if we're already getting it. */
stale = stale_scid_map_get(&seeker->stale_scids, &c->scid);
if (stale)
stale->query_flag |= query_flag;
else {
stale = tal(seeker, struct stale_scid);
stale->scid = c->scid;
stale->query_flag = query_flag;
stale_scid_map_add(&seeker->stale_scids, stale);
}
}
static void process_scid_probe(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids,
@ -486,8 +555,11 @@ static void process_scid_probe(struct peer *peer,
for (size_t i = 0; i < tal_count(scids); i++) {
struct chan *c = get_channel(seeker->daemon->rstate, &scids[i]);
if (c)
if (c) {
if (ts)
check_timestamps(seeker, c, ts+i);
continue;
}
new_unknown_scids |= add_unknown_scid(seeker, &scids[i]);
}

Loading…
Cancel
Save