diff --git a/common/Makefile b/common/Makefile index ee582544e..b72c6695c 100644 --- a/common/Makefile +++ b/common/Makefile @@ -32,6 +32,7 @@ COMMON_SRC_NOGEN := \ common/ecdh_hsmd.c \ common/features.c \ common/fee_states.c \ + common/fp16.c \ common/gossip_rcvd_filter.c \ common/gossip_store.c \ common/hash_u5.c \ diff --git a/common/fp16.c b/common/fp16.c new file mode 100644 index 000000000..f87154dcb --- /dev/null +++ b/common/fp16.c @@ -0,0 +1,50 @@ +#include "config.h" +#include +#include +#include + +fp16_t u64_to_fp16(u64 val, bool round_up) +{ + u16 mantissa_bits, mantissa, exponent; + + if (val == 0) + return 0; + + /* How many bits do we need to represent mantissa? */ + mantissa_bits = bitops_hs64(val) + 1; + + /* We only have 11 bits, so if we need more, we will round. */ + if (mantissa_bits > 11) { + exponent = mantissa_bits - 11; + mantissa = (val >> exponent); + /* If we're losing bits here, we're rounding down */ + if (round_up && (val & ((1ULL << exponent)-1))) { + mantissa++; + if (mantissa == (1 << 11)) { + mantissa >>= 1; + exponent++; + } + } + /* huge number? Make it max. */ + if (exponent >= 32) { + exponent = 31; + mantissa = (1 << 11)-1; + } + } else { + exponent = 0; + mantissa = val; + } + + assert((mantissa >> 11) == 0); + return (exponent << 11) | mantissa; +} + +bool amount_msat_less_fp16(struct amount_msat amt, fp16_t fp) +{ + return amt.millisatoshis < fp16_to_u64(fp); /* Raw: fp16 compare */ +} + +bool amount_msat_greater_fp16(struct amount_msat amt, fp16_t fp) +{ + return amt.millisatoshis > fp16_to_u64(fp); /* Raw: fp16 compare */ +} diff --git a/common/fp16.h b/common/fp16.h new file mode 100644 index 000000000..57e7112aa --- /dev/null +++ b/common/fp16.h @@ -0,0 +1,19 @@ +/* 5 bit exponent, 11 bit mantissa approximations of min/max */ +#ifndef LIGHTNING_COMMON_FP16_H +#define LIGHTNING_COMMON_FP16_H +#include "config.h" +#include + +typedef u16 fp16_t; + +static inline u64 fp16_to_u64(fp16_t val) +{ + return ((u64)val & ((1 << 11)-1)) << (val >> 11); +} + +fp16_t u64_to_fp16(u64 val, bool round_up); + +bool amount_msat_less_fp16(struct amount_msat amt, fp16_t fp); +bool amount_msat_greater_fp16(struct amount_msat amt, fp16_t fp); + +#endif /* LIGHTNING_COMMON_FP16_H */ diff --git a/common/gossmap.c b/common/gossmap.c index fa2473a41..d0b7be70c 100644 --- a/common/gossmap.c +++ b/common/gossmap.c @@ -227,42 +227,6 @@ struct gossmap_chan *gossmap_find_chan(const struct gossmap *map, return NULL; } -static fp16_t u64_to_fp16(u64 val, bool round_up) -{ - u16 mantissa_bits, mantissa, exponent; - - if (val == 0) - return 0; - - /* How many bits do we need to represent mantissa? */ - mantissa_bits = bitops_hs64(val) + 1; - - /* We only have 11 bits, so if we need more, we will round. */ - if (mantissa_bits > 11) { - exponent = mantissa_bits - 11; - mantissa = (val >> exponent); - /* If we're losing bits here, we're rounding down */ - if (round_up && (val & ((1ULL << exponent)-1))) { - mantissa++; - if (mantissa == (1 << 11)) { - mantissa >>= 1; - exponent++; - } - } - /* huge number? Make it max. */ - if (exponent >= 32) { - exponent = 31; - mantissa = (1 << 11)-1; - } - } else { - exponent = 0; - mantissa = val; - } - - assert((mantissa >> 11) == 0); - return (exponent << 11) | mantissa; -} - static u32 init_node_arr(struct gossmap_node *node_arr, size_t start) { size_t i; @@ -822,12 +786,10 @@ bool gossmap_chan_capacity(const struct gossmap_chan *chan, int direction, struct amount_msat amount) { - if (amount.millisatoshis /* Raw: fp16 compare */ - < fp16_to_u64(chan->half[direction].htlc_min)) + if (amount_msat_less_fp16(amount, chan->half[direction].htlc_min)) return false; - if (amount.millisatoshis /* Raw: fp16 compare */ - > fp16_to_u64(chan->half[direction].htlc_max)) + if (amount_msat_greater_fp16(amount, chan->half[direction].htlc_max)) return false; return true; diff --git a/common/gossmap.h b/common/gossmap.h index 0350f0675..6dae347f7 100644 --- a/common/gossmap.h +++ b/common/gossmap.h @@ -4,13 +4,11 @@ #include #include #include +#include struct node_id; struct pubkey32; -/* 5 bit exponent, 11 bit mantissa approximations of min/max */ -typedef u16 fp16_t; - struct gossmap_node { /* Offset in memory map for node_announce, or 0. */ u32 nann_off; @@ -38,11 +36,6 @@ struct gossmap_chan { } half[2]; }; -static inline u64 fp16_to_u64(fp16_t val) -{ - return ((u64)val & ((1 << 11)-1)) << (val >> 11); -} - struct gossmap *gossmap_load(const tal_t *ctx, const char *filename); /* Call this before using to ensure it's up-to-date. Returns true if something diff --git a/common/test/run-gossmap-fp16.c b/common/test/run-gossmap-fp16.c index cac2037a8..cc7e84d70 100644 --- a/common/test/run-gossmap-fp16.c +++ b/common/test/run-gossmap-fp16.c @@ -1,5 +1,8 @@ +#include "../fp16.c" +#include +#include #include -#include "../gossmap.c" +#include /* AUTOGENERATED MOCKS START */ /* Generated stub for amount_asset_is_main */ diff --git a/devtools/Makefile b/devtools/Makefile index 4bb8418f0..247f853a3 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -83,6 +83,6 @@ devtools/mkquery: $(DEVTOOLS_COMMON_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/from devtools/lightning-checkmessage: $(DEVTOOLS_COMMON_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/lightning-checkmessage.o -devtools/route: $(DEVTOOLS_COMMON_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o wire/tlvstream.o common/gossmap.o common/random_select.o common/route.o common/dijkstra.o devtools/clean_topo.o devtools/route.o +devtools/route: $(DEVTOOLS_COMMON_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o wire/tlvstream.o common/gossmap.o common/fp16.o common/random_select.o common/route.o common/dijkstra.o devtools/clean_topo.o devtools/route.o -devtools/topology: $(DEVTOOLS_COMMON_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o wire/tlvstream.o common/gossmap.o common/random_select.o common/dijkstra.o common/route.o devtools/clean_topo.o devtools/topology.o +devtools/topology: $(DEVTOOLS_COMMON_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o wire/tlvstream.o common/gossmap.o common/fp16.o common/random_select.o common/dijkstra.o common/route.o devtools/clean_topo.o devtools/topology.o diff --git a/plugins/Makefile b/plugins/Makefile index cbaf5b35c..ac07fbfbe 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -118,7 +118,7 @@ PLUGIN_COMMON_OBJS := \ wire/tlvstream.o \ wire/towire.o -plugins/pay: bitcoin/chainparams.o $(PLUGIN_PAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) common/gossmap.o common/route.o common/dijkstra.o common/bolt12.o common/bolt12_merkle.o wire/bolt12$(EXP)_wiregen.o bitcoin/block.o +plugins/pay: bitcoin/chainparams.o $(PLUGIN_PAY_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) common/gossmap.o common/fp16.o common/route.o common/dijkstra.o common/bolt12.o common/bolt12_merkle.o wire/bolt12$(EXP)_wiregen.o bitcoin/block.o $(PLUGIN_PAY_OBJS): $(PLUGIN_PAY_LIB_HEADER) plugins/autoclean: bitcoin/chainparams.o $(PLUGIN_AUTOCLEAN_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) @@ -127,14 +127,14 @@ plugins/txprepare: bitcoin/chainparams.o $(PLUGIN_TXPREPARE_OBJS) $(PLUGIN_LIB_O plugins/bcli: bitcoin/chainparams.o $(PLUGIN_BCLI_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) -plugins/keysend: bitcoin/chainparams.o wire/tlvstream.o wire/onion$(EXP)_wiregen.o $(PLUGIN_KEYSEND_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) common/gossmap.o common/route.o common/dijkstra.o +plugins/keysend: bitcoin/chainparams.o wire/tlvstream.o wire/onion$(EXP)_wiregen.o $(PLUGIN_KEYSEND_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_PAY_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) common/gossmap.o common/fp16.o common/route.o common/dijkstra.o $(PLUGIN_KEYSEND_OBJS): $(PLUGIN_PAY_LIB_HEADER) plugins/spenderp: bitcoin/chainparams.o bitcoin/psbt.o common/psbt_open.o $(PLUGIN_SPENDER_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) plugins/offers: bitcoin/chainparams.o $(PLUGIN_OFFERS_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/bolt12.o common/bolt12_merkle.o common/bolt11_json.o common/iso4217.o $(WIRE_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o $(JSMN_OBJS) $(CCAN_OBJS) -plugins/fetchinvoice: bitcoin/chainparams.o $(PLUGIN_FETCHINVOICE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/bolt12.o common/bolt12_merkle.o common/iso4217.o $(WIRE_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o $(JSMN_OBJS) $(CCAN_OBJS) common/gossmap.o common/dijkstra.o common/route.o common/blindedpath.o common/hmac.o common/blinding.o +plugins/fetchinvoice: bitcoin/chainparams.o $(PLUGIN_FETCHINVOICE_OBJS) $(PLUGIN_LIB_OBJS) $(PLUGIN_COMMON_OBJS) common/bolt12.o common/bolt12_merkle.o common/iso4217.o $(WIRE_OBJS) bitcoin/block.o common/channel_id.o bitcoin/preimage.o $(JSMN_OBJS) $(CCAN_OBJS) common/gossmap.o common/fp16.o common/dijkstra.o common/route.o common/blindedpath.o common/hmac.o common/blinding.o $(PLUGIN_ALL_OBJS): $(PLUGIN_LIB_HEADER)