mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 20:09:18 +01:00
gossmap: don't spew to stderr, include counter for callers.
Fixes: #4722 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Fixed: Plugins: don't drop complaints about silly channels to stderr.
This commit is contained in:
parent
c970195b93
commit
cf1dd779d1
11 changed files with 70 additions and 42 deletions
|
@ -458,7 +458,7 @@ static struct gossmap_chan *add_channel(struct gossmap *map,
|
|||
* * [`u32`:`fee_proportional_millionths`]
|
||||
* * [`u64`:`htlc_maximum_msat`] (option_channel_htlc_max)
|
||||
*/
|
||||
static void update_channel(struct gossmap *map, size_t cupdate_off)
|
||||
static bool update_channel(struct gossmap *map, size_t cupdate_off)
|
||||
{
|
||||
/* Note that first two bytes are message type */
|
||||
const size_t scid_off = cupdate_off + 2 + (64 + 32);
|
||||
|
@ -473,6 +473,7 @@ static void update_channel(struct gossmap *map, size_t cupdate_off)
|
|||
struct gossmap_chan *chan;
|
||||
struct half_chan hc;
|
||||
u8 chanflags;
|
||||
bool dumb_values;
|
||||
|
||||
scid.u64 = map_be64(map, scid_off);
|
||||
chan = gossmap_find_chan(map, &scid);
|
||||
|
@ -502,19 +503,18 @@ static void update_channel(struct gossmap *map, size_t cupdate_off)
|
|||
if (hc.base_fee != map_be32(map, fee_base_off)
|
||||
|| hc.proportional_fee != map_be32(map, fee_prop_off)
|
||||
|| hc.delay != map_be16(map, cltv_expiry_delta_off)) {
|
||||
warnx("channel_update %s ignored: fee %u/%u cltv %u too large",
|
||||
type_to_string(tmpctx, struct short_channel_id, &scid),
|
||||
map_be32(map, fee_base_off),
|
||||
map_be32(map, fee_prop_off),
|
||||
map_be16(map, cltv_expiry_delta_off));
|
||||
dumb_values = true;
|
||||
hc.htlc_max = 0;
|
||||
hc.enabled = false;
|
||||
}
|
||||
} else
|
||||
dumb_values = false;
|
||||
|
||||
/* Preserve this */
|
||||
hc.nodeidx = chan->half[chanflags & 1].nodeidx;
|
||||
chan->half[chanflags & 1] = hc;
|
||||
chan->cupdate_off[chanflags & 1] = cupdate_off;
|
||||
|
||||
return !dumb_values;
|
||||
}
|
||||
|
||||
static void remove_channel_by_deletemsg(struct gossmap *map, size_t del_off)
|
||||
|
@ -580,13 +580,14 @@ static void reopen_store(struct gossmap *map, size_t ended_off)
|
|||
|
||||
close(map->fd);
|
||||
map->fd = fd;
|
||||
gossmap_refresh(map);
|
||||
gossmap_refresh(map, NULL);
|
||||
}
|
||||
|
||||
static bool map_catchup(struct gossmap *map)
|
||||
static bool map_catchup(struct gossmap *map, size_t *num_rejected)
|
||||
{
|
||||
size_t reclen;
|
||||
bool changed = false;
|
||||
size_t num_bad = 0;
|
||||
|
||||
for (; map->map_end + sizeof(struct gossip_hdr) < map->map_size;
|
||||
map->map_end += reclen) {
|
||||
|
@ -612,9 +613,9 @@ static bool map_catchup(struct gossmap *map)
|
|||
else if (type == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL)
|
||||
add_channel(map, off + 2 + 8 + 2, true);
|
||||
else if (type == WIRE_CHANNEL_UPDATE)
|
||||
update_channel(map, off);
|
||||
num_bad += !update_channel(map, off);
|
||||
else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE)
|
||||
update_channel(map, off + 2 + 2);
|
||||
num_bad += !update_channel(map, off + 2 + 2);
|
||||
else if (type == WIRE_GOSSIP_STORE_DELETE_CHAN)
|
||||
remove_channel_by_deletemsg(map, off);
|
||||
else if (type == WIRE_NODE_ANNOUNCEMENT)
|
||||
|
@ -627,10 +628,12 @@ static bool map_catchup(struct gossmap *map)
|
|||
changed = true;
|
||||
}
|
||||
|
||||
if (num_rejected)
|
||||
*num_rejected = num_bad;
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool load_gossip_store(struct gossmap *map)
|
||||
static bool load_gossip_store(struct gossmap *map, size_t *num_rejected)
|
||||
{
|
||||
map->fd = open(map->fname, O_RDONLY);
|
||||
if (map->fd < 0)
|
||||
|
@ -665,7 +668,7 @@ static bool load_gossip_store(struct gossmap *map)
|
|||
map->freed_nodes = init_node_arr(map->node_arr, 0);
|
||||
|
||||
map->map_end = 1;
|
||||
map_catchup(map);
|
||||
map_catchup(map, num_rejected);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -910,7 +913,7 @@ void gossmap_remove_localmods(struct gossmap *map,
|
|||
map->local = NULL;
|
||||
}
|
||||
|
||||
bool gossmap_refresh(struct gossmap *map)
|
||||
bool gossmap_refresh(struct gossmap *map, size_t *num_rejected)
|
||||
{
|
||||
off_t len;
|
||||
|
||||
|
@ -928,14 +931,15 @@ bool gossmap_refresh(struct gossmap *map)
|
|||
map->mmap = mmap(NULL, map->map_size, PROT_READ, MAP_SHARED, map->fd, 0);
|
||||
if (map->mmap == MAP_FAILED)
|
||||
map->mmap = NULL;
|
||||
return map_catchup(map);
|
||||
return map_catchup(map, num_rejected);
|
||||
}
|
||||
|
||||
struct gossmap *gossmap_load(const tal_t *ctx, const char *filename)
|
||||
struct gossmap *gossmap_load(const tal_t *ctx, const char *filename,
|
||||
size_t *num_channel_updates_rejected)
|
||||
{
|
||||
map = tal(ctx, struct gossmap);
|
||||
map->fname = tal_strdup(map, filename);
|
||||
if (load_gossip_store(map))
|
||||
if (load_gossip_store(map, num_channel_updates_rejected))
|
||||
tal_add_destructor(map, destroy_map);
|
||||
else
|
||||
map = tal_free(map);
|
||||
|
|
|
@ -41,11 +41,14 @@ struct gossmap_chan {
|
|||
} half[2];
|
||||
};
|
||||
|
||||
struct gossmap *gossmap_load(const tal_t *ctx, const char *filename);
|
||||
/* If num_channel_updates_rejected is not NULL, indicates how many channels we
|
||||
* marked inactive because their values were too high to be represented. */
|
||||
struct gossmap *gossmap_load(const tal_t *ctx, const char *filename,
|
||||
size_t *num_channel_updates_rejected);
|
||||
|
||||
/* Call this before using to ensure it's up-to-date. Returns true if something
|
||||
* was updated. Note: this can scramble node and chan indexes! */
|
||||
bool gossmap_refresh(struct gossmap *map);
|
||||
bool gossmap_refresh(struct gossmap *map, size_t *num_channel_updates_rejected);
|
||||
|
||||
/* Local modifications. */
|
||||
struct gossmap_localmods *gossmap_localmods_new(const tal_t *ctx);
|
||||
|
|
|
@ -311,7 +311,7 @@ int main(int argc, char *argv[])
|
|||
fd = mkstemp(gossfile);
|
||||
assert(write_all(fd, canned_map, sizeof(canned_map)));
|
||||
|
||||
map = gossmap_load(tmpctx, gossfile);
|
||||
map = gossmap_load(tmpctx, gossfile, NULL);
|
||||
assert(map);
|
||||
|
||||
/* There is a public channel 2<->3 (103x1x0), and private
|
||||
|
@ -503,6 +503,6 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* Now we can refresh. */
|
||||
assert(write(fd, "", 1) == 1);
|
||||
gossmap_refresh(map);
|
||||
gossmap_refresh(map, NULL);
|
||||
common_shutdown();
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ int main(void)
|
|||
assert(write(store_fd, &gossip_version, sizeof(gossip_version))
|
||||
== sizeof(gossip_version));
|
||||
|
||||
gossmap = gossmap_load(tmpctx, gossipfilename);
|
||||
gossmap = gossmap_load(tmpctx, gossipfilename, NULL);
|
||||
|
||||
/* [{'active': True, 'short_id': '6990:2:1/1', 'fee_per_kw': 10, 'delay': 5, 'message_flags': 0, 'channel_flags': 1, 'destination': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'source': '02ea622d5c8d6143f15ed3ce1d501dd0d3d09d3b1c83a44d0034949f8a9ab60f06', 'last_update': 1504064344}, */
|
||||
add_connection(store_fd, &c, &b, "6990x2x1",
|
||||
|
@ -232,7 +232,7 @@ int main(void)
|
|||
AMOUNT_MSAT(0), AMOUNT_MSAT(1000),
|
||||
0, 10, 5, false);
|
||||
|
||||
assert(gossmap_refresh(gossmap));
|
||||
assert(gossmap_refresh(gossmap, NULL));
|
||||
|
||||
a_node = gossmap_find_node(gossmap, &a);
|
||||
b_node = gossmap_find_node(gossmap, &b);
|
||||
|
@ -278,7 +278,7 @@ int main(void)
|
|||
add_connection(store_fd, &a, &d, "6991x2x1",
|
||||
AMOUNT_MSAT(100), AMOUNT_MSAT(499968), /* exact repr in fp16! */
|
||||
0, 0, 5);
|
||||
assert(gossmap_refresh(gossmap));
|
||||
assert(gossmap_refresh(gossmap, NULL));
|
||||
|
||||
a_node = gossmap_find_node(gossmap, &a);
|
||||
b_node = gossmap_find_node(gossmap, &b);
|
||||
|
|
|
@ -190,18 +190,18 @@ int main(void)
|
|||
store_fd = mkstemp(gossipfilename);
|
||||
assert(write(store_fd, &gossip_version, sizeof(gossip_version))
|
||||
== sizeof(gossip_version));
|
||||
gossmap = gossmap_load(tmpctx, gossipfilename);
|
||||
gossmap = gossmap_load(tmpctx, gossipfilename, NULL);
|
||||
|
||||
memset(&tmp, 'a', sizeof(tmp));
|
||||
node_id_from_privkey(&tmp, &a);
|
||||
memset(&tmp, 'b', sizeof(tmp));
|
||||
node_id_from_privkey(&tmp, &b);
|
||||
|
||||
assert(!gossmap_refresh(gossmap));
|
||||
assert(!gossmap_refresh(gossmap, NULL));
|
||||
|
||||
/* A<->B */
|
||||
add_connection(store_fd, &a, &b, 1, 1, 1);
|
||||
assert(gossmap_refresh(gossmap));
|
||||
assert(gossmap_refresh(gossmap, NULL));
|
||||
|
||||
a_node = gossmap_find_node(gossmap, &a);
|
||||
b_node = gossmap_find_node(gossmap, &b);
|
||||
|
@ -219,7 +219,7 @@ int main(void)
|
|||
memset(&tmp, 'c', sizeof(tmp));
|
||||
node_id_from_privkey(&tmp, &c);
|
||||
add_connection(store_fd, &b, &c, 1, 1, 1);
|
||||
assert(gossmap_refresh(gossmap));
|
||||
assert(gossmap_refresh(gossmap, NULL));
|
||||
|
||||
/* These can theoretically change after refresh! */
|
||||
a_node = gossmap_find_node(gossmap, &a);
|
||||
|
@ -243,7 +243,7 @@ int main(void)
|
|||
|
||||
add_connection(store_fd, &a, &d, 0, 2, 1);
|
||||
add_connection(store_fd, &d, &c, 0, 2, 1);
|
||||
assert(gossmap_refresh(gossmap));
|
||||
assert(gossmap_refresh(gossmap, NULL));
|
||||
|
||||
/* These can theoretically change after refresh! */
|
||||
a_node = gossmap_find_node(gossmap, &a);
|
||||
|
@ -284,7 +284,7 @@ int main(void)
|
|||
|
||||
/* Make B->C inactive, force it back via D */
|
||||
update_connection(store_fd, &b, &c, 1, 1, 1, true);
|
||||
assert(gossmap_refresh(gossmap));
|
||||
assert(gossmap_refresh(gossmap, NULL));
|
||||
|
||||
/* These can theoretically change after refresh! */
|
||||
a_node = gossmap_find_node(gossmap, &a);
|
||||
|
|
|
@ -71,6 +71,7 @@ int main(int argc, char *argv[])
|
|||
struct gossmap *map;
|
||||
struct node_id dstid;
|
||||
bool clean_topology = false;
|
||||
size_t num_channel_updates_rejected;
|
||||
|
||||
opt_register_noarg("--clean-topology", opt_set_bool, &clean_topology,
|
||||
"Clean up topology before run");
|
||||
|
@ -83,13 +84,14 @@ int main(int argc, char *argv[])
|
|||
opt_usage_exit_fail("Expect 3 arguments");
|
||||
|
||||
tstart = time_mono();
|
||||
map = gossmap_load(NULL, argv[1]);
|
||||
map = gossmap_load(NULL, argv[1], &num_channel_updates_rejected);
|
||||
if (!map)
|
||||
err(1, "Loading gossip store %s", argv[1]);
|
||||
tstop = time_mono();
|
||||
|
||||
printf("# Time to load: %"PRIu64" msec\n",
|
||||
time_to_msec(timemono_between(tstop, tstart)));
|
||||
printf("# Time to load: %"PRIu64" msec (%zu ignored)\n",
|
||||
time_to_msec(timemono_between(tstop, tstart)),
|
||||
num_channel_updates_rejected);
|
||||
|
||||
if (clean_topology)
|
||||
clean_topo(map, false);
|
||||
|
|
|
@ -270,7 +270,7 @@ int main(int argc, char *argv[])
|
|||
opt_usage_exit_fail("Expect 3 arguments");
|
||||
|
||||
tstart = time_mono();
|
||||
map = gossmap_load(NULL, argv[1]);
|
||||
map = gossmap_load(NULL, argv[1], NULL);
|
||||
if (!map)
|
||||
err(1, "Loading gossip store %s", argv[1]);
|
||||
tstop = time_mono();
|
||||
|
|
|
@ -462,12 +462,18 @@ static struct command_result *sendonionmsg_done(struct command *cmd,
|
|||
|
||||
static void init_gossmap(struct plugin *plugin)
|
||||
{
|
||||
size_t num_cupdates_rejected;
|
||||
global_gossmap
|
||||
= notleak_with_children(gossmap_load(NULL,
|
||||
GOSSIP_STORE_FILENAME));
|
||||
GOSSIP_STORE_FILENAME,
|
||||
&num_cupdates_rejected));
|
||||
if (!global_gossmap)
|
||||
plugin_err(plugin, "Could not load gossmap %s: %s",
|
||||
GOSSIP_STORE_FILENAME, strerror(errno));
|
||||
if (num_cupdates_rejected)
|
||||
plugin_log(plugin, LOG_DBG,
|
||||
"gossmap ignored %zu channel updates",
|
||||
num_cupdates_rejected);
|
||||
}
|
||||
|
||||
static struct gossmap *get_gossmap(struct plugin *plugin)
|
||||
|
@ -475,7 +481,7 @@ static struct gossmap *get_gossmap(struct plugin *plugin)
|
|||
if (!global_gossmap)
|
||||
init_gossmap(plugin);
|
||||
else
|
||||
gossmap_refresh(global_gossmap);
|
||||
gossmap_refresh(global_gossmap, NULL);
|
||||
return global_gossmap;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,18 @@ static struct gossmap *global_gossmap;
|
|||
|
||||
static void init_gossmap(struct plugin *plugin)
|
||||
{
|
||||
size_t num_channel_updates_rejected;
|
||||
global_gossmap
|
||||
= notleak_with_children(gossmap_load(NULL,
|
||||
GOSSIP_STORE_FILENAME));
|
||||
GOSSIP_STORE_FILENAME,
|
||||
&num_channel_updates_rejected));
|
||||
if (!global_gossmap)
|
||||
plugin_err(plugin, "Could not load gossmap %s: %s",
|
||||
GOSSIP_STORE_FILENAME, strerror(errno));
|
||||
if (num_channel_updates_rejected)
|
||||
plugin_log(plugin, LOG_DBG,
|
||||
"gossmap ignored %zu channel updates",
|
||||
num_channel_updates_rejected);
|
||||
}
|
||||
|
||||
struct gossmap *get_gossmap(struct plugin *plugin)
|
||||
|
@ -30,7 +36,7 @@ struct gossmap *get_gossmap(struct plugin *plugin)
|
|||
if (!global_gossmap)
|
||||
init_gossmap(plugin);
|
||||
else
|
||||
gossmap_refresh(global_gossmap);
|
||||
gossmap_refresh(global_gossmap, NULL);
|
||||
return global_gossmap;
|
||||
}
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ int main(void)
|
|||
assert(write(store_fd, &gossip_version, sizeof(gossip_version))
|
||||
== sizeof(gossip_version));
|
||||
|
||||
gossmap = gossmap_load(tmpctx, gossipfilename);
|
||||
gossmap = gossmap_load(tmpctx, gossipfilename, NULL);
|
||||
|
||||
for (size_t i = 0; i < NUM_NODES; i++) {
|
||||
struct privkey tmp;
|
||||
|
@ -384,7 +384,7 @@ int main(void)
|
|||
1 << i);
|
||||
}
|
||||
|
||||
assert(gossmap_refresh(gossmap));
|
||||
assert(gossmap_refresh(gossmap, NULL));
|
||||
for (size_t i = ROUTING_MAX_HOPS; i > 2; i--) {
|
||||
struct gossmap_node *dst, *src;
|
||||
struct route_hop *r;
|
||||
|
|
|
@ -27,7 +27,7 @@ static struct plugin *plugin;
|
|||
/* We load this on demand, since we can start before gossipd. */
|
||||
static struct gossmap *get_gossmap(void)
|
||||
{
|
||||
gossmap_refresh(global_gossmap);
|
||||
gossmap_refresh(global_gossmap, NULL);
|
||||
return global_gossmap;
|
||||
}
|
||||
|
||||
|
@ -687,17 +687,24 @@ done:
|
|||
static const char *init(struct plugin *p,
|
||||
const char *buf UNUSED, const jsmntok_t *config UNUSED)
|
||||
{
|
||||
size_t num_cupdates_rejected;
|
||||
|
||||
plugin = p;
|
||||
rpc_scan(p, "getinfo",
|
||||
take(json_out_obj(NULL, NULL, NULL)),
|
||||
"{id:%}", JSON_SCAN(json_to_node_id, &local_id));
|
||||
|
||||
global_gossmap = notleak_with_children(gossmap_load(NULL,
|
||||
GOSSIP_STORE_FILENAME));
|
||||
GOSSIP_STORE_FILENAME,
|
||||
&num_cupdates_rejected));
|
||||
if (!global_gossmap)
|
||||
plugin_err(plugin, "Could not load gossmap %s: %s",
|
||||
GOSSIP_STORE_FILENAME, strerror(errno));
|
||||
|
||||
if (num_cupdates_rejected)
|
||||
plugin_log(plugin, LOG_DBG,
|
||||
"gossmap ignored %zu channel updates",
|
||||
num_cupdates_rejected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue