mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 22:45:27 +01:00
gossipd: put gossip_store pointer inside gossmap_manage.
It's actually the only one that uses it. We also tweak the way gossip_store handles failure: gossmap_manage now tells it when to reset the corrupted store. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
e440799b5e
commit
4f2a7039c6
9 changed files with 115 additions and 74 deletions
|
@ -191,7 +191,7 @@ static bool upgrade_field(u8 oldversion,
|
|||
* validity, but this code is written as simply and robustly as
|
||||
* possible!
|
||||
*
|
||||
* Returns fd of new store.
|
||||
* Returns fd of new store, or -1 if it was grossly invalid.
|
||||
*/
|
||||
static int gossip_store_compact(struct daemon *daemon,
|
||||
u64 *total_len,
|
||||
|
@ -398,19 +398,18 @@ rename_new:
|
|||
return new_fd;
|
||||
|
||||
badmsg:
|
||||
/* We truncate */
|
||||
status_broken("gossip_store: %s (offset %"PRIu64"). Moving to %s.corrupt and truncating",
|
||||
bad, cur_off, GOSSIP_STORE_FILENAME);
|
||||
/* Caller will presumably try gossip_store_reset. */
|
||||
status_broken("gossip_store: %s (offset %"PRIu64").", bad, cur_off);
|
||||
close(old_fd);
|
||||
close(new_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gossip_store_corrupt(void)
|
||||
{
|
||||
status_broken("gossip_store: Moving to %s.corrupt",
|
||||
GOSSIP_STORE_FILENAME);
|
||||
rename(GOSSIP_STORE_FILENAME, GOSSIP_STORE_FILENAME ".corrupt");
|
||||
if (lseek(new_fd, 0, SEEK_SET) != 0
|
||||
|| !write_all(new_fd, &version, sizeof(version))) {
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Overwriting new gossip_store file: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
*total_len = sizeof(version);
|
||||
goto rename_new;
|
||||
}
|
||||
|
||||
struct gossip_store *gossip_store_new(const tal_t *ctx,
|
||||
|
@ -423,6 +422,8 @@ struct gossip_store *gossip_store_new(const tal_t *ctx,
|
|||
gs->daemon = daemon;
|
||||
*dying = tal_arr(ctx, struct chan_dying, 0);
|
||||
gs->fd = gossip_store_compact(daemon, &gs->len, populated, dying);
|
||||
if (gs->fd < 0)
|
||||
return tal_free(gs);
|
||||
tal_add_destructor(gs, gossip_store_destroy);
|
||||
return gs;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ struct chan_dying {
|
|||
* @daemon: the daemon context
|
||||
* @populated: set to false if store is empty/obviously partial.
|
||||
* @dying: an array of channels we found dying markers for.
|
||||
*
|
||||
* Returns NULL on error.
|
||||
*/
|
||||
struct gossip_store *gossip_store_new(const tal_t *ctx,
|
||||
struct daemon *daemon,
|
||||
|
@ -38,10 +40,9 @@ struct gossip_store *gossip_store_new(const tal_t *ctx,
|
|||
struct chan_dying **dying);
|
||||
|
||||
/**
|
||||
* Get the (refreshed!) gossmap from the gossip_store.
|
||||
* @gs: gossip store
|
||||
* Move the old gossip store out the way. Log a broken message about it.
|
||||
*/
|
||||
struct gossmap *gossip_store_gossmap(struct gossip_store *gs);
|
||||
void gossip_store_corrupt(void);
|
||||
|
||||
/**
|
||||
* Append a gossip message to the gossip_store
|
||||
|
@ -109,4 +110,5 @@ void gossip_store_set_timestamp(struct gossip_store *gs, u64 offset, u32 timesta
|
|||
* For debugging.
|
||||
*/
|
||||
u64 gossip_store_len_written(const struct gossip_store *gs);
|
||||
|
||||
#endif /* LIGHTNING_GOSSIPD_GOSSIP_STORE_H */
|
||||
|
|
|
@ -282,12 +282,8 @@ handled_msg_errmsg:
|
|||
err = NULL;
|
||||
|
||||
handled_msg:
|
||||
if (err) {
|
||||
if (err)
|
||||
queue_peer_msg(daemon, &source, take(err));
|
||||
} else {
|
||||
/* Some peer gave us gossip, so we're not at zero. */
|
||||
peer->daemon->gossip_store_populated = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*~ connectd's input handler is very simple. */
|
||||
|
@ -401,7 +397,6 @@ bool timestamp_reasonable(const struct daemon *daemon, u32 timestamp)
|
|||
static void gossip_init(struct daemon *daemon, const u8 *msg)
|
||||
{
|
||||
u32 *dev_gossip_time;
|
||||
struct chan_dying *dying;
|
||||
|
||||
if (!fromwire_gossipd_init(daemon, msg,
|
||||
&chainparams,
|
||||
|
@ -422,13 +417,8 @@ static void gossip_init(struct daemon *daemon, const u8 *msg)
|
|||
tal_free(dev_gossip_time);
|
||||
}
|
||||
|
||||
daemon->gs = gossip_store_new(daemon,
|
||||
daemon,
|
||||
&daemon->gossip_store_populated,
|
||||
&dying);
|
||||
|
||||
/* Gossmap manager starts up */
|
||||
daemon->gm = gossmap_manage_new(daemon, daemon, take(dying));
|
||||
daemon->gm = gossmap_manage_new(daemon, daemon);
|
||||
|
||||
/* Fire up the seeker! */
|
||||
daemon->seeker = new_seeker(daemon);
|
||||
|
|
|
@ -65,12 +65,6 @@ struct daemon {
|
|||
/* Features lightningd told us to set. */
|
||||
struct feature_set *our_features;
|
||||
|
||||
/* Gossip store */
|
||||
struct gossip_store *gs;
|
||||
|
||||
/* Was there anything in the gossip store at startup? */
|
||||
bool gossip_store_populated;
|
||||
|
||||
/* Override local time for gossip messages */
|
||||
struct timeabs *dev_gossip_time;
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ struct gossmap_manage {
|
|||
/* gossip map itself (access via gossmap_manage_get_gossmap, so it's fresh!) */
|
||||
struct gossmap *raw_gossmap;
|
||||
|
||||
/* The gossip_store, which writes to the gossip_store file */
|
||||
struct gossip_store *gs;
|
||||
|
||||
/* Announcements we're checking, indexed by scid */
|
||||
struct cannounce_map pending_ann_map;
|
||||
|
||||
|
@ -87,6 +90,9 @@ struct gossmap_manage {
|
|||
|
||||
/* Occasional check for dead channels */
|
||||
struct oneshot *prune_timer;
|
||||
|
||||
/* Are we populated yet? */
|
||||
bool gossip_store_populated;
|
||||
};
|
||||
|
||||
/* Timer recursion */
|
||||
|
@ -257,15 +263,15 @@ static void remove_channel(struct gossmap_manage *gm,
|
|||
tal_free(map_del(&gm->early_ann_map, scid));
|
||||
|
||||
/* Put in tombstone marker. */
|
||||
gossip_store_add(gm->daemon->gs,
|
||||
gossip_store_add(gm->gs,
|
||||
towire_gossip_store_delete_chan(tmpctx, scid),
|
||||
0);
|
||||
|
||||
/* Delete from store */
|
||||
gossip_store_del(gm->daemon->gs, chan->cann_off, WIRE_CHANNEL_ANNOUNCEMENT);
|
||||
gossip_store_del(gm->gs, chan->cann_off, WIRE_CHANNEL_ANNOUNCEMENT);
|
||||
for (int dir = 0; dir < 2; dir++) {
|
||||
if (gossmap_chan_set(chan, dir))
|
||||
gossip_store_del(gm->daemon->gs, chan->cupdate_off[dir], WIRE_CHANNEL_UPDATE);
|
||||
gossip_store_del(gm->gs, chan->cupdate_off[dir], WIRE_CHANNEL_UPDATE);
|
||||
}
|
||||
|
||||
/* Check for node_announcements which should no longer be there */
|
||||
|
@ -285,7 +291,7 @@ static void remove_channel(struct gossmap_manage *gm,
|
|||
|
||||
/* Last channel? Delete node announce */
|
||||
if (node->num_chans == 1) {
|
||||
gossip_store_del(gm->daemon->gs, node->nann_off, WIRE_NODE_ANNOUNCEMENT);
|
||||
gossip_store_del(gm->gs, node->nann_off, WIRE_NODE_ANNOUNCEMENT);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -297,10 +303,10 @@ static void remove_channel(struct gossmap_manage *gm,
|
|||
|
||||
/* To maintain order, delete and re-add node_announcement */
|
||||
nannounce = gossmap_node_get_announce(tmpctx, gossmap, node);
|
||||
timestamp = gossip_store_get_timestamp(gm->daemon->gs, node->nann_off);
|
||||
timestamp = gossip_store_get_timestamp(gm->gs, node->nann_off);
|
||||
|
||||
gossip_store_del(gm->daemon->gs, node->nann_off, WIRE_NODE_ANNOUNCEMENT);
|
||||
offset = gossip_store_add(gm->daemon->gs, nannounce, timestamp);
|
||||
gossip_store_del(gm->gs, node->nann_off, WIRE_NODE_ANNOUNCEMENT);
|
||||
offset = gossip_store_add(gm->gs, nannounce, timestamp);
|
||||
} else {
|
||||
/* Are all remaining channels dying but we weren't?
|
||||
* Can happen if we removed this channel immediately
|
||||
|
@ -314,7 +320,7 @@ static void remove_channel(struct gossmap_manage *gm,
|
|||
/* Be sure to set DYING flag when we move (ignore current
|
||||
* channel, we haven't reloaded gossmap yet!) */
|
||||
if (all_node_channels_dying(gossmap, node, chan))
|
||||
gossip_store_set_flag(gm->daemon->gs, offset,
|
||||
gossip_store_set_flag(gm->gs, offset,
|
||||
GOSSIP_STORE_DYING_BIT,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
}
|
||||
|
@ -419,14 +425,43 @@ static void gossmap_logcb(struct daemon *daemon,
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
static bool setup_gossmap(struct gossmap_manage *gm,
|
||||
struct daemon *daemon,
|
||||
struct chan_dying **dying)
|
||||
{
|
||||
*dying = NULL;
|
||||
|
||||
/* This compacts, and creates if necessary */
|
||||
gm->gs = gossip_store_new(gm,
|
||||
daemon,
|
||||
&gm->gossip_store_populated,
|
||||
dying);
|
||||
if (!gm->gs)
|
||||
return false;
|
||||
|
||||
/* This actually loads it into memory */
|
||||
gm->raw_gossmap = gossmap_load(gm, GOSSIP_STORE_FILENAME,
|
||||
gossmap_logcb, daemon);
|
||||
if (!gm->raw_gossmap) {
|
||||
gm->gs = tal_free(gm->gs);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct gossmap_manage *gossmap_manage_new(const tal_t *ctx,
|
||||
struct daemon *daemon,
|
||||
struct chan_dying *dying_channels TAKES)
|
||||
struct daemon *daemon)
|
||||
{
|
||||
struct gossmap_manage *gm = tal(ctx, struct gossmap_manage);
|
||||
|
||||
gm->raw_gossmap = gossmap_load(gm, GOSSIP_STORE_FILENAME,
|
||||
gossmap_logcb, daemon);
|
||||
if (!setup_gossmap(gm, daemon, &gm->dying_channels)) {
|
||||
tal_free(gm->dying_channels);
|
||||
gossip_store_corrupt();
|
||||
if (!setup_gossmap(gm, daemon, &gm->dying_channels))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Could not re-initialize %s", GOSSIP_STORE_FILENAME);
|
||||
}
|
||||
assert(gm->gs);
|
||||
assert(gm->raw_gossmap);
|
||||
gm->daemon = daemon;
|
||||
|
||||
|
@ -436,7 +471,6 @@ struct gossmap_manage *gossmap_manage_new(const tal_t *ctx,
|
|||
gm->early_cupdates = tal_arr(gm, struct pending_cupdate *, 0);
|
||||
gm->pending_nannounces = tal_arr(gm, struct pending_nannounce *, 0);
|
||||
gm->txf = txout_failures_new(gm, daemon);
|
||||
gm->dying_channels = tal_dup_talarr(gm, struct chan_dying, dying_channels);
|
||||
|
||||
start_prune_timer(gm);
|
||||
return gm;
|
||||
|
@ -477,9 +511,9 @@ static void node_announcements_not_dying(struct gossmap_manage *gm,
|
|||
struct gossmap_node *n = gossmap_find_node(gossmap, &pca->node_id[i]);
|
||||
if (!n || !gossmap_node_announced(n))
|
||||
continue;
|
||||
if (gossip_store_get_flags(gm->daemon->gs, n->nann_off, WIRE_NODE_ANNOUNCEMENT)
|
||||
if (gossip_store_get_flags(gm->gs, n->nann_off, WIRE_NODE_ANNOUNCEMENT)
|
||||
& GOSSIP_STORE_DYING_BIT) {
|
||||
gossip_store_clear_flag(gm->daemon->gs, n->nann_off,
|
||||
gossip_store_clear_flag(gm->gs, n->nann_off,
|
||||
GOSSIP_STORE_DYING_BIT,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
}
|
||||
|
@ -555,8 +589,8 @@ const char *gossmap_manage_channel_announcement(const tal_t *ctx,
|
|||
&& !map_get(&gm->pending_ann_map, scid)
|
||||
&& !map_get(&gm->early_ann_map, scid)) {
|
||||
/* Set with timestamp 0 (we will update once we have a channel_update) */
|
||||
gossip_store_add(gm->daemon->gs, announce, 0);
|
||||
gossip_store_add(gm->daemon->gs,
|
||||
gossip_store_add(gm->gs, announce, 0);
|
||||
gossip_store_add(gm->gs,
|
||||
towire_gossip_store_channel_amount(tmpctx, *known_amount), 0);
|
||||
|
||||
node_announcements_not_dying(gm, gossmap, pca);
|
||||
|
@ -662,7 +696,7 @@ void gossmap_manage_handle_get_txout_reply(struct gossmap_manage *gm, const u8 *
|
|||
status_broken("Redundant channel_announce for scid %s at off %"PRIu64" (gossmap %"PRIu64"/%"PRIu64", store %"PRIu64")",
|
||||
fmt_short_channel_id(tmpctx, scid), chan->cann_off,
|
||||
before_length_processed, before_total_length,
|
||||
gossip_store_len_written(gm->daemon->gs));
|
||||
gossip_store_len_written(gm->gs));
|
||||
goto out;
|
||||
} else {
|
||||
u64 after_length_processed, after_total_length;
|
||||
|
@ -675,14 +709,14 @@ void gossmap_manage_handle_get_txout_reply(struct gossmap_manage *gm, const u8 *
|
|||
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));
|
||||
gossip_store_len_written(gm->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,
|
||||
gossip_store_add(gm->gs, pca->channel_announcement, 0);
|
||||
gossip_store_add(gm->gs,
|
||||
towire_gossip_store_channel_amount(tmpctx, sat), 0);
|
||||
|
||||
/* If we looking specifically for this, we no longer are. */
|
||||
|
@ -768,7 +802,7 @@ static const char *process_channel_update(const tal_t *ctx,
|
|||
/* Do we have same or earlier update? */
|
||||
if (gossmap_chan_set(chan, dir)) {
|
||||
u32 prev_timestamp
|
||||
= gossip_store_get_timestamp(gm->daemon->gs, chan->cupdate_off[dir]);
|
||||
= gossip_store_get_timestamp(gm->gs, chan->cupdate_off[dir]);
|
||||
if (prev_timestamp >= timestamp) {
|
||||
status_debug("Too-old update for %s",
|
||||
fmt_short_channel_id(tmpctx, scid));
|
||||
|
@ -779,15 +813,15 @@ static const char *process_channel_update(const tal_t *ctx,
|
|||
/* Is this the first update in either direction? If so,
|
||||
* rewrite channel_announcement so timestamp is correct. */
|
||||
if (!gossmap_chan_set(chan, !dir))
|
||||
gossip_store_set_timestamp(gm->daemon->gs, chan->cann_off, timestamp);
|
||||
gossip_store_set_timestamp(gm->gs, chan->cann_off, timestamp);
|
||||
}
|
||||
|
||||
/* OK, apply the new one */
|
||||
offset = gossip_store_add(gm->daemon->gs, update, timestamp);
|
||||
offset = gossip_store_add(gm->gs, update, timestamp);
|
||||
|
||||
/* If channel is dying, make sure update is also marked dying! */
|
||||
if (gossmap_chan_is_dying(gossmap, chan)) {
|
||||
gossip_store_set_flag(gm->daemon->gs,
|
||||
gossip_store_set_flag(gm->gs,
|
||||
offset,
|
||||
GOSSIP_STORE_DYING_BIT,
|
||||
WIRE_CHANNEL_UPDATE);
|
||||
|
@ -795,7 +829,7 @@ static const char *process_channel_update(const tal_t *ctx,
|
|||
|
||||
/* Now delete old */
|
||||
if (gossmap_chan_set(chan, dir))
|
||||
gossip_store_del(gm->daemon->gs, chan->cupdate_off[dir], WIRE_CHANNEL_UPDATE);
|
||||
gossip_store_del(gm->gs, chan->cupdate_off[dir], WIRE_CHANNEL_UPDATE);
|
||||
|
||||
/* Is this an update for an incoming channel? If so, keep lightningd updated */
|
||||
gossmap_node_get_id(gossmap,
|
||||
|
@ -818,6 +852,9 @@ static const char *process_channel_update(const tal_t *ctx,
|
|||
dir,
|
||||
channel_flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE");
|
||||
|
||||
/* We're off zero, at least! */
|
||||
gm->gossip_store_populated = true;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -936,7 +973,7 @@ static void process_node_announcement(struct gossmap_manage *gm,
|
|||
/* Do we have a later one? If so, ignore */
|
||||
if (gossmap_node_announced(node)) {
|
||||
u32 prev_timestamp
|
||||
= gossip_store_get_timestamp(gm->daemon->gs, node->nann_off);
|
||||
= gossip_store_get_timestamp(gm->gs, node->nann_off);
|
||||
if (prev_timestamp >= timestamp) {
|
||||
/* Too old, ignore */
|
||||
return;
|
||||
|
@ -944,17 +981,17 @@ static void process_node_announcement(struct gossmap_manage *gm,
|
|||
}
|
||||
|
||||
/* OK, apply the new one */
|
||||
offset = gossip_store_add(gm->daemon->gs, nannounce, timestamp);
|
||||
offset = gossip_store_add(gm->gs, nannounce, timestamp);
|
||||
/* If all channels are dying, make sure this is marked too. */
|
||||
if (all_node_channels_dying(gossmap, node, NULL)) {
|
||||
gossip_store_set_flag(gm->daemon->gs, offset,
|
||||
gossip_store_set_flag(gm->gs, offset,
|
||||
GOSSIP_STORE_DYING_BIT,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
}
|
||||
|
||||
/* Now delete old */
|
||||
if (gossmap_node_announced(node))
|
||||
gossip_store_del(gm->daemon->gs, node->nann_off, WIRE_NODE_ANNOUNCEMENT);
|
||||
gossip_store_del(gm->gs, node->nann_off, WIRE_NODE_ANNOUNCEMENT);
|
||||
|
||||
/* Used to evaluate gossip peers' performance */
|
||||
peer_supplied_good_gossip(gm->daemon, source_peer, 1);
|
||||
|
@ -1231,7 +1268,7 @@ void gossmap_manage_new_block(struct gossmap_manage *gm, u32 new_blockheight)
|
|||
* in particular, we might move a node_announcement twice! */
|
||||
gossmap = gossmap_manage_get_gossmap(gm);
|
||||
kill_spent_channel(gm, gossmap, gm->dying_channels[i].scid);
|
||||
gossip_store_del(gm->daemon->gs,
|
||||
gossip_store_del(gm->gs,
|
||||
gm->dying_channels[i].gossmap_offset,
|
||||
WIRE_GOSSIP_STORE_CHAN_DYING);
|
||||
tal_arr_remove(&gm->dying_channels, i);
|
||||
|
@ -1280,11 +1317,11 @@ void gossmap_manage_channel_spent(struct gossmap_manage *gm,
|
|||
|
||||
/* Save to gossip_store in case we restart */
|
||||
msg = towire_gossip_store_chan_dying(tmpctx, cd.scid, cd.deadline);
|
||||
cd.gossmap_offset = gossip_store_add(gm->daemon->gs, msg, 0);
|
||||
cd.gossmap_offset = gossip_store_add(gm->gs, msg, 0);
|
||||
tal_arr_expand(&gm->dying_channels, cd);
|
||||
|
||||
/* Mark it dying, so we don't gossip it */
|
||||
gossip_store_set_flag(gm->daemon->gs, chan->cann_off,
|
||||
gossip_store_set_flag(gm->gs, chan->cann_off,
|
||||
GOSSIP_STORE_DYING_BIT,
|
||||
WIRE_CHANNEL_ANNOUNCEMENT);
|
||||
/* Channel updates too! */
|
||||
|
@ -1292,7 +1329,7 @@ void gossmap_manage_channel_spent(struct gossmap_manage *gm,
|
|||
if (!gossmap_chan_set(chan, dir))
|
||||
continue;
|
||||
|
||||
gossip_store_set_flag(gm->daemon->gs,
|
||||
gossip_store_set_flag(gm->gs,
|
||||
chan->cupdate_off[dir],
|
||||
GOSSIP_STORE_DYING_BIT,
|
||||
WIRE_CHANNEL_UPDATE);
|
||||
|
@ -1312,7 +1349,7 @@ void gossmap_manage_channel_spent(struct gossmap_manage *gm,
|
|||
|
||||
/* Are all (other) channels dying? */
|
||||
if (all_node_channels_dying(gossmap, n, chan)) {
|
||||
gossip_store_set_flag(gm->daemon->gs,
|
||||
gossip_store_set_flag(gm->gs,
|
||||
n->nann_off,
|
||||
GOSSIP_STORE_DYING_BIT,
|
||||
WIRE_NODE_ANNOUNCEMENT);
|
||||
|
@ -1384,3 +1421,8 @@ void gossmap_manage_tell_lightningd_locals(struct daemon *daemon,
|
|||
take(towire_gossipd_init_nannounce(NULL,
|
||||
nannounce)));
|
||||
}
|
||||
|
||||
bool gossmap_manage_populated(const struct gossmap_manage *gm)
|
||||
{
|
||||
return gm->gossip_store_populated;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@ struct gossmap_manage;
|
|||
struct chan_dying;
|
||||
|
||||
struct gossmap_manage *gossmap_manage_new(const tal_t *ctx,
|
||||
struct daemon *daemon,
|
||||
struct chan_dying *dying_channels TAKES);
|
||||
struct daemon *daemon);
|
||||
|
||||
/**
|
||||
* gossmap_manage_channel_announcement: process an incoming channel_announcement
|
||||
|
@ -103,4 +102,13 @@ struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm);
|
|||
*/
|
||||
void gossmap_manage_tell_lightningd_locals(struct daemon *daemon,
|
||||
struct gossmap_manage *gm);
|
||||
|
||||
/**
|
||||
* gossmap_manage_populated - do we have some gossip?
|
||||
* @gm: the gossmap_manage context.
|
||||
*
|
||||
*
|
||||
* The seeker uses this if we're at startup and want complete gossip.
|
||||
*/
|
||||
bool gossmap_manage_populated(const struct gossmap_manage *gm);
|
||||
#endif /* LIGHTNING_GOSSIPD_GOSSMAP_MANAGE_H */
|
||||
|
|
|
@ -236,7 +236,7 @@ static void enable_gossip_stream(struct seeker *seeker, struct peer *peer,
|
|||
u8 *msg;
|
||||
|
||||
/* If we have no gossip, always ask for everything */
|
||||
if (!peer->daemon->gossip_store_populated)
|
||||
if (!gossmap_manage_populated(peer->daemon->gm))
|
||||
ask_for_all = true;
|
||||
|
||||
/* Modern timestamp_filter is a trinary: 0 = all, FFFFFFFF = none,
|
||||
|
|
|
@ -68,6 +68,9 @@ struct gossmap_node *gossmap_first_node(const struct gossmap *map UNNEEDED)
|
|||
/* Generated stub for gossmap_manage_get_gossmap */
|
||||
struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm UNNEEDED)
|
||||
{ fprintf(stderr, "gossmap_manage_get_gossmap called!\n"); abort(); }
|
||||
/* Generated stub for gossmap_manage_populated */
|
||||
bool gossmap_manage_populated(const struct gossmap_manage *gm UNNEEDED)
|
||||
{ fprintf(stderr, "gossmap_manage_populated called!\n"); abort(); }
|
||||
/* Generated stub for gossmap_max_node_idx */
|
||||
u32 gossmap_max_node_idx(const struct gossmap *map UNNEEDED)
|
||||
{ fprintf(stderr, "gossmap_max_node_idx called!\n"); abort(); }
|
||||
|
|
|
@ -1283,7 +1283,7 @@ def test_gossip_store_load_announce_before_update(node_factory):
|
|||
|
||||
def test_gossip_store_load_amount_truncated(node_factory):
|
||||
"""Make sure we can read canned gossip store with truncated amount"""
|
||||
l1 = node_factory.get_node(start=False, broken_log=r'gossip_store: channel_announcement without amount \(offset 1\). Moving to gossip_store.corrupt and truncating|plugin-cln-renepay:.*unable to fetch channel capacity')
|
||||
l1 = node_factory.get_node(start=False, broken_log=r'gossip_store: channel_announcement without amount \(offset 1\)|Moving to gossip_store.corrupt|plugin-cln-renepay:.*unable to fetch channel capacity')
|
||||
with open(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store'), 'wb') as f:
|
||||
f.write(bytearray.fromhex("0c" # GOSSIP_STORE_VERSION
|
||||
"000001b0" # len
|
||||
|
@ -1294,8 +1294,9 @@ def test_gossip_store_load_amount_truncated(node_factory):
|
|||
|
||||
l1.start()
|
||||
# May preceed the Started msg waited for in 'start'.
|
||||
wait_for(lambda: l1.daemon.is_in_log(r'\*\*BROKEN\*\* gossipd: gossip_store: channel_announcement without amount \(offset 1\). Moving to gossip_store.corrupt and truncating'))
|
||||
wait_for(lambda: l1.daemon.is_in_log(r'gossip_store: Read 0/0/0/0 cannounce/cupdate/nannounce/delete from store in 467 bytes, now 1 bytes \(populated=false\)'))
|
||||
wait_for(lambda: l1.daemon.is_in_log(r'\*\*BROKEN\*\* gossipd: gossip_store: channel_announcement without amount \(offset 1\)\.'))
|
||||
wait_for(lambda: l1.daemon.is_in_log(r'\*\*BROKEN\*\* gossipd: gossip_store: Moving to gossip_store.corrupt'))
|
||||
wait_for(lambda: l1.daemon.is_in_log(r'gossip_store: Read 0/0/0/0 cannounce/cupdate/nannounce/delete from store in 0 bytes, now 1 bytes \(populated=false\)'))
|
||||
assert os.path.exists(os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, 'gossip_store.corrupt'))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue