gossipd: make extra-sure we don't put in redundant channel_announcement messages.
We only write these in two places: one where we get a message from lightningd about our own channel, and one where we get a reply from lightningd about a txout check. The former case we explicitly check that we don't already have it in gossmap, so add checks to the latter case, and give verbose detail if it's found. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Vincenzo Palazzo
parent
369c0c1391
commit
744116e501
@@ -1444,3 +1444,9 @@ u8 *gossmap_node_get_features(const tal_t *ctx,
|
||||
map_copy(map, n->nann_off + feature_len_off + 2, ret, feature_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t gossmap_lengths(const struct gossmap *map, size_t *total)
|
||||
{
|
||||
*total = map->map_size;
|
||||
return map->map_end;
|
||||
}
|
||||
|
||||
@@ -257,4 +257,7 @@ size_t gossmap_num_chans(const struct gossmap *map);
|
||||
struct gossmap_chan *gossmap_first_chan(const struct gossmap *map);
|
||||
struct gossmap_chan *gossmap_next_chan(const struct gossmap *map,
|
||||
struct gossmap_chan *prev);
|
||||
|
||||
/* For debugging: returns length read, and total known length of file */
|
||||
size_t gossmap_lengths(const struct gossmap *map, size_t *total);
|
||||
#endif /* LIGHTNING_COMMON_GOSSMAP_H */
|
||||
|
||||
@@ -600,3 +600,8 @@ void gossip_store_set_timestamp(struct gossip_store *gs, u64 offset, u32 timesta
|
||||
"Failed writing header to re-timestamp @%"PRIu64": %s",
|
||||
offset, strerror(errno));
|
||||
}
|
||||
|
||||
u64 gossip_store_len_written(const struct gossip_store *gs)
|
||||
{
|
||||
return gs->len;
|
||||
}
|
||||
|
||||
@@ -113,4 +113,8 @@ u32 gossip_store_get_timestamp(struct gossip_store *gs, u64 offset);
|
||||
*/
|
||||
void gossip_store_set_timestamp(struct gossip_store *gs, u64 offset, u32 timestamp);
|
||||
|
||||
/**
|
||||
* For debugging.
|
||||
*/
|
||||
u64 gossip_store_len_written(const struct gossip_store *gs);
|
||||
#endif /* LIGHTNING_GOSSIPD_GOSSIP_STORE_H */
|
||||
|
||||
@@ -652,6 +652,34 @@ void gossmap_manage_handle_get_txout_reply(struct gossmap_manage *gm, const u8 *
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* We have reports of doubled-up channel_announcements, hence this check! */
|
||||
struct gossmap_chan *chan;
|
||||
size_t before_length_processed, before_total_length;
|
||||
|
||||
before_length_processed = gossmap_lengths(gm->raw_gossmap, &before_total_length);
|
||||
chan = gossmap_find_chan(gm->raw_gossmap, &scid);
|
||||
if (chan) {
|
||||
status_broken("Redundant channel_announce for scid %s at off %u (gossmap %zu/%zu, store %"PRIu64")",
|
||||
fmt_short_channel_id(tmpctx, scid), chan->cann_off,
|
||||
before_length_processed, before_total_length,
|
||||
gossip_store_len_written(gm->daemon->gs));
|
||||
goto out;
|
||||
} else {
|
||||
size_t after_length_processed, after_total_length;
|
||||
/* Good, now try refreshing in case it somehow slipped in! */
|
||||
gossmap = gossmap_manage_get_gossmap(gm);
|
||||
after_length_processed = gossmap_lengths(gm->raw_gossmap, &after_total_length);
|
||||
chan = gossmap_find_chan(gm->raw_gossmap, &scid);
|
||||
if (chan) {
|
||||
status_broken("Redundant channel_announce *AFTER REFRESH* for scid %s at off %u (gossmap was %zu/%zu, now %zu/%zu, store %"PRIu64")",
|
||||
fmt_short_channel_id(tmpctx, scid), chan->cann_off,
|
||||
before_length_processed, before_total_length,
|
||||
after_length_processed, after_total_length,
|
||||
gossip_store_len_written(gm->daemon->gs));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set with timestamp 0 (we will update once we have a channel_update) */
|
||||
gossip_store_add(gm->daemon->gs, pca->channel_announcement, 0);
|
||||
gossip_store_add(gm->daemon->gs,
|
||||
@@ -672,8 +700,9 @@ void gossmap_manage_handle_get_txout_reply(struct gossmap_manage *gm, const u8 *
|
||||
return;
|
||||
|
||||
bad:
|
||||
tal_free(pca);
|
||||
txout_failures_add(gm->txf, scid);
|
||||
out:
|
||||
tal_free(pca);
|
||||
/* If we looking specifically for this, we no longer are. */
|
||||
remove_unknown_scid(gm->daemon->seeker, &scid, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user