From 042d5d13f52c36f4adf47f990043accfb85b3683 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 1 Mar 2018 19:52:24 +1030 Subject: [PATCH] short_channel_id: don't use bitfields. I leave all the now-unnecessary accessors in place to avoid churn, but the use of bitfields has been more pain than help. Signed-off-by: Rusty Russell --- bitcoin/short_channel_id.c | 30 +++++++++++++---------------- bitcoin/short_channel_id.h | 38 +++++++++++++++++++++++++++++-------- lightningd/gossip_control.c | 4 +++- lightningd/pay.c | 2 +- lightningd/peer_control.c | 6 +++--- wire/fromwire.c | 10 +--------- wire/towire.c | 7 +------ 7 files changed, 52 insertions(+), 45 deletions(-) diff --git a/bitcoin/short_channel_id.c b/bitcoin/short_channel_id.c index 4085981ae2c5..44506fcfb564 100644 --- a/bitcoin/short_channel_id.c +++ b/bitcoin/short_channel_id.c @@ -3,6 +3,14 @@ #include #include +void mk_short_channel_id(struct short_channel_id *scid, + u32 blocknum, u32 txnum, u16 outnum) +{ + scid->u64 = (((u64)blocknum & 0xFFFFFF) << 40 | + ((u64)txnum & 0xFFFFFF) << 16 | + (outnum & 0xFFFF)); +} + bool short_channel_id_from_str(const char *str, size_t strlen, struct short_channel_id *dst) { @@ -15,26 +23,14 @@ bool short_channel_id_from_str(const char *str, size_t strlen, buf[strlen] = 0; matches = sscanf(buf, "%u:%u:%hu", &blocknum, &txnum, &outnum); - dst->blocknum = blocknum; - dst->txnum = txnum; - dst->outnum = outnum; + mk_short_channel_id(dst, blocknum, txnum, outnum); return matches == 3; } char *short_channel_id_to_str(const tal_t *ctx, const struct short_channel_id *scid) { - return tal_fmt(ctx, "%d:%d:%d", scid->blocknum, scid->txnum, scid->outnum); -} - -bool short_channel_id_eq(const struct short_channel_id *a, - const struct short_channel_id *b) -{ - return a->blocknum == b->blocknum && a->txnum == b->txnum && - a->outnum == b->outnum; -} - -u64 short_channel_id_to_uint(const struct short_channel_id *scid) -{ - return ((u64)scid->blocknum & 0xFFFFFF) << 40 | - ((u64)scid->txnum & 0xFFFFFF) << 16 | (scid->outnum & 0xFFFF); + return tal_fmt(ctx, "%d:%d:%d", + short_channel_id_blocknum(scid), + short_channel_id_txnum(scid), + short_channel_id_outnum(scid)); } diff --git a/bitcoin/short_channel_id.h b/bitcoin/short_channel_id.h index d0e9a346fd1c..e3278095b399 100644 --- a/bitcoin/short_channel_id.h +++ b/bitcoin/short_channel_id.h @@ -12,20 +12,42 @@ * just memset them and not have to take care about the extra byte for * u32 */ struct short_channel_id { - u32 blocknum : 24; - u32 txnum : 24; - u16 outnum; + u64 u64; }; +static inline u32 short_channel_id_blocknum(const struct short_channel_id *scid) +{ + return scid->u64 >> 40; +} + +static inline u32 short_channel_id_txnum(const struct short_channel_id *scid) +{ + return (scid->u64 >> 16) & 0x00FFFFFF; +} + +static inline u16 short_channel_id_outnum(const struct short_channel_id *scid) +{ + return scid->u64 & 0xFFFF; +} + +void mk_short_channel_id(struct short_channel_id *scid, + u32 blocknum, u32 txnum, u16 outnum); + bool short_channel_id_from_str(const char *str, size_t strlen, struct short_channel_id *dst); -bool short_channel_id_eq(const struct short_channel_id *a, - const struct short_channel_id *b); - -char *short_channel_id_to_str(const tal_t *ctx, const struct short_channel_id *scid); +static inline bool short_channel_id_eq(const struct short_channel_id *a, + const struct short_channel_id *b) +{ + return a->u64 == b->u64; +} /* Fast, platform dependent, way to convert from a short_channel_id to u64 */ -u64 short_channel_id_to_uint(const struct short_channel_id *scid); +static inline u64 short_channel_id_to_uint(const struct short_channel_id *scid) +{ + return scid->u64; +} + +char *short_channel_id_to_str(const tal_t *ctx, const struct short_channel_id *scid); #endif /* LIGHTNING_BITCOIN_SHORT_CHANNEL_ID_H */ diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 479832a7d098..0fcb068523db 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -89,7 +89,9 @@ static void get_txout(struct subd *gossip, const u8 *msg) /* FIXME: Block less than 6 deep? */ bitcoind_getoutput(gossip->ld->topology->bitcoind, - scid->blocknum, scid->txnum, scid->outnum, + short_channel_id_blocknum(scid), + short_channel_id_txnum(scid), + short_channel_id_outnum(scid), got_txout, scid); } diff --git a/lightningd/pay.c b/lightningd/pay.c index 3ba9ec75f28a..d77b8b1d6540 100644 --- a/lightningd/pay.c +++ b/lightningd/pay.c @@ -256,7 +256,7 @@ remote_routing_failure(const tal_t *ctx, const struct pubkey *erring_node; const struct short_channel_id *route_channels; const struct short_channel_id *erring_channel; - static const struct short_channel_id dummy_channel = { 0, 0, 0 }; + static const struct short_channel_id dummy_channel = { 0 }; int origin_index; bool retry_plausible; bool report_to_gossipd; diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 97bf9d84a4ec..5e566624214e 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -521,9 +521,9 @@ static enum watch_result funding_lockin_cb(struct channel *channel, /* If we restart, we could already have peer->scid from database */ if (!channel->scid) { channel->scid = tal(channel, struct short_channel_id); - channel->scid->blocknum = loc->blkheight; - channel->scid->txnum = loc->index; - channel->scid->outnum = channel->funding_outnum; + mk_short_channel_id(channel->scid, + loc->blkheight, loc->index, + channel->funding_outnum); } tal_free(loc); diff --git a/wire/fromwire.c b/wire/fromwire.c index b54f263186e6..9fa2dddad9e3 100644 --- a/wire/fromwire.c +++ b/wire/fromwire.c @@ -158,15 +158,7 @@ void fromwire_channel_id(const u8 **cursor, size_t *max, void fromwire_short_channel_id(const u8 **cursor, size_t *max, struct short_channel_id *short_channel_id) { - be32 txnum = 0, blocknum = 0; - - /* Pulling 3 bytes off wire is tricky; they're big-endian. */ - fromwire(cursor, max, (char *)&blocknum + 1, 3); - short_channel_id->blocknum = be32_to_cpu(blocknum); - fromwire(cursor, max, (char *)&txnum + 1, 3); - short_channel_id->txnum = be32_to_cpu(txnum); - - short_channel_id->outnum = fromwire_u16 (cursor, max); + short_channel_id->u64 = fromwire_u64(cursor, max); } void fromwire_sha256(const u8 **cursor, size_t *max, struct sha256 *sha256) diff --git a/wire/towire.c b/wire/towire.c index 94d9a930c1e4..564f66b9ada7 100644 --- a/wire/towire.c +++ b/wire/towire.c @@ -105,12 +105,7 @@ void towire_channel_id(u8 **pptr, const struct channel_id *channel_id) void towire_short_channel_id(u8 **pptr, const struct short_channel_id *short_channel_id) { - be32 txnum = cpu_to_be32(short_channel_id->txnum); - be32 blocknum = cpu_to_be32(short_channel_id->blocknum); - - towire(pptr, (char *)&blocknum + 1, 3); - towire(pptr, (char *)&txnum + 1, 3); - towire_u16(pptr, short_channel_id->outnum); + towire_u64(pptr, short_channel_id->u64); } void towire_sha256(u8 **pptr, const struct sha256 *sha256)