gossmap: add callback for gossipd to see dying messages.
gossmap doesn't care, so gossipd currently has to iterate through the store to find them at startup. Create a callback for gossipd to use instead. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -641,8 +641,47 @@ static void node_announcement(struct gossmap *map, u64 nann_off)
|
||||
n->nann_off = nann_off;
|
||||
}
|
||||
|
||||
static bool report_dying_cb(struct gossmap *map,
|
||||
u64 dying_off,
|
||||
u16 msglen,
|
||||
void (*dyingcb)(struct short_channel_id scid,
|
||||
u32 blockheight,
|
||||
u64 offset,
|
||||
void *cb_arg),
|
||||
void *cb_arg)
|
||||
{
|
||||
struct short_channel_id scid;
|
||||
u32 blockheight;
|
||||
u8 *msg;
|
||||
|
||||
msg = tal_arr(NULL, u8, msglen);
|
||||
map_copy(map, dying_off, msg, msglen);
|
||||
|
||||
if (!fromwire_gossip_store_chan_dying(msg, &scid, &blockheight)) {
|
||||
map->logcb(map->cbarg,
|
||||
LOG_BROKEN,
|
||||
"Invalid chan_dying message @%"PRIu64
|
||||
"/%"PRIu64": %s",
|
||||
dying_off, map->map_size, msglen,
|
||||
tal_hex(tmpctx, msg));
|
||||
tal_free(msg);
|
||||
return false;
|
||||
}
|
||||
tal_free(msg);
|
||||
|
||||
dyingcb(scid, blockheight, dying_off, cb_arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Mutual recursion */
|
||||
static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed);
|
||||
static bool map_catchup(struct gossmap *map,
|
||||
void (*dyingcb)(struct short_channel_id scid,
|
||||
u32 blockheight,
|
||||
u64 offset,
|
||||
void *cb_arg),
|
||||
void *cb_arg,
|
||||
bool must_be_clean,
|
||||
bool *changed);
|
||||
|
||||
static void init_map_structs(struct gossmap *map)
|
||||
{
|
||||
@@ -724,7 +763,7 @@ static bool reopen_store(struct gossmap *map, u64 ended_off)
|
||||
map->generation++;
|
||||
|
||||
/* Now do reload. */
|
||||
map_catchup(map, false, &changed);
|
||||
map_catchup(map, NULL, NULL, false, &changed);
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -744,7 +783,14 @@ static bool csum_matches(const struct gossmap *map,
|
||||
}
|
||||
|
||||
/* Returns false only if must_be_clean is true. */
|
||||
static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
|
||||
static bool map_catchup(struct gossmap *map,
|
||||
void (*dyingcb)(struct short_channel_id scid,
|
||||
u32 blockheight,
|
||||
u64 offset,
|
||||
void *cb_arg),
|
||||
void *cb_arg,
|
||||
bool must_be_clean,
|
||||
bool *changed)
|
||||
{
|
||||
size_t reclen, num_bad_cupdates = 0;
|
||||
|
||||
@@ -830,6 +876,8 @@ static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
|
||||
/* We absorbed this in add_channel; ignore */
|
||||
continue;
|
||||
} else if (type == WIRE_GOSSIP_STORE_CHAN_DYING) {
|
||||
if (dyingcb && !report_dying_cb(map, off, msglen, dyingcb, cb_arg))
|
||||
return false;
|
||||
/* We don't really care until it's deleted */
|
||||
continue;
|
||||
} else if (type == WIRE_GOSSIP_STORE_UUID) {
|
||||
@@ -856,7 +904,13 @@ static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool load_gossip_store(struct gossmap *map, bool must_be_clean)
|
||||
static bool load_gossip_store(struct gossmap *map,
|
||||
void (*dyingcb)(struct short_channel_id scid,
|
||||
u32 blockheight,
|
||||
u64 offset,
|
||||
void *cb_arg),
|
||||
void *cb_arg,
|
||||
bool must_be_clean)
|
||||
{
|
||||
bool updated;
|
||||
|
||||
@@ -880,7 +934,7 @@ static bool load_gossip_store(struct gossmap *map, bool must_be_clean)
|
||||
init_map_structs(map);
|
||||
|
||||
map->map_end = 1;
|
||||
return map_catchup(map, must_be_clean, &updated);
|
||||
return map_catchup(map, dyingcb, cb_arg, must_be_clean, &updated);
|
||||
}
|
||||
|
||||
static void destroy_map(struct gossmap *map)
|
||||
@@ -1292,7 +1346,7 @@ bool gossmap_refresh(struct gossmap *map)
|
||||
}
|
||||
}
|
||||
|
||||
map_catchup(map, false, &changed);
|
||||
map_catchup(map, NULL, NULL, false, &changed);
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -1319,7 +1373,11 @@ struct gossmap *gossmap_load_(const tal_t *ctx,
|
||||
enum log_level level,
|
||||
const char *fmt,
|
||||
...),
|
||||
void *cbarg)
|
||||
void (*dyingcb)(struct short_channel_id scid,
|
||||
u32 blockheight,
|
||||
u64 offset,
|
||||
void *cb_arg),
|
||||
void *cb_arg)
|
||||
{
|
||||
map = tal(ctx, struct gossmap);
|
||||
map->generation = 0;
|
||||
@@ -1331,15 +1389,15 @@ struct gossmap *gossmap_load_(const tal_t *ctx,
|
||||
map->logcb = logcb;
|
||||
else
|
||||
map->logcb = log_stderr;
|
||||
map->cbarg = cbarg;
|
||||
map->cbarg = cb_arg;
|
||||
tal_add_destructor(map, destroy_map);
|
||||
|
||||
if (!load_gossip_store(map, expected_len != 0))
|
||||
if (!load_gossip_store(map, dyingcb, cb_arg, expected_len != 0))
|
||||
return tal_free(map);
|
||||
if (expected_len != 0
|
||||
&& (map->map_size != map->map_end
|
||||
|| map->map_size != expected_len)) {
|
||||
logcb(cbarg, LOG_BROKEN,
|
||||
logcb(cb_arg, LOG_BROKEN,
|
||||
"gossip_store only processed %"PRIu64
|
||||
" bytes of %"PRIu64" (expected %"PRIu64")",
|
||||
map->map_end, map->map_size, expected_len);
|
||||
|
||||
@@ -46,17 +46,21 @@ struct gossmap_chan {
|
||||
enum log_level, \
|
||||
const char *fmt, \
|
||||
...), \
|
||||
(cbarg))
|
||||
NULL, (cbarg))
|
||||
|
||||
/* If we're the author of the gossmap, it should have no redundant records, corruption, etc.
|
||||
* So this fails if that's not the case. */
|
||||
#define gossmap_load_initial(ctx, filename, expected_len, logcb, cbarg) \
|
||||
#define gossmap_load_initial(ctx, filename, expected_len, logcb, dyingcb, cb_arg) \
|
||||
gossmap_load_((ctx), (filename), (expected_len), \
|
||||
typesafe_cb_postargs(void, void *, (logcb), (cbarg), \
|
||||
typesafe_cb_postargs(void, void *, (logcb), (cb_arg), \
|
||||
enum log_level, \
|
||||
const char *fmt, \
|
||||
...), \
|
||||
(cbarg))
|
||||
typesafe_cb_preargs(void, void *, (dyingcb), (cb_arg), \
|
||||
struct short_channel_id, \
|
||||
u32, \
|
||||
u64), \
|
||||
(cb_arg))
|
||||
|
||||
struct gossmap *gossmap_load_(const tal_t *ctx,
|
||||
const char *filename,
|
||||
@@ -65,6 +69,10 @@ struct gossmap *gossmap_load_(const tal_t *ctx,
|
||||
enum log_level level,
|
||||
const char *fmt,
|
||||
...),
|
||||
void (*dyingcb)(struct short_channel_id scid,
|
||||
u32 blockheight,
|
||||
u64 offset,
|
||||
void *cb_arg),
|
||||
void *cb_arg);
|
||||
|
||||
/* Disable mmap. Noop if already disabled. */
|
||||
@@ -305,4 +313,5 @@ u64 gossmap_lengths(const struct gossmap *map, u64 *total);
|
||||
|
||||
/* Debugging: connectd wants to enumerate fds */
|
||||
int gossmap_fd(const struct gossmap *map);
|
||||
|
||||
#endif /* LIGHTNING_COMMON_GOSSMAP_H */
|
||||
|
||||
@@ -19,6 +19,9 @@ bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
struct channel_id *channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_chan_dying */
|
||||
bool fromwire_gossip_store_chan_dying(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED, u32 *blockheight UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_chan_dying called!\n"); abort(); }
|
||||
/* Generated stub for sciddir_or_pubkey_from_node_id */
|
||||
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
|
||||
const struct node_id *node_id UNNEEDED)
|
||||
|
||||
@@ -19,6 +19,9 @@ bigsize_t fromwire_bigsize(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||
bool fromwire_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
struct channel_id *channel_id UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_channel_id called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_chan_dying */
|
||||
bool fromwire_gossip_store_chan_dying(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED, u32 *blockheight UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_chan_dying called!\n"); abort(); }
|
||||
/* Generated stub for sciddir_or_pubkey_from_node_id */
|
||||
bool sciddir_or_pubkey_from_node_id(struct sciddir_or_pubkey *sciddpk UNNEEDED,
|
||||
const struct node_id *node_id UNNEEDED)
|
||||
|
||||
@@ -10,12 +10,16 @@ int unused_main(int argc, char *argv[]);
|
||||
#include <common/memleak.h>
|
||||
#include <common/onionreply.h>
|
||||
#include <common/setup.h>
|
||||
#include <common/gossip_store_wiregen.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* AUTOGENERATED MOCKS START */
|
||||
/* Generated stub for fromwire_connectd_dev_set_max_scids_encode_size */
|
||||
bool fromwire_connectd_dev_set_max_scids_encode_size(const void *p UNNEEDED, u32 *max UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_connectd_dev_set_max_scids_encode_size called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_chan_dying */
|
||||
bool fromwire_gossip_store_chan_dying(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED, u32 *blockheight UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_chan_dying called!\n"); abort(); }
|
||||
/* Generated stub for get_gossmap */
|
||||
struct gossmap *get_gossmap(struct daemon *daemon UNNEEDED)
|
||||
{ fprintf(stderr, "get_gossmap called!\n"); abort(); }
|
||||
|
||||
@@ -464,7 +464,9 @@ static bool setup_gossmap(struct gossmap_manage *gm,
|
||||
/* This actually loads it into memory, with strict checks. */
|
||||
gm->raw_gossmap = gossmap_load_initial(gm, GOSSIP_STORE_FILENAME,
|
||||
expected_len,
|
||||
gossmap_logcb, daemon);
|
||||
gossmap_logcb,
|
||||
NULL,
|
||||
daemon);
|
||||
if (!gm->raw_gossmap) {
|
||||
gm->gs = tal_free(gm->gs);
|
||||
return false;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <common/sciddir_or_pubkey.h>
|
||||
#include <common/setup.h>
|
||||
#include <common/wireaddr.h>
|
||||
#include <common/gossip_store_wiregen.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* AUTOGENERATED MOCKS START */
|
||||
@@ -19,6 +20,9 @@ struct peer *find_peer(struct daemon *daemon UNNEEDED, const struct node_id *id
|
||||
struct peer *first_random_peer(struct daemon *daemon UNNEEDED,
|
||||
struct peer_node_id_map_iter *it UNNEEDED)
|
||||
{ fprintf(stderr, "first_random_peer called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_gossip_store_chan_dying */
|
||||
bool fromwire_gossip_store_chan_dying(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED, u32 *blockheight UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_gossip_store_chan_dying called!\n"); abort(); }
|
||||
/* 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(); }
|
||||
|
||||
Reference in New Issue
Block a user