From d1f8a5f0be5ace32dd881468a3e12095e9228498 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 22 May 2021 14:30:22 +0930 Subject: [PATCH] gossmap: add gossmap_chan_get_capacity() helper. Signed-off-by: Rusty Russell --- common/gossmap.c | 37 ++++++++++++++++++++++++--- common/gossmap.h | 5 ++++ common/test/run-gossmap_local.c | 45 ++++++--------------------------- 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/common/gossmap.c b/common/gossmap.c index 350c080c9..84ec77211 100644 --- a/common/gossmap.c +++ b/common/gossmap.c @@ -577,9 +577,7 @@ static bool map_catchup(struct gossmap *map) u16 type; map_copy(map, map->map_end, &ghdr, sizeof(ghdr)); - reclen = (be32_to_cpu(ghdr.len) - & ~(GOSSIP_STORE_LEN_DELETED_BIT| - GOSSIP_STORE_LEN_PUSH_BIT)) + reclen = (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_MASK) + sizeof(ghdr); if (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) @@ -947,6 +945,39 @@ void gossmap_node_get_id(const struct gossmap *map, + 8 + PUBKEY_CMPR_LEN*dir, id); } +bool gossmap_chan_get_capacity(const struct gossmap *map, + const struct gossmap_chan *c, + struct amount_sat *amount) +{ + struct gossip_hdr ghdr; + size_t off; + u16 type; + + /* For private, we need to go back WIRE_GOSSIP_STORE_PRIVATE_CHANNEL, + * which is 8 (satoshis) + 2 (len) */ + if (c->private) { + *amount = amount_sat(map_be64(map, c->cann_off - 8 - 2)); + return true; + } + + /* Skip over this record to next; expect a gossip_store_channel_amount */ + off = c->cann_off - sizeof(ghdr); + map_copy(map, off, &ghdr, sizeof(ghdr)); + off += sizeof(ghdr) + (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_MASK); + + /* Partial write, this can happen. */ + if (off + sizeof(ghdr) + 2 > map->map_size) + return false; + + /* Get type of next field. */ + type = map_be16(map, off + sizeof(ghdr)); + if (type != WIRE_GOSSIP_STORE_CHANNEL_AMOUNT) + return false; + + *amount = amount_sat(map_be64(map, off + sizeof(ghdr) + sizeof(be16))); + return true; +} + struct gossmap_chan *gossmap_nth_chan(const struct gossmap *map, const struct gossmap_node *node, u32 n, diff --git a/common/gossmap.h b/common/gossmap.h index 09a6c2602..5db8a693b 100644 --- a/common/gossmap.h +++ b/common/gossmap.h @@ -111,6 +111,11 @@ static inline bool gossmap_chan_set(const struct gossmap_chan *chan, int dir) return chan->half[dir].htlc_max != 0; } +/* Return capacity if it's known (fails only on race condition) */ +bool gossmap_chan_get_capacity(const struct gossmap *map, + const struct gossmap_chan *c, + struct amount_sat *amount); + /* Get the announcement msg which created this chan */ u8 *gossmap_chan_get_announce(const tal_t *ctx, const struct gossmap *map, diff --git a/common/test/run-gossmap_local.c b/common/test/run-gossmap_local.c index 548aa3c07..076489132 100644 --- a/common/test/run-gossmap_local.c +++ b/common/test/run-gossmap_local.c @@ -1,4 +1,5 @@ /* Test local modifications to gossmap */ +#include "../amount.c" #include "../fp16.c" #include "../gossmap.c" #include "../node_id.c" @@ -10,43 +11,9 @@ #include /* AUTOGENERATED MOCKS START */ -/* Generated stub for amount_asset_is_main */ -bool amount_asset_is_main(struct amount_asset *asset UNNEEDED) -{ fprintf(stderr, "amount_asset_is_main called!\n"); abort(); } -/* Generated stub for amount_asset_to_sat */ -struct amount_sat amount_asset_to_sat(struct amount_asset *asset UNNEEDED) -{ fprintf(stderr, "amount_asset_to_sat called!\n"); abort(); } -/* Generated stub for amount_sat */ -struct amount_sat amount_sat(u64 satoshis UNNEEDED) -{ fprintf(stderr, "amount_sat called!\n"); abort(); } -/* Generated stub for amount_sat_add */ - bool amount_sat_add(struct amount_sat *val UNNEEDED, - struct amount_sat a UNNEEDED, - struct amount_sat b UNNEEDED) -{ fprintf(stderr, "amount_sat_add called!\n"); abort(); } -/* Generated stub for amount_sat_eq */ -bool amount_sat_eq(struct amount_sat a UNNEEDED, struct amount_sat b UNNEEDED) -{ fprintf(stderr, "amount_sat_eq called!\n"); abort(); } -/* Generated stub for amount_sat_greater_eq */ -bool amount_sat_greater_eq(struct amount_sat a UNNEEDED, struct amount_sat b UNNEEDED) -{ fprintf(stderr, "amount_sat_greater_eq called!\n"); abort(); } -/* Generated stub for amount_sat_sub */ - bool amount_sat_sub(struct amount_sat *val UNNEEDED, - struct amount_sat a UNNEEDED, - struct amount_sat b UNNEEDED) -{ fprintf(stderr, "amount_sat_sub called!\n"); abort(); } -/* Generated stub for amount_sat_to_asset */ -struct amount_asset amount_sat_to_asset(struct amount_sat *sat UNNEEDED, const u8 *asset UNNEEDED) -{ fprintf(stderr, "amount_sat_to_asset called!\n"); abort(); } -/* Generated stub for amount_tx_fee */ -struct amount_sat amount_tx_fee(u32 fee_per_kw UNNEEDED, size_t weight UNNEEDED) -{ fprintf(stderr, "amount_tx_fee called!\n"); abort(); } /* Generated stub for fromwire */ const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED) { fprintf(stderr, "fromwire called!\n"); abort(); } -/* Generated stub for fromwire_amount_sat */ -struct amount_sat fromwire_amount_sat(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) -{ fprintf(stderr, "fromwire_amount_sat called!\n"); abort(); } /* Generated stub for fromwire_bool */ bool fromwire_bool(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_bool called!\n"); abort(); } @@ -82,9 +49,6 @@ void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr /* Generated stub for towire */ void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) { fprintf(stderr, "towire called!\n"); abort(); } -/* Generated stub for towire_amount_sat */ -void towire_amount_sat(u8 **pptr UNNEEDED, const struct amount_sat sat UNNEEDED) -{ fprintf(stderr, "towire_amount_sat called!\n"); abort(); } /* Generated stub for towire_bool */ void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) { fprintf(stderr, "towire_bool called!\n"); abort(); } @@ -335,6 +299,7 @@ int main(int argc, char *argv[]) struct short_channel_id scid23, scid12, scid_local; struct gossmap_chan *chan; struct gossmap_localmods *mods; + struct amount_sat capacity; common_setup(argv[0]); @@ -359,6 +324,12 @@ int main(int argc, char *argv[]) assert(!gossmap_find_chan(map, &scid23)->private); assert(gossmap_find_chan(map, &scid12)); assert(gossmap_find_chan(map, &scid12)->private); + assert(gossmap_chan_get_capacity(map, gossmap_find_chan(map, &scid23), + &capacity)); + assert(amount_sat_eq(capacity, AMOUNT_SAT(1000000))); + assert(gossmap_chan_get_capacity(map, gossmap_find_chan(map, &scid12), + &capacity)); + assert(amount_sat_eq(capacity, AMOUNT_SAT(1000000))); /* Now, let's add a new channel l1 -> l4. */ mods = gossmap_localmods_new(tmpctx);