diff --git a/gossipd/routing.c b/gossipd/routing.c index 9d3bf28c4..229e15519 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -25,30 +25,6 @@ /* 365.25 * 24 * 60 / 10 */ #define BLOCKS_PER_YEAR 52596 -/* We've unpacked and checked its signatures, now we wait for master to tell - * us the txout to check */ -struct pending_cannouncement { - /* Off routing_state->pending_cannouncement */ - struct list_node list; - - /* Unpacked fields here */ - struct short_channel_id short_channel_id; - struct node_id node_id_1; - struct node_id node_id_2; - struct pubkey bitcoin_key_1; - struct pubkey bitcoin_key_2; - - /* The raw bits */ - const u8 *announce; - - /* Deferred updates, if we received them while waiting for - * this (one for each direction) */ - const u8 *updates[2]; - - /* Only ever replace with newer updates */ - u32 update_timestamps[2]; -}; - struct pending_node_announce { struct routing_state *rstate; struct node_id nodeid; @@ -193,7 +169,9 @@ struct routing_state *new_routing_state(const tal_t *ctx, rstate->local_id = *local_id; rstate->prune_timeout = prune_timeout; rstate->local_channel_announced = false; - list_head_init(&rstate->pending_cannouncement); + + pending_cannouncement_map_init(&rstate->pending_cannouncements); + uintmap_init(&rstate->chanmap); uintmap_init(&rstate->unupdated_chanmap); chan_map_init(&rstate->local_disabled_map); @@ -895,19 +873,17 @@ static struct pending_cannouncement * find_pending_cannouncement(struct routing_state *rstate, const struct short_channel_id *scid) { - struct pending_cannouncement *i; + struct pending_cannouncement *pann; - list_for_each(&rstate->pending_cannouncement, i, list) { - if (short_channel_id_eq(scid, &i->short_channel_id)) - return i; - } - return NULL; + pann = pending_cannouncement_map_get(&rstate->pending_cannouncements, scid); + + return pann; } static void destroy_pending_cannouncement(struct pending_cannouncement *pending, struct routing_state *rstate) { - list_del_from(&rstate->pending_cannouncement, &pending->list); + pending_cannouncement_map_del(&rstate->pending_cannouncements, pending); } static bool is_local_channel(const struct routing_state *rstate, @@ -1152,7 +1128,7 @@ u8 *handle_channel_announcement(struct routing_state *rstate, catch_node_announcement(pending, rstate, &pending->node_id_1); catch_node_announcement(pending, rstate, &pending->node_id_2); - list_add_tail(&rstate->pending_cannouncement, &pending->list); + pending_cannouncement_map_add(&rstate->pending_cannouncements, pending); tal_add_destructor2(pending, destroy_pending_cannouncement, rstate); /* Success */ @@ -1253,7 +1229,7 @@ void handle_pending_cannouncement(struct routing_state *rstate, } /* Remove pending now, so below functions don't see it. */ - list_del_from(&rstate->pending_cannouncement, &pending->list); + pending_cannouncement_map_del(&rstate->pending_cannouncements, pending); tal_del_destructor2(pending, destroy_pending_cannouncement, rstate); if (!routing_add_channel_announcement(rstate, pending->announce, sat, 0)) @@ -2017,6 +1993,7 @@ void memleak_remove_routing_tables(struct htable *memtable, memleak_remove_htable(memtable, &rstate->nodes->raw); memleak_remove_htable(memtable, &rstate->pending_node_map->raw); + memleak_remove_htable(memtable, &rstate->pending_cannouncements.raw); for (n = node_map_first(rstate->nodes, &nit); n; diff --git a/gossipd/routing.h b/gossipd/routing.h index e5e4f6fcf..6dd1c3f2a 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -89,6 +89,7 @@ static inline bool chan_eq_scid(const struct chan *c, { return short_channel_id_eq(scid, &c->scid); } + HTABLE_DEFINE_TYPE(struct chan, chan_map_scid, hash_scid, chan_eq_scid, chan_map); /* For a small number of channels (by far the most common) we use a simple @@ -124,8 +125,54 @@ size_t node_map_hash_key(const struct node_id *pc); bool node_map_node_eq(const struct node *n, const struct node_id *pc); HTABLE_DEFINE_TYPE(struct node, node_map_keyof_node, node_map_hash_key, node_map_node_eq, node_map); +/* We've unpacked and checked its signatures, now we wait for master to tell + * us the txout to check */ +struct pending_cannouncement { + /* Unpacked fields here */ + + /* also the key in routing_state->pending_cannouncements */ + struct short_channel_id short_channel_id; + struct node_id node_id_1; + struct node_id node_id_2; + struct pubkey bitcoin_key_1; + struct pubkey bitcoin_key_2; + + /* The raw bits */ + const u8 *announce; + + /* Deferred updates, if we received them while waiting for + * this (one for each direction) */ + const u8 *updates[2]; + + /* Only ever replace with newer updates */ + u32 update_timestamps[2]; +}; + +static inline const struct short_channel_id *panding_cannouncement_map_scid( + const struct pending_cannouncement *pending_ann) +{ + return &pending_ann->short_channel_id; +} + +static inline size_t hash_pending_cannouncement_scid( + const struct short_channel_id *scid) +{ + /* like hash_scid() for struct chan above */ + return (scid->u64 >> 32) ^ (scid->u64 >> 16) ^ scid->u64; +} + +static inline bool pending_cannouncement_eq_scid( + const struct pending_cannouncement *pending_ann, + const struct short_channel_id *scid) +{ + return short_channel_id_eq(scid, &pending_ann->short_channel_id); +} + +HTABLE_DEFINE_TYPE(struct pending_cannouncement, panding_cannouncement_map_scid, + hash_pending_cannouncement_scid, pending_cannouncement_eq_scid, + pending_cannouncement_map); + struct pending_node_map; -struct pending_cannouncement; struct unupdated_channel; /* Fast versions: if you know n is one end of the channel */ @@ -167,9 +214,8 @@ struct routing_state { /* node_announcements which are waiting on pending_cannouncement */ struct pending_node_map *pending_node_map; - /* FIXME: Make this a htable! */ /* channel_announcement which are pending short_channel_id lookup */ - struct list_head pending_cannouncement; + struct pending_cannouncement_map pending_cannouncements; /* Broadcast map, and access to gossip store */ struct broadcast_state *broadcasts;