mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-05 14:14:23 +01:00
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>
This commit is contained in:
committed by
neil saitug
parent
1f2a03f019
commit
af3bc4d11f
@@ -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]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user