coin-moves: when a splice confirms, send a channel_closed event

We weren't properly notifying that a channel output has been spent in
the case of it being spent in a splice. This fixes the notification side
of the equation, however there's still some issues remaining for the
bookkeeper side (to come).

Changelog-Fixed: We now send a `coin_movement` notification for splice confirmations of channel funding outpoint spends.
This commit is contained in:
niftynei 2024-08-06 00:11:47 -05:00 committed by ShahanaFarooqui
parent 89f01f13fc
commit 7b3a4799db
8 changed files with 77 additions and 16 deletions

View file

@ -40,6 +40,7 @@ static const char *mvt_tags[] = {
"leased",
"stealable",
"channel_proposed",
"splice",
};
const char *mvt_tag_str(enum mvt_tag tag)
@ -177,19 +178,31 @@ struct chain_coin_mvt *new_onchaind_deposit(const tal_t *ctx,
}
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx,
const struct channel_id *chan_id,
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)
u32 output_count,
bool is_splice)
{
return new_chain_coin_mvt(ctx, NULL, txid,
struct chain_coin_mvt *mvt;
enum mvt_tag *tags = new_tag_arr(NULL, CHANNEL_CLOSE);
if (is_splice)
tal_arr_expand(&tags, SPLICE);
mvt = new_chain_coin_mvt(ctx, NULL, txid,
out, NULL, blockheight,
take(new_tag_arr(NULL, CHANNEL_CLOSE)),
take(tags),
amount, false,
output_val,
output_count);
if (chan_id)
mvt->account_name = fmt_channel_id(mvt, chan_id);
return mvt;
}
struct chain_coin_mvt *new_coin_channel_open_proposed(const tal_t *ctx,

View file

@ -14,7 +14,7 @@ enum mvt_type {
CHANNEL_MVT = 1,
};
#define NUM_MVT_TAGS (CHANNEL_PROPOSED + 1)
#define NUM_MVT_TAGS (SPLICE + 1)
enum mvt_tag {
DEPOSIT = 0,
WITHDRAWAL = 1,
@ -40,6 +40,7 @@ enum mvt_tag {
LEASED = 21,
STEALABLE = 22,
CHANNEL_PROPOSED = 23,
SPLICE = 24,
};
struct channel_coin_mvt {
@ -181,13 +182,15 @@ struct chain_coin_mvt *new_onchaind_deposit(const tal_t *ctx,
NON_NULL_ARGS(2);
struct chain_coin_mvt *new_coin_channel_close(const tal_t *ctx,
const struct channel_id *chan_id,
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)
NON_NULL_ARGS(2, 3);
u32 output_count,
bool is_splice)
NON_NULL_ARGS(3, 4);
struct chain_coin_mvt *new_coin_channel_open_proposed(const tal_t *ctx,
const struct channel_id *chan_id,

View file

@ -912,6 +912,27 @@ static void handle_update_inflight(struct lightningd *ld,
wallet_inflight_save(ld->wallet, inflight);
}
static void channel_record_splice(struct channel *channel,
struct amount_msat orig_our_msats,
struct amount_sat orig_funding_sats,
struct bitcoin_outpoint *funding,
u32 blockheight, struct bitcoin_txid *txid, const struct channel_inflight *inflight)
{
struct chain_coin_mvt *mvt;
u32 output_count;
output_count = inflight->funding_psbt->num_outputs;
mvt = new_coin_channel_close(tmpctx, &channel->cid,
txid,
funding,
blockheight,
orig_our_msats,
orig_funding_sats,
output_count,
/* is_splice = */true);
notify_chain_mvt(channel->peer->ld, mvt);
}
void channel_record_open(struct channel *channel, u32 blockheight, bool record_push)
{
struct chain_coin_mvt *mvt;
@ -1039,7 +1060,9 @@ bool channel_on_channel_ready(struct channel *channel,
static void handle_peer_splice_locked(struct channel *channel, const u8 *msg)
{
struct amount_sat funding_sats;
struct amount_sat funding_sats, prev_funding_sats;
struct amount_msat prev_our_msats;
struct bitcoin_outpoint prev_funding_out;
s64 splice_amnt;
struct channel_inflight *inflight;
struct bitcoin_txid locked_txid;
@ -1054,16 +1077,22 @@ static void handle_peer_splice_locked(struct channel *channel, const u8 *msg)
return;
}
channel->our_msat.millisatoshis += splice_amnt * 1000; /* Raw: splicing */
channel->msat_to_us_min.millisatoshis += splice_amnt * 1000; /* Raw: splicing */
channel->msat_to_us_max.millisatoshis += splice_amnt * 1000; /* Raw: splicing */
inflight = channel_inflight_find(channel, &locked_txid);
if(!inflight)
channel_internal_error(channel, "Unable to load inflight for"
" locked_txid %s",
fmt_bitcoin_txid(tmpctx, &locked_txid));
/* Stash prev funding data so we can log it after scid is updated
* (to get the blockheight) */
prev_our_msats = channel->our_msat;
prev_funding_sats = channel->funding_sats;
prev_funding_out = channel->funding;
channel->our_msat.millisatoshis += splice_amnt * 1000; /* Raw: splicing */
channel->msat_to_us_min.millisatoshis += splice_amnt * 1000; /* Raw: splicing */
channel->msat_to_us_max.millisatoshis += splice_amnt * 1000; /* Raw: splicing */
wallet_htlcsigs_confirm_inflight(channel->peer->ld->wallet, channel,
&inflight->funding->outpoint);
@ -1085,6 +1114,16 @@ static void handle_peer_splice_locked(struct channel *channel, const u8 *msg)
/* That freed watchers in inflights: now watch funding tx */
channel_watch_funding(channel->peer->ld, channel);
/* Log that funding output has been spent */
channel_record_splice(channel,
prev_our_msats,
prev_funding_sats,
&prev_funding_out,
channel->scid ?
short_channel_id_blocknum(*channel->scid) : 0,
&locked_txid,
inflight);
/* Put the successful inflight back in as a memory-only object.
* peer_control's funding_spent function will pick this up and clean up
* our inflight.

View file

@ -3463,14 +3463,15 @@ int main(int argc, char *argv[])
FUNDING_OUTPUT, NULL, NULL, NULL);
/* Record funding output spent */
send_coin_mvt(take(new_coin_channel_close(NULL, &tx->txid,
send_coin_mvt(take(new_coin_channel_close(NULL, NULL, &tx->txid,
&funding, tx_blockheight,
our_msat,
funding_sats,
is_elements(chainparams) ?
/* Minus 1, fee output */
tal_count(tx->outputs) - 1 :
tal_count(tx->outputs))));
tal_count(tx->outputs),
/* is_splice? */ false)));
status_debug("Remote per-commit point: %s",
fmt_pubkey(tmpctx, &remote_per_commit_point));

View file

@ -103,12 +103,14 @@ void memleak_status_broken(void *unused UNNEEDED, const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "memleak_status_broken 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_id *chan_id UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED,
const struct bitcoin_outpoint *out UNNEEDED,
u32 blockheight UNNEEDED,
const struct amount_msat amount UNNEEDED,
const struct amount_sat output_val UNNEEDED,
u32 output_count)
u32 output_count UNNEEDED,
bool is_splice)
{ fprintf(stderr, "new_coin_channel_close called!\n"); abort(); }
/* Generated stub for new_coin_external_deposit */

View file

@ -153,12 +153,14 @@ void memleak_status_broken(void *unused UNNEEDED, const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "memleak_status_broken 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_id *chan_id UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED,
const struct bitcoin_outpoint *out UNNEEDED,
u32 blockheight UNNEEDED,
const struct amount_msat amount UNNEEDED,
const struct amount_sat output_val UNNEEDED,
u32 output_count)
u32 output_count UNNEEDED,
bool is_splice)
{ fprintf(stderr, "new_coin_channel_close called!\n"); abort(); }
/* Generated stub for new_coin_external_deposit */

View file

@ -1294,6 +1294,7 @@ void maybe_update_account(struct db *db,
case TO_MINER:
case LEASE_FEE:
case STEALABLE:
case SPLICE:
/* Ignored */
break;
}

View file

@ -1002,7 +1002,7 @@ void topology_add_sync_waiter_(const tal_t *ctx UNNEEDED,
u8 *towire_announcement_signatures(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, struct short_channel_id short_channel_id UNNEEDED, const secp256k1_ecdsa_signature *node_signature UNNEEDED, const secp256k1_ecdsa_signature *bitcoin_signature UNNEEDED)
{ fprintf(stderr, "towire_announcement_signatures called!\n"); abort(); }
/* Generated stub for towire_channel_reestablish */
u8 *towire_channel_reestablish(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u64 next_commitment_number UNNEEDED, u64 next_revocation_number UNNEEDED, const struct secret *your_last_per_commitment_secret UNNEEDED, const struct pubkey *my_current_per_commitment_point UNNEEDED, const struct tlv_channel_reestablish_tlvs *channel_reestablish UNNEEDED)
u8 *towire_channel_reestablish(const tal_t *ctx UNNEEDED, const struct channel_id *channel_id UNNEEDED, u64 next_commitment_number UNNEEDED, u64 next_revocation_number UNNEEDED, const struct secret *your_last_per_commitment_secret UNNEEDED, const struct pubkey *my_current_per_commitment_point UNNEEDED, const struct tlv_channel_reestablish_tlvs *tlvs UNNEEDED)
{ fprintf(stderr, "towire_channel_reestablish called!\n"); abort(); }
/* Generated stub for towire_channeld_dev_memleak */
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)