gossmap: don't process channel_announcement until amount is present.

This simplifies the callers significantly: all channel_announcements now
have an amount, so gossmap_chan_get_capacity() only fails on a local
modification.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-08-07 11:19:52 +09:30
parent 4d593463fa
commit e11bab8bbb
2 changed files with 16 additions and 7 deletions

View File

@ -444,7 +444,8 @@ void gossmap_remove_node(struct gossmap *map, struct gossmap_node *node)
* * [`point`:`node_id_2`]
*/
static struct gossmap_chan *add_channel(struct gossmap *map,
size_t cannounce_off)
size_t cannounce_off,
size_t msglen)
{
/* Note that first two bytes are message type */
const size_t feature_len_off = 2 + (64 + 64 + 64 + 64);
@ -473,6 +474,12 @@ static struct gossmap_chan *add_channel(struct gossmap *map,
return NULL;
}
/* gossipd writes WIRE_GOSSIP_STORE_CHANNEL_AMOUNT after this (not for
* local channels), so ignore channel_announcement until that appears */
if (msglen
&& (map->map_size < cannounce_off + msglen + sizeof(struct gossip_hdr) + sizeof(u16) + sizeof(u64)))
return NULL;
/* We carefully map pointers to indexes, since new_node can move them! */
n[0] = gossmap_find_node(map, &node_id[0]);
if (n[0])
@ -668,9 +675,11 @@ static bool map_catchup(struct gossmap *map, bool *changed)
off = map->map_end + sizeof(ghdr);
type = map_be16(map, off);
if (type == WIRE_CHANNEL_ANNOUNCEMENT)
add_channel(map, off);
else if (type == WIRE_CHANNEL_UPDATE)
if (type == WIRE_CHANNEL_ANNOUNCEMENT) {
/* Don't read yet if amount field is not there! */
if (!add_channel(map, off, be16_to_cpu(ghdr.len)))
break;
} else if (type == WIRE_CHANNEL_UPDATE)
update_channel(map, off);
else if (type == WIRE_GOSSIP_STORE_DELETE_CHAN)
remove_channel_by_deletemsg(map, off);
@ -944,7 +953,7 @@ void gossmap_apply_localmods(struct gossmap *map,
continue;
/* Create new channel, pointing into local. */
chan = add_channel(map, map->map_size + mod->local_off);
chan = add_channel(map, map->map_size + mod->local_off, 0);
}
/* Save old, overwrite (keep nodeidx) */
@ -1144,7 +1153,7 @@ bool gossmap_chan_get_capacity(const struct gossmap *map,
off += sizeof(ghdr) + be16_to_cpu(ghdr.len);
/* Partial write, this can happen. */
if (off + sizeof(ghdr) + 2 > map->map_size)
if (off + sizeof(ghdr) + sizeof(u16) + sizeof(u64) > map->map_size)
return false;
/* Get type of next field. */

View File

@ -161,7 +161,7 @@ static inline bool gossmap_chan_set(const struct gossmap_chan *chan, int dir)
return chan->cupdate_off[dir] != 0;
}
/* Return capacity if it's known (fails only on race condition, or a local mod) */
/* Return capacity if it's known (fails on a local mod) */
bool gossmap_chan_get_capacity(const struct gossmap *map,
const struct gossmap_chan *c,
struct amount_sat *amount);