coin_mvt: use bitmap instead of tal_arr for tags.
What changed, and why it matters
This commit is a straightforward internal refactoring: it replaces a variable-length list of text labels (called a 'tal_arr') with a compact 64-bit bitmap (a 'struct mvt_tags') for tracking coin-movement tags. The change touches many call sites but does not alter what the tags mean, how money moves, or any security boundary. It is not a security fix and introduces no obvious vulnerability.
No security action required. Treat as normal code-review item; verify that the new bitmap covers all existing tags and that the wire-format change is compatible with the intended database schema.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors the coin-movement (coin_mvt) subsystem to store movement tags as a u64 bitfield (struct mvt_tags) instead of a tal-allocated enum array. It removes helpers such as new_tag_arr, check_tags, and mvt_tag_is_primary in favor of PRIMARY_TAG_BITS, tag_set, mvt_tags_valid, tag_to_mvt_tags, and mk_mvt_tags. Wire serialization changes from a length-prefixed u8 array to a single u64. A new unit test verifies that the PRIMARY_TAG_BITS bitmap matches the old primary-tag classification. All call sites are mechanically updated. No security-relevant behavior is changed.
Changed components
common/coin_mvt.ccommon/coin_mvt.hcommon/test/run-coin_mvt.clightningd/chaintopology.clightningd/channel_control.clightningd/coin_mvts.clightningd/onchain_control.conchaind/onchaind.conchaind/test/run-grind_feerate-bug.conchaind/test/run-grind_feerate.cwallet/test/run-db.cwallet/test/run-wallet.cwallet/wallet.cwallet/walletrpc.cInspect captured patch +427 / −342
diff --git a/common/coin_mvt.c b/common/coin_mvt.c
index 5c7142fd..ca8f69a4 100644
--- a/common/coin_mvt.c
+++ b/common/coin_mvt.c
@@ -36,80 +36,50 @@ static const char *mvt_tags[] = {
"splice",
};
-static bool mvt_tag_is_primary(enum mvt_tag tag)
-{
- switch (tag) {
- case MVT_DEPOSIT:
- return true;
- case MVT_WITHDRAWAL:
- return true;
- case MVT_PENALTY:
- return true;
- case MVT_INVOICE:
- return true;
- case MVT_ROUTED:
- return true;
- case MVT_PUSHED:
- return true;
- case MVT_CHANNEL_OPEN:
- return true;
- case MVT_CHANNEL_CLOSE:
- return true;
- case MVT_CHANNEL_TO_US:
- return true;
- case MVT_HTLC_TIMEOUT:
- return true;
- case MVT_HTLC_FULFILL:
- return true;
- case MVT_HTLC_TX:
- return true;
- case MVT_TO_WALLET:
- return true;
- case MVT_ANCHOR:
- return true;
- case MVT_TO_THEM:
- return true;
- case MVT_PENALIZED:
- return true;
- case MVT_STOLEN:
- return true;
- case MVT_TO_MINER:
- return true;
- case MVT_OPENER:
- return false;
- case MVT_LEASE_FEE:
- return true;
- case MVT_LEASED:
- return false;
- case MVT_STEALABLE:
- return false;
- case MVT_CHANNEL_PROPOSED:
- return true;
- case MVT_SPLICE:
- return false;
- }
- abort();
-}
+#define PRIMARY_TAG_BITS ((1ULL << MVT_DEPOSIT) | \
+ (1ULL << MVT_WITHDRAWAL) | \
+ (1ULL << MVT_PENALTY) | \
+ (1ULL << MVT_INVOICE) | \
+ (1ULL << MVT_ROUTED) | \
+ (1ULL << MVT_PUSHED) | \
+ (1ULL << MVT_CHANNEL_OPEN) | \
+ (1ULL << MVT_CHANNEL_CLOSE) | \
+ (1ULL << MVT_CHANNEL_TO_US) | \
+ (1ULL << MVT_HTLC_TIMEOUT) | \
+ (1ULL << MVT_HTLC_FULFILL) | \
+ (1ULL << MVT_HTLC_TX) | \
+ (1ULL << MVT_TO_WALLET) | \
+ (1ULL << MVT_ANCHOR) | \
+ (1ULL << MVT_TO_THEM) | \
+ (1ULL << MVT_PENALIZED) | \
+ (1ULL << MVT_STOLEN) | \
+ (1ULL << MVT_TO_MINER) | \
+ (1ULL << MVT_LEASE_FEE) | \
+ (1ULL << MVT_CHANNEL_PROPOSED))
const char *mvt_tag_str(enum mvt_tag tag)
{
return mvt_tags[tag];
}
-enum mvt_tag *new_tag_arr(const tal_t *ctx, enum mvt_tag tag)
+static void tag_set(struct mvt_tags *tags, enum mvt_tag tag)
{
- enum mvt_tag *tags = tal_arr(ctx, enum mvt_tag, 1);
- assert(mvt_tag_is_primary(tag));
- tags[0] = tag;
- return tags;
+ u64 bitnum = tag;
+ assert(bitnum < NUM_MVT_TAGS);
+ /* Not already set! */
+ assert((tags->bits & (1ULL << bitnum)) == 0);
+ tags->bits |= (1ULL << bitnum);
}
-static void check_tags(const enum mvt_tag *tags)
+static bool mvt_tags_valid(struct mvt_tags tags)
{
- assert(tal_count(tags) > 0);
- assert(mvt_tag_is_primary(tags[0]));
- for (size_t i = 1; i < tal_count(tags); i++)
- assert(!mvt_tag_is_primary(tags[i]));
+ u64 primaries = (tags.bits & PRIMARY_TAG_BITS);
+ /* Must have exactly one primary. */
+ if (!primaries)
+ return false;
+ if ((primaries & (primaries - 1)) != 0)
+ return false;
+ return tags.bits < (1ULL << NUM_MVT_TAGS);
}
void set_mvt_account_id(struct mvt_account_id *acct_id,
@@ -143,11 +113,12 @@ struct channel_coin_mvt *new_channel_coin_mvt(const tal_t *ctx,
const u64 *group_id,
enum coin_mvt_dir direction,
struct amount_msat amount,
- const enum mvt_tag *tags TAKES,
+ struct mvt_tags tags,
struct amount_msat fees)
{
struct channel_coin_mvt *mvt = tal(ctx, struct channel_coin_mvt);
+ assert(mvt_tags_valid(tags));
set_mvt_account_id(&mvt->account, channel, NULL);
mvt->payment_hash = tal_dup_or_null(mvt, struct sha256, payment_hash);
if (!part_id) {
@@ -161,9 +132,7 @@ struct channel_coin_mvt *new_channel_coin_mvt(const tal_t *ctx,
pg->group_id = *group_id;
}
- check_tags(tags);
- mvt->tags = tal_dup_talarr(mvt, enum mvt_tag, tags);
-
+ mvt->tags = tags;
mvt->fees = fees;
switch (direction) {
case COIN_CREDIT:
@@ -186,7 +155,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
const struct sha256 *payment_hash TAKES,
u32 blockheight,
- enum mvt_tag *tags,
+ struct mvt_tags tags,
enum coin_mvt_dir direction,
struct amount_msat amount,
struct amount_sat output_val,
@@ -194,6 +163,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt(const tal_t *ctx,
{
struct chain_coin_mvt *mvt = tal(ctx, struct chain_coin_mvt);
+ assert(mvt_tags_valid(tags));
set_mvt_account_id(&mvt->account, channel, account_name);
mvt->tx_txid = tx_txid;
mvt->outpoint = outpoint;
@@ -207,9 +177,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt(const tal_t *ctx,
mvt->payment_hash = tal_dup_or_null(mvt, struct sha256, payment_hash);
mvt->blockheight = blockheight;
- check_tags(tags);
- mvt->tags = tal_dup_talarr(mvt, enum mvt_tag, tags);
-
+ mvt->tags = tags;
mvt->output_val = output_val;
mvt->output_count = out_count;
@@ -233,7 +201,7 @@ static struct chain_coin_mvt *new_chain_coin_mvt_sat(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
const struct sha256 *payment_hash TAKES,
u32 blockheight,
- enum mvt_tag *tags TAKES,
+ struct mvt_tags tags,
enum coin_mvt_dir direction,
struct amount_sat amt_sat)
{
@@ -255,12 +223,12 @@ struct chain_coin_mvt *new_onchaind_withdraw(const tal_t *ctx,
const struct bitcoin_txid *spend_txid,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
return new_chain_coin_mvt_sat(ctx, NULL, "", spend_txid,
outpoint, NULL,
blockheight,
- take(new_tag_arr(NULL, tag)),
+ tags,
COIN_DEBIT, amount);
}
@@ -268,12 +236,12 @@ struct chain_coin_mvt *new_onchaind_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
return new_chain_coin_mvt_sat(ctx, NULL, "", NULL,
outpoint, NULL,
blockheight,
- take(new_tag_arr(NULL, tag)),
+ tags,
COIN_CREDIT, amount);
}
@@ -289,14 +257,16 @@ struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx,
bool is_splice)
{
struct chain_coin_mvt *mvt;
- enum mvt_tag *tags = new_tag_arr(NULL, MVT_CHANNEL_CLOSE);
+ struct mvt_tags tags;
if (is_splice)
- tal_arr_expand(&tags, MVT_SPLICE);
+ tags = mk_mvt_tags(MVT_CHANNEL_CLOSE, MVT_SPLICE);
+ else
+ tags = mk_mvt_tags(MVT_CHANNEL_CLOSE);
mvt = new_chain_coin_mvt(ctx, channel, alt_account, txid,
out, NULL, blockheight,
- take(tags),
+ tags,
COIN_DEBIT, amount,
output_val,
output_count);
@@ -313,18 +283,19 @@ struct chain_coin_mvt *new_coin_channel_open_proposed(const tal_t *ctx,
bool is_leased)
{
struct chain_coin_mvt *mvt;
-
- mvt = new_chain_coin_mvt(ctx, channel, NULL, NULL, out, NULL, 0,
- take(new_tag_arr(NULL, MVT_CHANNEL_PROPOSED)),
- COIN_CREDIT, amount, output_val, 0);
- mvt->peer_id = tal_dup(mvt, struct node_id, peer_id);
+ struct mvt_tags tags = tag_to_mvt_tags(MVT_CHANNEL_PROPOSED);
/* If we're the opener, add to the tag list */
if (is_opener)
- tal_arr_expand(&mvt->tags, MVT_OPENER);
+ tag_set(&tags, MVT_OPENER);
if (is_leased)
- tal_arr_expand(&mvt->tags, MVT_LEASED);
+ tag_set(&tags, MVT_LEASED);
+
+ mvt = new_chain_coin_mvt(ctx, channel, NULL, NULL, out, NULL, 0,
+ tags,
+ COIN_CREDIT, amount, output_val, 0);
+ mvt->peer_id = tal_dup(mvt, struct node_id, peer_id);
return mvt;
}
@@ -340,19 +311,20 @@ struct chain_coin_mvt *new_coin_channel_open(const tal_t *ctx,
bool is_leased)
{
struct chain_coin_mvt *mvt;
-
- mvt = new_chain_coin_mvt(ctx, channel, NULL, NULL, out, NULL, blockheight,
- take(new_tag_arr(NULL, MVT_CHANNEL_OPEN)),
- COIN_CREDIT, amount,
- output_val, 0);
- mvt->peer_id = tal_dup(mvt, struct node_id, peer_id);
+ struct mvt_tags tags = tag_to_mvt_tags(MVT_CHANNEL_OPEN);
/* If we're the opener, add to the tag list */
if (is_opener)
- tal_arr_expand(&mvt->tags, MVT_OPENER);
+ tag_set(&tags, MVT_OPENER);
if (is_leased)
- tal_arr_expand(&mvt->tags, MVT_LEASED);
+ tag_set(&tags, MVT_LEASED);
+
+ mvt = new_chain_coin_mvt(ctx, channel, NULL, NULL, out, NULL, blockheight,
+ tags,
+ COIN_CREDIT, amount,
+ output_val, 0);
+ mvt->peer_id = tal_dup(mvt, struct node_id, peer_id);
return mvt;
}
@@ -366,7 +338,7 @@ struct chain_coin_mvt *new_onchain_htlc_deposit(const tal_t *ctx,
return new_chain_coin_mvt_sat(ctx, NULL, "", NULL,
outpoint, payment_hash,
blockheight,
- take(new_tag_arr(NULL, MVT_HTLC_FULFILL)),
+ tag_to_mvt_tags(MVT_HTLC_FULFILL),
COIN_CREDIT, amount);
}
@@ -382,55 +354,31 @@ struct chain_coin_mvt *new_onchain_htlc_withdraw(const tal_t *ctx,
return new_chain_coin_mvt_sat(ctx, NULL, EXTERNAL, NULL,
outpoint, payment_hash,
blockheight,
- take(new_tag_arr(NULL, MVT_HTLC_FULFILL)),
+ tag_to_mvt_tags(MVT_HTLC_FULFILL),
COIN_CREDIT, amount);
}
-struct chain_coin_mvt *new_coin_external_spend_tags(const tal_t *ctx,
- const struct bitcoin_outpoint *outpoint,
- const struct bitcoin_txid *txid,
- u32 blockheight,
- struct amount_sat amount,
- enum mvt_tag *tags TAKES)
-{
- return new_chain_coin_mvt(ctx, NULL, EXTERNAL, txid,
- outpoint, NULL, blockheight,
- take(tags),
- COIN_CREDIT, AMOUNT_MSAT(0), amount, 0);
-}
-
struct chain_coin_mvt *new_coin_external_spend(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
const struct bitcoin_txid *txid,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
-{
- return new_coin_external_spend_tags(ctx, outpoint,
- txid, blockheight, amount,
- new_tag_arr(NULL, tag));
-}
-
-struct chain_coin_mvt *new_coin_external_deposit_tags(const tal_t *ctx,
- const struct bitcoin_outpoint *outpoint,
- u32 blockheight,
- struct amount_sat amount,
- enum mvt_tag *tags TAKES)
+ struct mvt_tags tags)
{
- return new_chain_coin_mvt_sat(ctx, NULL, EXTERNAL, NULL, outpoint, NULL,
- blockheight, take(tags),
- COIN_CREDIT, amount);
+ return new_chain_coin_mvt(ctx, NULL, EXTERNAL, txid,
+ outpoint, NULL, blockheight,
+ tags,
+ COIN_CREDIT, AMOUNT_MSAT(0), amount, 0);
}
-
struct chain_coin_mvt *new_coin_external_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
return new_chain_coin_mvt_sat(ctx, NULL, EXTERNAL, NULL, outpoint, NULL,
- blockheight, take(new_tag_arr(NULL, tag)),
+ blockheight, tags,
COIN_CREDIT, amount);
}
@@ -443,24 +391,11 @@ struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
-{
- return new_chain_coin_mvt_sat(ctx, NULL, WALLET, NULL,
- outpoint, NULL,
- blockheight, take(new_tag_arr(NULL, tag)),
- COIN_CREDIT, amount);
-}
-
-struct chain_coin_mvt *new_coin_wallet_deposit_tagged(const tal_t *ctx,
- const struct bitcoin_outpoint *outpoint,
- u32 blockheight,
- struct amount_sat amount,
- enum mvt_tag *tags TAKES)
+ struct mvt_tags tags)
{
return new_chain_coin_mvt_sat(ctx, NULL, WALLET, NULL,
outpoint, NULL,
- blockheight,
- take(tags),
+ blockheight, tags,
COIN_CREDIT, amount);
}
@@ -469,11 +404,11 @@ struct chain_coin_mvt *new_coin_wallet_withdraw(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
return new_chain_coin_mvt_sat(ctx, NULL, WALLET, spend_txid,
outpoint, NULL,
- blockheight, take(new_tag_arr(NULL, tag)),
+ blockheight, tags,
COIN_DEBIT, amount);
}
@@ -481,23 +416,34 @@ struct channel_coin_mvt *new_coin_channel_push(const tal_t *ctx,
const struct channel *channel,
enum coin_mvt_dir direction,
struct amount_msat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
return new_channel_coin_mvt(ctx, channel, NULL,
NULL, NULL, direction, amount,
- take(new_tag_arr(NULL, tag)),
+ tags,
AMOUNT_MSAT(0));
}
-const char **mvt_tag_strs(const tal_t *ctx, const enum mvt_tag *tags)
+const char **mvt_tag_strs(const tal_t *ctx, struct mvt_tags tags)
{
- const char **strs = tal_arr(ctx, const char *, 0);
- for (size_t i = 0; i < tal_count(tags); i++)
- tal_arr_expand(&strs, mvt_tag_str(tags[i]));
+ const char **strs = tal_arr(ctx, const char *, 1);
+
+ /* There must be exactly one primary */
+ assert(mvt_tags_valid(tags));
+
+ /* We put the *primary* tag first */
+ for (size_t i = 0; i < NUM_MVT_TAGS; i++) {
+ u64 bit = (u64)1 << i;
+ if ((bit & tags.bits) == 0)
+ continue;
+ if (bit & PRIMARY_TAG_BITS)
+ strs[0] = mvt_tag_str(i);
+ else
+ tal_arr_expand(&strs, mvt_tag_str(i));
+ }
return strs;
}
-
/* Parse a single mvt tag. Returns false or populates *tag */
bool mvt_tag_parse(const char *buf, size_t len, enum mvt_tag *tag)
{
@@ -534,10 +480,7 @@ void towire_chain_coin_mvt(u8 **pptr, const struct chain_coin_mvt *mvt)
towire_bool(pptr, false);
towire_u32(pptr, mvt->blockheight);
- towire_u32(pptr, tal_count(mvt->tags));
- for (size_t i = 0; i < tal_count(mvt->tags); i++)
- towire_u8(pptr, mvt->tags[i]);
-
+ towire_u64(pptr, mvt->tags.bits);
towire_amount_msat(pptr, mvt->credit);
towire_amount_msat(pptr, mvt->debit);
towire_amount_sat(pptr, mvt->output_val);
@@ -576,11 +519,7 @@ void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_m
mvt->payment_hash = NULL;
mvt->blockheight = fromwire_u32(cursor, max);
- u32 tags_len = fromwire_u32(cursor, max);
- mvt->tags = tal_arr(mvt, enum mvt_tag, tags_len);
- for (size_t i = 0; i < tags_len; i++)
- mvt->tags[i] = fromwire_u8(cursor, max);
-
+ mvt->tags.bits = fromwire_u64(cursor, max);
mvt->credit = fromwire_amount_msat(cursor, max);
mvt->debit = fromwire_amount_msat(cursor, max);
mvt->output_val = fromwire_amount_sat(cursor, max);
@@ -593,3 +532,16 @@ void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_m
} else
mvt->peer_id = NULL;
}
+
+struct mvt_tags mk_mvt_tags_(enum mvt_tag tag, ...)
+{
+ va_list ap;
+ struct mvt_tags ret = { 0 };
+
+ tag_set(&ret, tag);
+ va_start(ap, tag);
+ while ((tag = va_arg(ap, enum mvt_tag)) != 999)
+ tag_set(&ret, tag);
+ va_end(ap);
+ return ret;
+}
diff --git a/common/coin_mvt.h b/common/coin_mvt.h
index 821333d9..2a59b619 100644
--- a/common/coin_mvt.h
+++ b/common/coin_mvt.h
@@ -37,6 +37,10 @@ enum mvt_tag {
#define NUM_MVT_TAGS (MVT_SPLICE + 1)
};
+struct mvt_tags {
+ u64 bits;
+};
+
enum coin_mvt_dir {
COIN_CREDIT = 1,
COIN_DEBIT = 2,
@@ -58,7 +62,7 @@ struct mvt_account_id {
struct channel_coin_mvt {
/* Common fields */
struct mvt_account_id account;
- enum mvt_tag *tags;
+ struct mvt_tags tags;
/* only one or the other */
struct amount_msat credit;
struct amount_msat debit;
@@ -77,7 +81,7 @@ struct channel_coin_mvt {
struct chain_coin_mvt {
/* account_id */
struct mvt_account_id account;
- enum mvt_tag *tags;
+ struct mvt_tags tags;
/* only one or the other */
struct amount_msat credit;
struct amount_msat debit;
@@ -107,7 +111,16 @@ struct chain_coin_mvt {
u32 output_count;
};
-enum mvt_tag *new_tag_arr(const tal_t *ctx, enum mvt_tag tag);
+/* Convenience macro for creating tag bitmaps */
+#define mk_mvt_tags(...) mk_mvt_tags_(__VA_ARGS__, 999)
+struct mvt_tags mk_mvt_tags_(enum mvt_tag tag, ...);
+
+static inline struct mvt_tags tag_to_mvt_tags(enum mvt_tag tag)
+{
+ struct mvt_tags tags;
+ tags.bits = ((u64)1) << tag;
+ return tags;
+}
/* Useful constructor for mvt_account_id: exactly one of channel/account_name must be NULL */
void set_mvt_account_id(struct mvt_account_id *acct_id,
@@ -127,7 +140,7 @@ struct channel_coin_mvt *new_channel_coin_mvt(const tal_t *ctx,
const u64 *group_id,
enum coin_mvt_dir direction,
struct amount_msat amount,
- const enum mvt_tag *tags TAKES,
+ struct mvt_tags tags,
struct amount_msat fees)
NON_NULL_ARGS(2);
@@ -136,14 +149,14 @@ struct chain_coin_mvt *new_onchaind_withdraw(const tal_t *ctx,
const struct bitcoin_txid *spend_txid,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
NON_NULL_ARGS(2, 3);
struct chain_coin_mvt *new_onchaind_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
NON_NULL_ARGS(2);
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx,
@@ -197,30 +210,16 @@ struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
NON_NULL_ARGS(2);
-struct chain_coin_mvt *new_coin_wallet_deposit_tagged(const tal_t *ctx,
- const struct bitcoin_outpoint *outpoint,
- u32 blockheight,
- struct amount_sat amount,
- enum mvt_tag *tags TAKES)
- NON_NULL_ARGS(2);
struct chain_coin_mvt *new_coin_wallet_withdraw(const tal_t *ctx,
const struct bitcoin_txid *spend_txid,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
- NON_NULL_ARGS(2, 3);
-
-struct chain_coin_mvt *new_coin_external_spend_tags(const tal_t *ctx,
- const struct bitcoin_outpoint *outpoint,
- const struct bitcoin_txid *txid,
- u32 blockheight,
- struct amount_sat amount,
- enum mvt_tag *tags)
+ struct mvt_tags tags)
NON_NULL_ARGS(2, 3);
struct chain_coin_mvt *new_coin_external_spend(const tal_t *ctx,
@@ -228,35 +227,28 @@ struct chain_coin_mvt *new_coin_external_spend(const tal_t *ctx,
const struct bitcoin_txid *txid,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
NON_NULL_ARGS(2, 3);
-struct chain_coin_mvt *new_coin_external_deposit_tags(const tal_t *ctx,
- const struct bitcoin_outpoint *outpoint,
- u32 blockheight,
- struct amount_sat amount,
- enum mvt_tag *tags)
- NON_NULL_ARGS(2, 5);
-
struct chain_coin_mvt *new_coin_external_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
NON_NULL_ARGS(2);
struct channel_coin_mvt *new_coin_channel_push(const tal_t *ctx,
const struct channel *channel,
enum coin_mvt_dir direction,
struct amount_msat amount,
- enum mvt_tag tag)
+ struct mvt_tags tags)
NON_NULL_ARGS(2);
/* Is this an xternal account? */
bool chain_mvt_is_external(const struct chain_coin_mvt *mvt);
const char *mvt_tag_str(enum mvt_tag tag);
-const char **mvt_tag_strs(const tal_t *ctx, const enum mvt_tag *tags);
+const char **mvt_tag_strs(const tal_t *ctx, struct mvt_tags tags);
/* Parse a single mvt tag. Returns false or populates *tag */
bool mvt_tag_parse(const char *buf, size_t len, enum mvt_tag *tag);
diff --git a/common/test/run-coin_mvt.c b/common/test/run-coin_mvt.c
new file mode 100644
index 00000000..9cf998e9
--- /dev/null
+++ b/common/test/run-coin_mvt.c
@@ -0,0 +1,194 @@
+#include "config.h"
+#include "../coin_mvt.c"
+#include <ccan/tal/str/str.h>
+#include <common/setup.h>
+#include <stdio.h>
+
+/* 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_feerate */
+ bool amount_feerate(u32 *feerate UNNEEDED, struct amount_sat fee UNNEEDED, size_t weight UNNEEDED)
+{ fprintf(stderr, "amount_feerate 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_sat_to_msat */
+ bool amount_sat_to_msat(struct amount_msat *msat UNNEEDED,
+ struct amount_sat sat UNNEEDED)
+{ fprintf(stderr, "amount_sat_to_msat 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_msat */
+struct amount_msat fromwire_amount_msat(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
+{ fprintf(stderr, "fromwire_amount_msat 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(); }
+/* Generated stub for fromwire_fail */
+void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
+{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
+/* Generated stub for fromwire_node_id */
+void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED)
+{ fprintf(stderr, "fromwire_node_id called!\n"); abort(); }
+/* Generated stub for fromwire_secp256k1_ecdsa_signature */
+void fromwire_secp256k1_ecdsa_signature(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
+ secp256k1_ecdsa_signature *signature UNNEEDED)
+{ fprintf(stderr, "fromwire_secp256k1_ecdsa_signature called!\n"); abort(); }
+/* Generated stub for fromwire_sha256 */
+void fromwire_sha256(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct sha256 *sha256 UNNEEDED)
+{ fprintf(stderr, "fromwire_sha256 called!\n"); abort(); }
+/* Generated stub for fromwire_tal_arrn */
+u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
+ const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
+{ fprintf(stderr, "fromwire_tal_arrn called!\n"); abort(); }
+/* Generated stub for fromwire_u32 */
+u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
+{ fprintf(stderr, "fromwire_u32 called!\n"); abort(); }
+/* Generated stub for fromwire_u64 */
+u64 fromwire_u64(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
+{ fprintf(stderr, "fromwire_u64 called!\n"); abort(); }
+/* Generated stub for fromwire_u8 */
+u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
+{ fprintf(stderr, "fromwire_u8 called!\n"); abort(); }
+/* Generated stub for fromwire_u8_array */
+void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
+{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
+/* Generated stub for fromwire_wirestring */
+char *fromwire_wirestring(const tal_t *ctx UNNEEDED, const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
+{ fprintf(stderr, "fromwire_wirestring called!\n"); abort(); }
+/* 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_msat */
+void towire_amount_msat(u8 **pptr UNNEEDED, const struct amount_msat msat UNNEEDED)
+{ fprintf(stderr, "towire_amount_msat 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(); }
+/* Generated stub for towire_node_id */
+void towire_node_id(u8 **pptr UNNEEDED, const struct node_id *id UNNEEDED)
+{ fprintf(stderr, "towire_node_id called!\n"); abort(); }
+/* Generated stub for towire_secp256k1_ecdsa_signature */
+void towire_secp256k1_ecdsa_signature(u8 **pptr UNNEEDED,
+ const secp256k1_ecdsa_signature *signature UNNEEDED)
+{ fprintf(stderr, "towire_secp256k1_ecdsa_signature called!\n"); abort(); }
+/* Generated stub for towire_sha256 */
+void towire_sha256(u8 **pptr UNNEEDED, const struct sha256 *sha256 UNNEEDED)
+{ fprintf(stderr, "towire_sha256 called!\n"); abort(); }
+/* Generated stub for towire_u32 */
+void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
+{ fprintf(stderr, "towire_u32 called!\n"); abort(); }
+/* Generated stub for towire_u64 */
+void towire_u64(u8 **pptr UNNEEDED, u64 v UNNEEDED)
+{ fprintf(stderr, "towire_u64 called!\n"); abort(); }
+/* Generated stub for towire_u8 */
+void towire_u8(u8 **pptr UNNEEDED, u8 v UNNEEDED)
+{ fprintf(stderr, "towire_u8 called!\n"); abort(); }
+/* Generated stub for towire_u8_array */
+void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED)
+{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
+/* Generated stub for towire_wirestring */
+void towire_wirestring(u8 **pptr UNNEEDED, const char *str UNNEEDED)
+{ fprintf(stderr, "towire_wirestring called!\n"); abort(); }
+/* AUTOGENERATED MOCKS END */
+
+static bool mvt_tag_is_primary(enum mvt_tag tag)
+{
+ switch (tag) {
+ case MVT_DEPOSIT:
+ return true;
+ case MVT_WITHDRAWAL:
+ return true;
+ case MVT_PENALTY:
+ return true;
+ case MVT_INVOICE:
+ return true;
+ case MVT_ROUTED:
+ return true;
+ case MVT_PUSHED:
+ return true;
+ case MVT_CHANNEL_OPEN:
+ return true;
+ case MVT_CHANNEL_CLOSE:
+ return true;
+ case MVT_CHANNEL_TO_US:
+ return true;
+ case MVT_HTLC_TIMEOUT:
+ return true;
+ case MVT_HTLC_FULFILL:
+ return true;
+ case MVT_HTLC_TX:
+ return true;
+ case MVT_TO_WALLET:
+ return true;
+ case MVT_ANCHOR:
+ return true;
+ case MVT_TO_THEM:
+ return true;
+ case MVT_PENALIZED:
+ return true;
+ case MVT_STOLEN:
+ return true;
+ case MVT_TO_MINER:
+ return true;
+ case MVT_OPENER:
+ return false;
+ case MVT_LEASE_FEE:
+ return true;
+ case MVT_LEASED:
+ return false;
+ case MVT_STEALABLE:
+ return false;
+ case MVT_CHANNEL_PROPOSED:
+ return true;
+ case MVT_SPLICE:
+ return false;
+ }
+ abort();
+}
+
+int main(int argc, char *argv[])
+{
+ common_setup(argv[0]);
+ for (size_t i = 0; i < NUM_MVT_TAGS; i++) {
+ if (mvt_tag_is_primary(i))
+ assert((1ULL << i) & PRIMARY_TAG_BITS);
+ else
+ assert(((1ULL << i) & PRIMARY_TAG_BITS) == 0);
+ }
+ common_shutdown();
+}
diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c
index 3735d629..dd22ccad 100644
--- a/lightningd/chaintopology.c
+++ b/lightningd/chaintopology.c
@@ -882,7 +882,7 @@ static void record_wallet_spend(struct lightningd *ld,
notify_chain_mvt(ld, new_coin_wallet_withdraw(tmpctx, txid, outpoint,
tx_blockheight,
- utxo->amount, MVT_WITHDRAWAL));
+ utxo->amount, mk_mvt_tags(MVT_WITHDRAWAL)));
}
/**
diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c
index 2273d199..93fb13ec 100644
--- a/lightningd/channel_control.c
+++ b/lightningd/channel_control.c
@@ -1030,7 +1030,9 @@ void channel_record_open(struct channel *channel, u32 blockheight, bool record_p
new_coin_channel_push(tmpctx, channel,
channel->opener == REMOTE ? COIN_CREDIT : COIN_DEBIT,
channel->push,
- is_leased ? MVT_LEASE_FEE : MVT_PUSHED));
+ is_leased
+ ? mk_mvt_tags(MVT_LEASE_FEE)
+ : mk_mvt_tags(MVT_PUSHED)));
}
void lockin_has_completed(struct channel *channel, bool record_push)
diff --git a/lightningd/coin_mvts.c b/lightningd/coin_mvts.c
index 2b70cfec..68bf42d9 100644
--- a/lightningd/coin_mvts.c
+++ b/lightningd/coin_mvts.c
@@ -13,7 +13,7 @@ struct channel_coin_mvt *new_channel_mvt_invoice_hin(const tal_t *ctx,
return new_channel_coin_mvt(ctx, channel,
&hin->payment_hash, NULL, NULL,
COIN_CREDIT, hin->msat,
- new_tag_arr(ctx, MVT_INVOICE),
+ mk_mvt_tags(MVT_INVOICE),
AMOUNT_MSAT(0));
}
@@ -33,7 +33,7 @@ struct channel_coin_mvt *new_channel_mvt_routed_hin(const tal_t *ctx,
return new_channel_coin_mvt(ctx, channel,
&hin->payment_hash, NULL, NULL,
COIN_CREDIT, hin->msat,
- new_tag_arr(ctx, MVT_ROUTED),
+ mk_mvt_tags(MVT_ROUTED),
fees_collected);
}
@@ -46,7 +46,7 @@ struct channel_coin_mvt *new_channel_mvt_invoice_hout(const tal_t *ctx,
&hout->partid,
&hout->groupid,
COIN_DEBIT, hout->msat,
- new_tag_arr(ctx, MVT_INVOICE),
+ mk_mvt_tags(MVT_INVOICE),
hout->fees);
}
@@ -57,7 +57,7 @@ struct channel_coin_mvt *new_channel_mvt_routed_hout(const tal_t *ctx,
return new_channel_coin_mvt(ctx, channel,
&hout->payment_hash, NULL, NULL,
COIN_DEBIT, hout->msat,
- new_tag_arr(ctx, MVT_ROUTED),
+ mk_mvt_tags(MVT_ROUTED),
hout->fees);
}
diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c
index 7310b8a4..e536e532 100644
--- a/lightningd/onchain_control.c
+++ b/lightningd/onchain_control.c
@@ -578,7 +578,7 @@ static void onchain_add_utxo(struct channel *channel, const u8 *msg)
csv_lock);
mvt = new_coin_wallet_deposit(msg, &outpoint, blockheight,
- amount, MVT_DEPOSIT);
+ amount, mk_mvt_tags(MVT_DEPOSIT));
mvt->originating_acct = new_mvt_account_id(mvt, channel, NULL);
notify_chain_mvt(channel->peer->ld, mvt);
diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c
index c23c42a3..bafa101d 100644
--- a/onchaind/onchaind.c
+++ b/onchaind/onchaind.c
@@ -225,55 +225,36 @@ static void send_coin_mvt(struct chain_coin_mvt *mvt TAKES)
static void record_channel_withdrawal(const struct bitcoin_txid *tx_txid,
struct tracked_output *out,
u32 blockheight,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
send_coin_mvt(take(new_onchaind_withdraw(NULL, &out->outpoint, tx_txid,
- blockheight, out->sat, tag)));
+ blockheight, out->sat, tags)));
}
static void record_external_spend(const struct bitcoin_txid *txid,
struct tracked_output *out,
u32 blockheight,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
send_coin_mvt(take(new_coin_external_spend(NULL, &out->outpoint,
txid, blockheight,
- out->sat, tag)));
-}
-
-static void record_external_spend_tags(const struct bitcoin_txid *txid,
- struct tracked_output *out,
- u32 blockheight,
- enum mvt_tag *tags TAKES)
-{
- send_coin_mvt(take(new_coin_external_spend_tags(NULL, &out->outpoint,
- txid, blockheight,
- out->sat, tags)));
+ out->sat, tags)));
}
static void record_external_output(const struct bitcoin_outpoint *out,
struct amount_sat amount,
u32 blockheight,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
send_coin_mvt(take(new_coin_external_deposit(NULL, out, blockheight,
- amount, tag)));
+ amount, tags)));
}
static void record_external_deposit(const struct tracked_output *out,
u32 blockheight,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{
- record_external_output(&out->outpoint, out->sat, blockheight, tag);
-}
-
-static void record_external_deposit_tags(const struct tracked_output *out,
- u32 blockheight,
- enum mvt_tag *tags TAKES)
-{
- send_coin_mvt(take(new_coin_external_deposit_tags(NULL, &out->outpoint,
- blockheight, out->sat,
- tags)));
+ record_external_output(&out->outpoint, out->sat, blockheight, tags);
}
static void record_mutual_close(const struct tx_parts *tx,
@@ -295,19 +276,19 @@ static void record_mutual_close(const struct tx_parts *tx,
record_external_output(&out,
amount_sat(tx->outputs[i]->satoshi),
blockheight,
- MVT_TO_THEM);
+ mk_mvt_tags(MVT_TO_THEM));
break;
}
}
static void record_channel_deposit(struct tracked_output *out,
- u32 blockheight, enum mvt_tag tag)
+ u32 blockheight, struct mvt_tags tags)
{
send_coin_mvt(take(new_onchaind_deposit(NULL,
&out->outpoint,
blockheight, out->sat,
- tag)));
+ tags)));
}
static void record_to_us_htlc_fulfilled(struct tracked_output *out,
@@ -339,7 +320,7 @@ static void record_our_anchor(struct tracked_output *out)
* it can be spent by anyone after 16 blocks. Our
* implementation doesn't ever spend it unless it needs to
* boost, so it's fair to record it as going "external". */
- record_external_deposit(out, out->tx_blockheight, MVT_ANCHOR);
+ record_external_deposit(out, out->tx_blockheight, mk_mvt_tags(MVT_ANCHOR));
}
static void record_coin_movements(struct tracked_output *out,
@@ -355,10 +336,10 @@ static void record_coin_movements(struct tracked_output *out,
* AND so we can accurately calculate our on-chain fee burden */
if (out->tx_type == OUR_HTLC_TIMEOUT_TX
|| out->tx_type == OUR_HTLC_SUCCESS_TX)
- record_channel_deposit(out, out->tx_blockheight, MVT_HTLC_TX);
+ record_channel_deposit(out, out->tx_blockheight, mk_mvt_tags(MVT_HTLC_TX));
if (out->resolved->tx_type == OUR_HTLC_TIMEOUT_TO_US)
- record_channel_deposit(out, out->tx_blockheight, MVT_HTLC_TIMEOUT);
+ record_channel_deposit(out, out->tx_blockheight, mk_mvt_tags(MVT_HTLC_TIMEOUT));
/* there is a case where we've fulfilled an htlc onchain,
* in which case we log a deposit to the channel */
@@ -371,20 +352,20 @@ static void record_coin_movements(struct tracked_output *out,
if (out->tx_type == OUR_UNILATERAL) {
if (out->output_type == DELAYED_OUTPUT_TO_US)
record_channel_deposit(out, out->tx_blockheight,
- MVT_CHANNEL_TO_US);
+ mk_mvt_tags(MVT_CHANNEL_TO_US));
else if (out->output_type == OUR_HTLC) {
record_channel_deposit(out, out->tx_blockheight,
- MVT_HTLC_TIMEOUT);
+ mk_mvt_tags(MVT_HTLC_TIMEOUT));
record_channel_withdrawal(txid, out, blockheight,
- MVT_HTLC_TIMEOUT);
+ mk_mvt_tags(MVT_HTLC_TIMEOUT));
} else if (out->output_type == THEIR_HTLC)
record_channel_withdrawal(txid, out, blockheight,
- MVT_HTLC_FULFILL);
+ mk_mvt_tags(MVT_HTLC_FULFILL));
}
if (out->tx_type == THEIR_REVOKED_UNILATERAL
|| out->resolved->tx_type == OUR_PENALTY_TX)
- record_channel_deposit(out, out->tx_blockheight, MVT_PENALTY);
+ record_channel_deposit(out, out->tx_blockheight, mk_mvt_tags(MVT_PENALTY));
if (out->resolved->tx_type == OUR_DELAYED_RETURN_TO_WALLET
|| out->resolved->tx_type == THEIR_HTLC_FULFILL_TO_US
@@ -393,9 +374,9 @@ static void record_coin_movements(struct tracked_output *out,
|| out->resolved->tx_type == OUR_PENALTY_TX) {
/* penalty rbf cases, the amount might be zero */
if (amount_sat_is_zero(out->sat))
- record_channel_withdrawal(txid, out, blockheight, MVT_TO_MINER);
+ record_channel_withdrawal(txid, out, blockheight, mk_mvt_tags(MVT_TO_MINER));
else
- record_channel_withdrawal(txid, out, blockheight, MVT_TO_WALLET);
+ record_channel_withdrawal(txid, out, blockheight, mk_mvt_tags(MVT_TO_WALLET));
}
}
@@ -1229,24 +1210,19 @@ static bool output_spent(struct tracked_output ***outs,
case DELAYED_OUTPUT_TO_US:
unknown_spend(out, tx_parts);
record_external_deposit(out, out->tx_blockheight,
- MVT_PENALIZED);
+ mk_mvt_tags(MVT_PENALIZED));
break;
case THEIR_HTLC:
if (out->tx_type == THEIR_REVOKED_UNILATERAL) {
- enum mvt_tag *tags;
- tags = new_tag_arr(NULL, MVT_HTLC_TIMEOUT);
- tal_arr_expand(&tags, MVT_STEALABLE);
-
- record_external_deposit_tags(out, out->tx_blockheight,
- /* This takes tags */
- tal_dup_talarr(NULL,
- enum mvt_tag,
- tags));
- record_external_spend_tags(&tx_parts->txid,
- out,
- tx_blockheight,
- tags);
+ struct mvt_tags tags = mk_mvt_tags(MVT_HTLC_TIMEOUT, MVT_STEALABLE);
+
+ record_external_deposit(out, out->tx_blockheight,
+ tags);
+ record_external_spend(&tx_parts->txid,
+ out,
+ tx_blockheight,
+ tags);
/* we've actually got a 'new' output here */
steal_htlc_tx(out, outs, tx_parts,
@@ -1283,13 +1259,10 @@ static bool output_spent(struct tracked_output ***outs,
record_to_them_htlc_fulfilled(out, out->tx_blockheight);
if (out->tx_type == THEIR_REVOKED_UNILATERAL) {
- enum mvt_tag *tags = new_tag_arr(NULL,
- MVT_HTLC_FULFILL);
- tal_arr_expand(&tags, MVT_STEALABLE);
- record_external_spend_tags(&tx_parts->txid,
- out,
- tx_blockheight,
- tags);
+ record_external_spend(&tx_parts->txid,
+ out,
+ tx_blockheight,
+ mk_mvt_tags(MVT_HTLC_FULFILL, MVT_STEALABLE));
steal_htlc_tx(out, outs, tx_parts,
tx_blockheight,
OUR_HTLC_FULFILL_TO_THEM,
@@ -1297,7 +1270,7 @@ static bool output_spent(struct tracked_output ***outs,
} else {
record_external_spend(&tx_parts->txid, out,
tx_blockheight,
- MVT_HTLC_FULFILL);
+ mk_mvt_tags(MVT_HTLC_FULFILL));
/* BOLT #5:
*
* ## HTLC Output Handling: Local Commitment,
@@ -1326,7 +1299,7 @@ static bool output_spent(struct tracked_output ***outs,
resolved_by_other(out, &tx_parts->txid,
THEIR_DELAYED_CHEAT);
- record_external_deposit(out, out->tx_blockheight, MVT_STOLEN);
+ record_external_deposit(out, out->tx_blockheight, mk_mvt_tags(MVT_STOLEN));
break;
/* Um, we don't track these! */
case OUTPUT_TO_THEM:
@@ -1430,7 +1403,7 @@ static void tx_new_depth(struct tracked_output **outs,
if (outs[i]->proposal->tx_type == THEIR_HTLC_TIMEOUT_TO_THEM)
record_external_deposit(outs[i], outs[i]->tx_blockheight,
- MVT_HTLC_TIMEOUT);
+ mk_mvt_tags(MVT_HTLC_TIMEOUT));
}
}
}
@@ -2310,7 +2283,7 @@ static void handle_our_unilateral(const struct tx_parts *tx,
OUTPUT_TO_THEM,
NULL, NULL, NULL);
ignore_output(out);
- record_external_deposit(out, tx_blockheight, MVT_TO_THEM);
+ record_external_deposit(out, tx_blockheight, mk_mvt_tags(MVT_TO_THEM));
script[REMOTE] = NULL;
continue;
}
@@ -2339,7 +2312,7 @@ static void handle_our_unilateral(const struct tx_parts *tx,
ANCHOR_TO_THEM,
NULL, NULL, NULL);
ignore_output(out);
- record_external_deposit(out, tx_blockheight, MVT_ANCHOR);
+ record_external_deposit(out, tx_blockheight, mk_mvt_tags(MVT_ANCHOR));
anchor[REMOTE] = NULL;
continue;
}
@@ -2413,7 +2386,7 @@ static void handle_our_unilateral(const struct tx_parts *tx,
ignore_output(out);
record_external_deposit(out,
tx_blockheight,
- MVT_TO_THEM);
+ mk_mvt_tags(MVT_TO_THEM));
script[REMOTE] = NULL;
found = true;
break;
@@ -2428,7 +2401,7 @@ static void handle_our_unilateral(const struct tx_parts *tx,
record_external_output(&outpoint, amt,
tx_blockheight,
- MVT_PENALTY);
+ mk_mvt_tags(MVT_PENALTY));
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not find resolution for output %zu",
i);
@@ -2823,7 +2796,7 @@ static void handle_their_cheat(const struct tx_parts *tx,
ANCHOR_TO_THEM,
NULL, NULL, NULL);
ignore_output(out);
- record_external_deposit(out, tx_blockheight, MVT_ANCHOR);
+ record_external_deposit(out, tx_blockheight, mk_mvt_tags(MVT_ANCHOR));
anchor[REMOTE] = NULL;
continue;
}
@@ -2893,7 +2866,7 @@ static void handle_their_cheat(const struct tx_parts *tx,
if (!found) {
record_external_output(&outpoint, amt,
tx_blockheight,
- MVT_PENALTY);
+ mk_mvt_tags(MVT_PENALTY));
status_broken("Could not find resolution"
" for output %zu: did"
" *we* cheat?", i);
@@ -3120,7 +3093,7 @@ static void handle_their_unilateral(const struct tx_parts *tx,
DELAYED_OUTPUT_TO_THEM,
NULL, NULL, NULL);
ignore_output(out);
- record_external_deposit(out, tx_blockheight, MVT_TO_THEM);
+ record_external_deposit(out, tx_blockheight, mk_mvt_tags(MVT_TO_THEM));
continue;
}
if (anchor[LOCAL]
@@ -3150,7 +3123,7 @@ static void handle_their_unilateral(const struct tx_parts *tx,
NULL, NULL, NULL);
ignore_output(out);
anchor[REMOTE] = NULL;
- record_external_deposit(out, tx_blockheight, MVT_ANCHOR);
+ record_external_deposit(out, tx_blockheight, mk_mvt_tags(MVT_ANCHOR));
continue;
}
@@ -3215,7 +3188,7 @@ static void handle_their_unilateral(const struct tx_parts *tx,
ignore_output(out);
record_external_deposit(out,
tx_blockheight,
- MVT_TO_THEM);
+ mk_mvt_tags(MVT_TO_THEM));
found = true;
break;
}
@@ -3226,7 +3199,7 @@ static void handle_their_unilateral(const struct tx_parts *tx,
record_external_output(&outpoint, amt,
tx_blockheight,
- MVT_PENALTY);
+ mk_mvt_tags(MVT_PENALTY));
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not find resolution for output %zu",
i);
@@ -3362,7 +3335,7 @@ found:
record_external_output(&outpoint, amt,
tx_blockheight,
- MVT_PENALTY);
+ mk_mvt_tags(MVT_PENALTY));
}
if (to_us_output == -1) {
diff --git a/onchaind/test/run-grind_feerate-bug.c b/onchaind/test/run-grind_feerate-bug.c
index ab686613..539fb088 100644
--- a/onchaind/test/run-grind_feerate-bug.c
+++ b/onchaind/test/run-grind_feerate-bug.c
@@ -101,6 +101,9 @@ struct htable *memleak_start(const tal_t *ctx UNNEEDED)
/* Generated stub for memleak_status_broken */
void memleak_status_broken(void *unused UNNEEDED, const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); }
+/* Generated stub for mk_mvt_tags_ */
+struct mvt_tags mk_mvt_tags_(enum mvt_tag tag UNNEEDED, ...)
+{ fprintf(stderr, "mk_mvt_tags_ called!\n"); abort(); }
/* Generated stub for new_coin_channel_close */
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx UNNEEDED,
const struct channel *channel UNNEEDED,
@@ -119,43 +122,26 @@ struct chain_coin_mvt *new_coin_external_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_coin_external_deposit called!\n"); abort(); }
-/* Generated stub for new_coin_external_deposit_tags */
-struct chain_coin_mvt *new_coin_external_deposit_tags(const tal_t *ctx UNNEEDED,
- const struct bitcoin_outpoint *outpoint UNNEEDED,
- u32 blockheight UNNEEDED,
- struct amount_sat amount UNNEEDED,
- enum mvt_tag *tags)
-
-{ fprintf(stderr, "new_coin_external_deposit_tags called!\n"); abort(); }
/* Generated stub for new_coin_external_spend */
struct chain_coin_mvt *new_coin_external_spend(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_coin_external_spend called!\n"); abort(); }
-/* Generated stub for new_coin_external_spend_tags */
-struct chain_coin_mvt *new_coin_external_spend_tags(const tal_t *ctx UNNEEDED,
- const struct bitcoin_outpoint *outpoint UNNEEDED,
- const struct bitcoin_txid *txid UNNEEDED,
- u32 blockheight UNNEEDED,
- struct amount_sat amount UNNEEDED,
- enum mvt_tag *tags)
-
-{ fprintf(stderr, "new_coin_external_spend_tags called!\n"); abort(); }
-/* Generated stub for new_coin_wallet_deposit_tagged */
-struct chain_coin_mvt *new_coin_wallet_deposit_tagged(const tal_t *ctx UNNEEDED,
- const struct bitcoin_outpoint *outpoint UNNEEDED,
- u32 blockheight UNNEEDED,
- struct amount_sat amount UNNEEDED,
- enum mvt_tag *tags TAKES)
+/* Generated stub for new_coin_wallet_deposit */
+struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
+ const struct bitcoin_outpoint *outpoint UNNEEDED,
+ u32 blockheight UNNEEDED,
+ struct amount_sat amount UNNEEDED,
+ struct mvt_tags tags)
-{ fprintf(stderr, "new_coin_wallet_deposit_tagged called!\n"); abort(); }
+{ fprintf(stderr, "new_coin_wallet_deposit called!\n"); abort(); }
/* Generated stub for new_onchain_htlc_deposit */
struct chain_coin_mvt *new_onchain_htlc_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
@@ -177,7 +163,7 @@ struct chain_coin_mvt *new_onchaind_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_onchaind_deposit called!\n"); abort(); }
/* Generated stub for new_onchaind_withdraw */
@@ -186,12 +172,9 @@ struct chain_coin_mvt *new_onchaind_withdraw(const tal_t *ctx UNNEEDED,
const struct bitcoin_txid *spend_txid UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_onchaind_withdraw called!\n"); abort(); }
-/* Generated stub for new_tag_arr */
-enum mvt_tag *new_tag_arr(const tal_t *ctx UNNEEDED, enum mvt_tag tag UNNEEDED)
-{ fprintf(stderr, "new_tag_arr called!\n"); abort(); }
/* Generated stub for notleak_ */
void *notleak_(void *ptr UNNEEDED, bool plus_children UNNEEDED)
{ fprintf(stderr, "notleak_ called!\n"); abort(); }
diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c
index cb944889..ae942288 100644
--- a/onchaind/test/run-grind_feerate.c
+++ b/onchaind/test/run-grind_feerate.c
@@ -151,6 +151,9 @@ struct htable *memleak_start(const tal_t *ctx UNNEEDED)
/* Generated stub for memleak_status_broken */
void memleak_status_broken(void *unused UNNEEDED, const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "memleak_status_broken called!\n"); abort(); }
+/* Generated stub for mk_mvt_tags_ */
+struct mvt_tags mk_mvt_tags_(enum mvt_tag tag UNNEEDED, ...)
+{ fprintf(stderr, "mk_mvt_tags_ called!\n"); abort(); }
/* Generated stub for new_coin_channel_close */
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx UNNEEDED,
const struct channel *channel UNNEEDED,
@@ -169,43 +172,26 @@ struct chain_coin_mvt *new_coin_external_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_coin_external_deposit called!\n"); abort(); }
-/* Generated stub for new_coin_external_deposit_tags */
-struct chain_coin_mvt *new_coin_external_deposit_tags(const tal_t *ctx UNNEEDED,
- const struct bitcoin_outpoint *outpoint UNNEEDED,
- u32 blockheight UNNEEDED,
- struct amount_sat amount UNNEEDED,
- enum mvt_tag *tags)
-
-{ fprintf(stderr, "new_coin_external_deposit_tags called!\n"); abort(); }
/* Generated stub for new_coin_external_spend */
struct chain_coin_mvt *new_coin_external_spend(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_coin_external_spend called!\n"); abort(); }
-/* Generated stub for new_coin_external_spend_tags */
-struct chain_coin_mvt *new_coin_external_spend_tags(const tal_t *ctx UNNEEDED,
- const struct bitcoin_outpoint *outpoint UNNEEDED,
- const struct bitcoin_txid *txid UNNEEDED,
- u32 blockheight UNNEEDED,
- struct amount_sat amount UNNEEDED,
- enum mvt_tag *tags)
-
-{ fprintf(stderr, "new_coin_external_spend_tags called!\n"); abort(); }
-/* Generated stub for new_coin_wallet_deposit_tagged */
-struct chain_coin_mvt *new_coin_wallet_deposit_tagged(const tal_t *ctx UNNEEDED,
- const struct bitcoin_outpoint *outpoint UNNEEDED,
- u32 blockheight UNNEEDED,
- struct amount_sat amount UNNEEDED,
- enum mvt_tag *tags TAKES)
+/* Generated stub for new_coin_wallet_deposit */
+struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
+ const struct bitcoin_outpoint *outpoint UNNEEDED,
+ u32 blockheight UNNEEDED,
+ struct amount_sat amount UNNEEDED,
+ struct mvt_tags tags)
-{ fprintf(stderr, "new_coin_wallet_deposit_tagged called!\n"); abort(); }
+{ fprintf(stderr, "new_coin_wallet_deposit called!\n"); abort(); }
/* Generated stub for new_onchain_htlc_deposit */
struct chain_coin_mvt *new_onchain_htlc_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
@@ -227,7 +213,7 @@ struct chain_coin_mvt *new_onchaind_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_onchaind_deposit called!\n"); abort(); }
/* Generated stub for new_onchaind_withdraw */
@@ -236,12 +222,9 @@ struct chain_coin_mvt *new_onchaind_withdraw(const tal_t *ctx UNNEEDED,
const struct bitcoin_txid *spend_txid UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_onchaind_withdraw called!\n"); abort(); }
-/* Generated stub for new_tag_arr */
-enum mvt_tag *new_tag_arr(const tal_t *ctx UNNEEDED, enum mvt_tag tag UNNEEDED)
-{ fprintf(stderr, "new_tag_arr called!\n"); abort(); }
/* Generated stub for notleak_ */
void *notleak_(void *ptr UNNEEDED, bool plus_children UNNEEDED)
{ fprintf(stderr, "notleak_ called!\n"); abort(); }
diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c
index c8cfb8f5..a75d099e 100644
--- a/wallet/test/run-db.c
+++ b/wallet/test/run-db.c
@@ -164,6 +164,9 @@ void logv(struct logger *logger UNNEEDED, enum log_level level UNNEEDED, const s
void memleak_scan_outpointfilter(struct htable *memtable UNNEEDED,
const struct outpointfilter *opf UNNEEDED)
{ fprintf(stderr, "memleak_scan_outpointfilter called!\n"); abort(); }
+/* Generated stub for mk_mvt_tags_ */
+struct mvt_tags mk_mvt_tags_(enum mvt_tag tag UNNEEDED, ...)
+{ fprintf(stderr, "mk_mvt_tags_ called!\n"); abort(); }
/* Generated stub for new_channel */
struct channel *new_channel(struct peer *peer UNNEEDED, u64 dbid UNNEEDED,
/* NULL or stolen */
@@ -253,7 +256,7 @@ struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_coin_wallet_deposit called!\n"); abort(); }
/* Generated stub for new_inflight */
diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c
index f8bfff7b..c55cc173 100644
--- a/wallet/test/run-wallet.c
+++ b/wallet/test/run-wallet.c
@@ -652,6 +652,9 @@ void logv(struct logger *logger UNNEEDED, enum log_level level UNNEEDED, const s
void memleak_scan_outpointfilter(struct htable *memtable UNNEEDED,
const struct outpointfilter *opf UNNEEDED)
{ fprintf(stderr, "memleak_scan_outpointfilter called!\n"); abort(); }
+/* Generated stub for mk_mvt_tags_ */
+struct mvt_tags mk_mvt_tags_(enum mvt_tag tag UNNEEDED, ...)
+{ fprintf(stderr, "mk_mvt_tags_ called!\n"); abort(); }
/* Generated stub for new_channel_mvt_invoice_hin */
struct channel_coin_mvt *new_channel_mvt_invoice_hin(const tal_t *ctx UNNEEDED,
const struct htlc_in *hin UNNEEDED,
@@ -677,7 +680,7 @@ struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
u32 blockheight UNNEEDED,
struct amount_sat amount UNNEEDED,
- enum mvt_tag tag)
+ struct mvt_tags tags)
{ fprintf(stderr, "new_coin_wallet_deposit called!\n"); abort(); }
/* Generated stub for new_global_subd */
diff --git a/wallet/wallet.c b/wallet/wallet.c
index 6b2b0564..6c2819d5 100644
--- a/wallet/wallet.c
+++ b/wallet/wallet.c
@@ -3130,7 +3130,7 @@ type_ok:
mvt = new_coin_wallet_deposit(tmpctx, &utxo->outpoint,
*blockheight,
utxo->amount,
- MVT_DEPOSIT);
+ mk_mvt_tags(MVT_DEPOSIT));
notify_chain_mvt(w->ld, mvt);
}
diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c
index dc559ca5..db49c831 100644
--- a/wallet/walletrpc.c
+++ b/wallet/walletrpc.c
@@ -946,7 +946,7 @@ static void maybe_notify_new_external_send(struct lightningd *ld,
mvt = new_coin_external_deposit(NULL, &outpoint,
0, amount,
- MVT_DEPOSIT);
+ mk_mvt_tags(MVT_DEPOSIT));
mvt->originating_acct = new_mvt_account_id(mvt, NULL, WALLET);
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.