Files
palladum-lightning/common/coin_mvt.h
Rusty Russell 194febe873 wallet: generate fixup chainmoves and channelmoves when first starting.
If we don't have an accountdb from bookkeeper:

1. Generate a deposit chain event for every confirmed UTXO.
2. Generate an open chain event for every open, confirmed channel.
3. Generate a push/lease event if necessary.
4. Generate a fixup "journal" entry if balance is different from initial.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-19 13:37:50 +09:30

351 lines
10 KiB
C

#ifndef LIGHTNING_COMMON_COIN_MVT_H
#define LIGHTNING_COMMON_COIN_MVT_H
#include "config.h"
#include <bitcoin/tx.h>
#include <common/amount.h>
#include <common/channel_id.h>
#include <common/utils.h>
#define COIN_MVT_VERSION 2
#define ACCOUNT_NAME_WALLET "wallet"
#define ACCOUNT_NAME_EXTERNAL "external"
/* /!\ You cannot change this order, it's committed to the db! /!\ */
enum mvt_tag {
MVT_DEPOSIT = 0,
MVT_WITHDRAWAL = 1,
MVT_PENALTY = 2,
MVT_INVOICE = 3,
MVT_ROUTED = 4,
MVT_PUSHED = 5,
MVT_CHANNEL_OPEN = 6,
MVT_CHANNEL_CLOSE = 7,
MVT_CHANNEL_TO_US = 8,
MVT_HTLC_TIMEOUT = 9,
MVT_HTLC_FULFILL = 10,
MVT_HTLC_TX = 11,
MVT_TO_WALLET = 12,
MVT_ANCHOR = 13,
MVT_TO_THEM = 14,
MVT_PENALIZED = 15,
MVT_STOLEN = 16,
MVT_TO_MINER = 17,
MVT_OPENER = 18,
MVT_LEASE_FEE = 19,
MVT_LEASED = 20,
MVT_STEALABLE = 21,
MVT_CHANNEL_PROPOSED = 22,
MVT_SPLICE = 23,
MVT_PENALTY_ADJ = 24,
MVT_JOURNAL = 25,
MVT_FOREIGN = 26,
#define NUM_MVT_TAGS (MVT_FOREIGN + 1)
};
struct mvt_tags {
u64 bits;
};
enum coin_mvt_dir {
COIN_CREDIT = 1,
COIN_DEBIT = 2,
};
struct channel_coin_mvt_id {
/* multi-part payments may share a payment hash,
* so we should also record part-id and group-id for them */
u64 part_id;
u64 group_id;
};
/* Only one of these is set. */
struct mvt_account_id {
const struct channel *channel;
const char *alt_account;
};
struct channel_coin_mvt {
/* Common fields */
struct mvt_account_id account;
struct mvt_tags tags;
/* only one or the other */
struct amount_msat credit;
struct amount_msat debit;
u64 timestamp;
/* identifier */
const struct sha256 *payment_hash;
/* multi-part payments may share a payment hash,
* so we should also record part-id and group-id for them */
const struct channel_coin_mvt_id *part_and_group;
/* Fees collected (or paid) on this mvt */
struct amount_msat fees;
};
struct chain_coin_mvt {
/* account_id */
struct mvt_account_id account;
struct mvt_tags tags;
/* only one or the other */
struct amount_msat credit;
struct amount_msat debit;
u64 timestamp;
struct bitcoin_outpoint outpoint;
const struct bitcoin_txid *spending_txid;
/* The id of the peer we have this channel with.
* Only on our channel_open events */
const struct node_id *peer_id;
/* some on-chain movements have a payment hash */
const struct sha256 *payment_hash;
/* block this transaction is confirmed in */
u32 blockheight;
/* total value of output (useful for tracking external outs) */
struct amount_sat output_val;
/* When we pay to external accounts, it's useful
* to track which internal account it originated from */
const struct mvt_account_id *originating_acct;
/* Number of outputs in spending tx; used by the
* `channel_close` event */
u32 output_count;
};
/* 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;
}
/* Add a tag */
void mvt_tag_set(struct mvt_tags *tags, enum mvt_tag tag);
/* Extract the primary tag */
enum mvt_tag primary_mvt_tag(struct mvt_tags tags);
/* Useful for assertions */
bool mvt_tags_valid(struct mvt_tags 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,
const struct channel *channel,
const char *account_name TAKES);
/* Allocating version */
struct mvt_account_id *new_mvt_account_id(const tal_t *ctx,
const struct channel *channel,
const char *account_name TAKES);
/* Either part_id and group_id both NULL, or neither are */
struct channel_coin_mvt *new_channel_coin_mvt(const tal_t *ctx,
const struct channel *channel,
u64 timestamp,
const struct sha256 *payment_hash TAKES,
const u64 *part_id,
const u64 *group_id,
enum coin_mvt_dir direction,
struct amount_msat amount,
struct mvt_tags tags,
struct amount_msat fees)
NON_NULL_ARGS(2);
struct chain_coin_mvt *new_onchaind_withdraw(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
const struct bitcoin_txid *spend_txid,
u32 blockheight,
struct amount_sat amount,
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,
struct mvt_tags tags)
NON_NULL_ARGS(2);
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx,
const struct channel *channel,
const char *alt_account,
const struct bitcoin_txid *txid,
const struct bitcoin_outpoint *out,
u32 blockheight,
const struct amount_msat amount,
const struct amount_sat output_val,
u32 output_count,
bool is_splice)
NON_NULL_ARGS(4, 5);
struct chain_coin_mvt *new_coin_channel_open_proposed(const tal_t *ctx,
const struct channel *channel,
const struct bitcoin_outpoint *out,
const struct node_id *peer_id,
const struct amount_msat amount,
const struct amount_sat output_val,
bool is_opener,
bool is_leased)
NON_NULL_ARGS(2, 3, 4);
struct chain_coin_mvt *new_coin_channel_open(const tal_t *ctx,
const struct channel *channel,
const struct bitcoin_outpoint *out,
const struct node_id *peer_id,
u32 blockheight,
const struct amount_msat amount,
const struct amount_sat output_val,
bool is_opener,
bool is_leased)
NON_NULL_ARGS(2, 3, 4);
struct chain_coin_mvt *new_onchain_htlc_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
const struct sha256 *payment_hash)
NON_NULL_ARGS(2, 5);
struct chain_coin_mvt *new_onchain_htlc_withdraw(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
const struct sha256 *payment_hash)
NON_NULL_ARGS(2, 5);
struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
struct mvt_tags tags)
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,
struct mvt_tags tags)
NON_NULL_ARGS(2, 3);
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,
struct mvt_tags tags)
NON_NULL_ARGS(2, 3);
struct chain_coin_mvt *new_coin_external_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
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,
struct mvt_tags tags)
NON_NULL_ARGS(2);
/* FIXME: Does not set originating_acct, caller must do that! */
struct chain_coin_mvt *new_foreign_deposit(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
u32 blockheight,
struct amount_sat amount,
const char *account,
u64 timestamp)
NON_NULL_ARGS(2, 5);
struct chain_coin_mvt *new_foreign_withdrawal(const tal_t *ctx,
const struct bitcoin_outpoint *outpoint,
const struct bitcoin_txid *spend_txid,
struct amount_sat amount,
u32 blockheight,
const char *account,
u64 timestamp)
NON_NULL_ARGS(2, 3, 6);
/* Generic versions (prefer the above ones: these are for migrations) */
struct channel_coin_mvt *new_channel_coin_mvt_general(const tal_t *ctx,
const struct channel *channel,
const struct channel_id *cid,
u64 timestamp,
const struct sha256 *payment_hash TAKES,
const u64 *part_id,
const u64 *group_id,
enum coin_mvt_dir direction,
struct amount_msat amount,
struct mvt_tags tags,
struct amount_msat fees);
struct chain_coin_mvt *new_coin_channel_open_general(const tal_t *ctx,
const struct channel *channel,
const struct channel_id *cid,
u64 timestamp,
const struct bitcoin_outpoint *out,
const struct node_id *peer_id,
u32 blockheight,
const struct amount_msat amount,
const struct amount_sat output_val,
bool is_opener,
bool is_leased);
struct channel_coin_mvt *new_coin_channel_push_general(const tal_t *ctx,
const struct channel *channel,
const struct channel_id *cid,
u64 timestamp,
enum coin_mvt_dir direction,
struct amount_msat amount,
struct mvt_tags tags);
/* There are three standard accounts:
* "wallet" for our internal wallet,
* "external" for other bitcoin sources,
* <channelid> for lightning channels.
*
* Exactly one of these is true:
*/
static inline bool is_wallet_account(const char *acctname)
{
return streq(acctname, ACCOUNT_NAME_WALLET);
}
static inline bool is_external_account(const char *acctname)
{
return streq(acctname, ACCOUNT_NAME_EXTERNAL);
}
static inline bool is_channel_account(const char *acctname)
{
return !is_wallet_account(acctname) && !is_external_account(acctname);
}
/* 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, 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);
void towire_chain_coin_mvt(u8 **pptr, const struct chain_coin_mvt *mvt);
void fromwire_chain_coin_mvt(const u8 **cursor, size_t *max, struct chain_coin_mvt *mvt);
#endif /* LIGHTNING_COMMON_COIN_MVT_H */