bitcoin: hash_scid and hash_scidd public functions.
What changed, and why it matters
This commit is a routine code cleanup: it renames an internal hash function and consolidates duplicate copies of the same hashing logic into one shared helper. There is no user-facing change, no bug fix, and no security-relevant behavior change.
No security action required; treat as normal refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch renames short_channel_id_hash to hash_scid in bitcoin/short_channel_id.h and adds a new inline helper hash_scidd for short_channel_id_dir. It removes redundant local implementations from plugins/askrene/askrene.h, plugins/askrene/layer.c, plugins/channel_hint.c, plugins/channel_hint.h, and plugins/renepay/disabledmap.h, switching those hash tables to the shared helpers. It also fixes a few call sites in plugins/renepay/disabledmap.c to pass pointers instead of values to scidd_map_get. The hash algorithms remain conceptually identical or equivalent for the intended use cases.
Changed components
bitcoin/short_channel_id.hcommon/gossmap.cconnectd/connectd.hlightningd/channel.hplugins/askrene/askrene.hplugins/askrene/layer.cplugins/channel_hint.cplugins/channel_hint.hplugins/renepay/chan_extra.hplugins/renepay/disabledmap.cplugins/renepay/disabledmap.hInspect captured patch +20 / −54
diff --git a/bitcoin/short_channel_id.h b/bitcoin/short_channel_id.h
index 3c7cce90..0a49a73f 100644
--- a/bitcoin/short_channel_id.h
+++ b/bitcoin/short_channel_id.h
@@ -17,7 +17,7 @@ static inline bool short_channel_id_eq(struct short_channel_id a,
return a.u64 == b.u64;
}
-static inline size_t short_channel_id_hash(struct short_channel_id scid)
+static inline size_t hash_scid(struct short_channel_id scid)
{
/* scids cost money to generate, so simple hash works here */
return (scid.u64 >> 32) ^ (scid.u64 >> 16) ^ scid.u64;
@@ -46,6 +46,12 @@ static inline bool short_channel_id_dir_eq(const struct short_channel_id_dir *a,
return short_channel_id_eq(a->scid, b->scid) && a->dir == b->dir;
}
+static inline size_t hash_scidd(const struct short_channel_id_dir *scidd)
+{
+ /* Bottom bit is common, so use bit 4 for direction */
+ return hash_scid(scidd->scid) | (scidd->dir << 4);
+}
+
static inline u32 short_channel_id_blocknum(struct short_channel_id scid)
{
return scid.u64 >> 40;
diff --git a/common/gossmap.c b/common/gossmap.c
index 693ebd0e..ce3d5425 100644
--- a/common/gossmap.c
+++ b/common/gossmap.c
@@ -29,7 +29,7 @@ static bool chanidx_eq_id(const ptrint_t *pidx,
struct short_channel_id pidxid = chanidx_id(pidx);
return short_channel_id_eq(pidxid, scid);
}
-HTABLE_DEFINE_NODUPS_TYPE(ptrint_t, chanidx_id, short_channel_id_hash, chanidx_eq_id,
+HTABLE_DEFINE_NODUPS_TYPE(ptrint_t, chanidx_id, hash_scid, chanidx_eq_id,
chanidx_htable);
static struct node_id nodeidx_id(const ptrint_t *pidx);
diff --git a/connectd/connectd.h b/connectd/connectd.h
index 1cce2c64..79770057 100644
--- a/connectd/connectd.h
+++ b/connectd/connectd.h
@@ -262,7 +262,7 @@ static bool scid_to_node_id_eq_scid(const struct scid_to_node_id *scid_to_node_i
* we use this to forward onion messages which specify the next hop by scid/dir. */
HTABLE_DEFINE_NODUPS_TYPE(struct scid_to_node_id,
scid_to_node_id_keyof,
- short_channel_id_hash,
+ hash_scid,
scid_to_node_id_eq_scid,
scid_htable);
diff --git a/lightningd/channel.h b/lightningd/channel.h
index bb27b687..9661e4b7 100644
--- a/lightningd/channel.h
+++ b/lightningd/channel.h
@@ -891,7 +891,7 @@ static inline bool scid_to_channel_eq_scid(const struct scid_to_channel *scidcha
/* Define channel_scid_map */
HTABLE_DEFINE_NODUPS_TYPE(struct scid_to_channel,
scid_to_channel_key,
- short_channel_id_hash,
+ hash_scid,
scid_to_channel_eq_scid,
channel_scid_map);
diff --git a/plugins/askrene/askrene.h b/plugins/askrene/askrene.h
index 207e3725..c9b15e39 100644
--- a/plugins/askrene/askrene.h
+++ b/plugins/askrene/askrene.h
@@ -95,12 +95,4 @@ static inline struct askrene *get_askrene(struct plugin *plugin)
{
return plugin_get_data(plugin, struct askrene);
}
-
-/* Convenience routine for hash tables */
-static inline size_t hash_scidd(const struct short_channel_id_dir *scidd)
-{
- /* scids cost money to generate, so simple hash works here */
- return (scidd->scid.u64 >> 32) ^ (scidd->scid.u64 >> 16) ^ (scidd->scid.u64 << 1) ^ scidd->dir;
-}
-
#endif /* LIGHTNING_PLUGINS_ASKRENE_ASKRENE_H */
diff --git a/plugins/askrene/layer.c b/plugins/askrene/layer.c
index 77bfa5ac..f811169e 100644
--- a/plugins/askrene/layer.c
+++ b/plugins/askrene/layer.c
@@ -81,12 +81,6 @@ local_channel_scid(const struct local_channel *lc)
return lc->scid;
}
-static size_t hash_scid(const struct short_channel_id scid)
-{
- /* scids cost money to generate, so simple hash works here */
- return (scid.u64 >> 32) ^ (scid.u64 >> 16) ^ scid.u64;
-}
-
static inline bool local_channel_eq_scid(const struct local_channel *lc,
const struct short_channel_id scid)
{
diff --git a/plugins/channel_hint.c b/plugins/channel_hint.c
index 299c605d..d7fc9076 100644
--- a/plugins/channel_hint.c
+++ b/plugins/channel_hint.c
@@ -3,15 +3,6 @@
#include <common/memleak.h>
#include <plugins/channel_hint.h>
-size_t channel_hint_hash(const struct short_channel_id_dir *out)
-{
- struct siphash24_ctx ctx;
- siphash24_init(&ctx, siphash_seed());
- siphash24_update(&ctx, &out->scid.u64, sizeof(u64));
- siphash24_update(&ctx, &out->dir, sizeof(int));
- return siphash24_done(&ctx);
-}
-
const struct short_channel_id_dir *channel_hint_keyof(const struct channel_hint *out)
{
return &out->scid;
@@ -20,8 +11,7 @@ const struct short_channel_id_dir *channel_hint_keyof(const struct channel_hint
bool channel_hint_eq(const struct channel_hint *a,
const struct short_channel_id_dir *b)
{
- return short_channel_id_eq(a->scid.scid, b->scid) &&
- a->scid.dir == b->dir;
+ return short_channel_id_dir_eq(&a->scid, b);
}
void channel_hint_to_json(const char *name, const struct channel_hint *hint,
diff --git a/plugins/channel_hint.h b/plugins/channel_hint.h
index db94c5b3..44e3bc1c 100644
--- a/plugins/channel_hint.h
+++ b/plugins/channel_hint.h
@@ -40,15 +40,13 @@ struct channel_hint {
struct amount_msat capacity;
};
-size_t channel_hint_hash(const struct short_channel_id_dir *out);
-
const struct short_channel_id_dir *channel_hint_keyof(const struct channel_hint *out);
bool channel_hint_eq(const struct channel_hint *a,
const struct short_channel_id_dir *b);
HTABLE_DEFINE_NODUPS_TYPE(struct channel_hint, channel_hint_keyof,
- channel_hint_hash, channel_hint_eq, channel_hint_map)
+ hash_scidd, channel_hint_eq, channel_hint_map)
/* A collection of channel_hint instances, allowing us to handle and
* update them more easily. */
diff --git a/plugins/renepay/chan_extra.h b/plugins/renepay/chan_extra.h
index d7213ad5..69a206e9 100644
--- a/plugins/renepay/chan_extra.h
+++ b/plugins/renepay/chan_extra.h
@@ -50,7 +50,8 @@ static inline bool chan_extra_eq_scid(const struct chan_extra *cd,
return short_channel_id_eq(scid, cd->scid);
}
-HTABLE_DEFINE_NODUPS_TYPE(struct chan_extra, chan_extra_scid, short_channel_id_hash,
+HTABLE_DEFINE_NODUPS_TYPE(struct chan_extra, chan_extra_scid,
+ hash_scid,
chan_extra_eq_scid,
chan_extra_map);
diff --git a/plugins/renepay/disabledmap.c b/plugins/renepay/disabledmap.c
index badeac86..7854bb8b 100644
--- a/plugins/renepay/disabledmap.c
+++ b/plugins/renepay/disabledmap.c
@@ -47,7 +47,7 @@ void disabledmap_add_channel(struct disabledmap *p,
struct short_channel_id_dir scidd)
{
struct short_channel_id_dir *ptr_scidd =
- scidd_map_get(p->disabled_map, scidd);
+ scidd_map_get(p->disabled_map, &scidd);
if (ptr_scidd) {
/* htable allows for duplicates, but we don't want duplicates.
*/
@@ -64,7 +64,7 @@ void disabledmap_warn_channel(struct disabledmap *p,
struct short_channel_id_dir scidd)
{
struct short_channel_id_dir *ptr_scidd =
- scidd_map_get(p->warned_map, scidd);
+ scidd_map_get(p->warned_map, &scidd);
if (ptr_scidd) {
/* htable allows for duplicates, but we don't want duplicates.
*/
@@ -84,7 +84,7 @@ void disabledmap_add_node(struct disabledmap *p, struct node_id node)
bool disabledmap_channel_is_warned(struct disabledmap *p,
struct short_channel_id_dir scidd)
{
- return scidd_map_get(p->warned_map, scidd) != NULL;
+ return scidd_map_get(p->warned_map, &scidd) != NULL;
}
bitmap *tal_disabledmap_get_bitmap(const tal_t *ctx, struct disabledmap *p,
diff --git a/plugins/renepay/disabledmap.h b/plugins/renepay/disabledmap.h
index 7bd0487b..1f273f0b 100644
--- a/plugins/renepay/disabledmap.h
+++ b/plugins/renepay/disabledmap.h
@@ -8,31 +8,16 @@
#include <common/gossmap.h>
#include <common/node_id.h>
-static inline size_t hash_scidd(const struct short_channel_id_dir scidd)
-{
- /* scids cost money to generate, so simple hash works here. Letting same
- * scid with two directions collide. */
- return (scidd.scid.u64 >> 32) ^ (scidd.scid.u64 >> 16) ^ scidd.scid.u64;
-}
-
-static inline struct short_channel_id_dir
+static inline const struct short_channel_id_dir *
self_scidd(const struct short_channel_id_dir *self)
{
- return *self;
-}
-
-static inline bool
-my_short_channel_id_dir_eq(const struct short_channel_id_dir *scidd_a,
- const struct short_channel_id_dir scidd_b)
-{
- return short_channel_id_eq(scidd_a->scid, scidd_b.scid) &&
- scidd_a->dir == scidd_b.dir;
+ return self;
}
/* A htable for short_channel_id_dir, the structure itself is the element key.
*/
HTABLE_DEFINE_NODUPS_TYPE(struct short_channel_id_dir, self_scidd, hash_scidd,
- my_short_channel_id_dir_eq, scidd_map);
+ short_channel_id_dir_eq, scidd_map);
struct disabledmap {
/* Channels we decided to disable for various reasons. */
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.