common: extract fp16 routines into their own file.

We might want to use them elsewhere.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2021-02-01 13:29:18 +10:30
parent 06a54606a3
commit cc4ea9420a
8 changed files with 82 additions and 54 deletions

View File

@ -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 \

50
common/fp16.c Normal file
View File

@ -0,0 +1,50 @@
#include "config.h"
#include <assert.h>
#include <ccan/bitops/bitops.h>
#include <common/fp16.h>
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 */
}

19
common/fp16.h Normal file
View File

@ -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 <common/amount.h>
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 */

View File

@ -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;

View File

@ -4,13 +4,11 @@
#include <bitcoin/short_channel_id.h>
#include <ccan/typesafe_cb/typesafe_cb.h>
#include <common/amount.h>
#include <common/fp16.h>
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

View File

@ -1,5 +1,8 @@
#include "../fp16.c"
#include <common/pseudorand.h>
#include <common/type_to_string.h>
#include <stdio.h>
#include "../gossmap.c"
#include <wire/wire.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for amount_asset_is_main */

View File

@ -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

View File

@ -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)