Skip to content

Commit

Permalink
lightningd: don't share funding_depth_cb for non-funding txs.
Browse files Browse the repository at this point in the history
We use the *same* callback for the funding tx, as well as for inflight dual-funding txs, as well as inflight splice txs.  This is deeply confusing!

Instead, use explicit cbs for splicing and df.  Once they're locked in, use the normal callback.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Oct 2, 2023
1 parent 1cd53ae commit 854bda8
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 84 deletions.
93 changes: 92 additions & 1 deletion lightningd/channel_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,94 @@ static void handle_splice_confirmed_signed(struct lightningd *ld,
send_splice_tx(channel, tx, cc, output_index);
}

bool depthcb_update_scid(struct channel *channel,
const struct bitcoin_txid *txid)
{
struct txlocator *loc;
struct lightningd *ld = channel->peer->ld;
struct short_channel_id scid;

/* What scid is this giving us? */
loc = wallet_transaction_locate(tmpctx, ld->wallet, txid);
if (!mk_short_channel_id(&scid,
loc->blkheight, loc->index,
channel->funding.n)) {
channel_fail_permanent(channel,
REASON_LOCAL,
"Invalid funding scid %u:%u:%u",
loc->blkheight, loc->index,
channel->funding.n);
return false;
}

if (!channel->scid) {
wallet_annotate_txout(ld->wallet, &channel->funding,
TX_CHANNEL_FUNDING, channel->dbid);
channel->scid = tal_dup(channel, struct short_channel_id, &scid);

/* If we have a zeroconf channel, i.e., no scid yet
* but have exchange `channel_ready` messages, then we
* need to fire a second time, in order to trigger the
* `coin_movement` event. This is a subset of the
* `lockin_complete` function called from
* AWAITING_LOCKIN->NORMAL otherwise. */
if (channel->minimum_depth == 0)
lockin_has_completed(channel, false);

wallet_channel_save(ld->wallet, channel);
} else if (!short_channel_id_eq(channel->scid, &scid)) {
/* We freaked out if required when original was
* removed, so just update now */
log_info(channel->log, "Short channel id changed from %s->%s",
type_to_string(tmpctx, struct short_channel_id, channel->scid),
type_to_string(tmpctx, struct short_channel_id, &scid));
*channel->scid = scid;
wallet_channel_save(ld->wallet, channel);
}

return true;
}

static enum watch_result splice_depth_cb(struct lightningd *ld,
const struct bitcoin_txid *txid,
const struct bitcoin_tx *tx,
unsigned int depth,
struct channel_inflight *inflight)
{
/* Usually, we're here because we're awaiting a splice, but
* we could also mutual shutdown, or that weird splice_locked_memonly
* hack... */
if (inflight->channel->state != CHANNELD_AWAITING_SPLICE)
return DELETE_WATCH;

/* Reorged out? OK, we're not committed yet. */
if (depth == 0)
return KEEP_WATCHING;

if (!depthcb_update_scid(inflight->channel, txid))
return DELETE_WATCH;

if (inflight->channel->owner) {
subd_send_msg(inflight->channel->owner,
take(towire_channeld_funding_depth(
NULL, inflight->channel->scid,
inflight->channel->alias[LOCAL],
depth, true, txid)));
}

/* channeld will tell us when splice is locked in: we'll clean
* this watch up then. */
return KEEP_WATCHING;
}

void watch_splice_inflight(struct lightningd *ld,
struct channel_inflight *inflight)
{
watch_txid(inflight, ld->topology,
&inflight->funding->outpoint.txid,
splice_depth_cb, inflight);
}

static void handle_add_inflight(struct lightningd *ld,
struct channel *channel,
const u8 *msg)
Expand Down Expand Up @@ -596,7 +684,7 @@ static void handle_add_inflight(struct lightningd *ld,
&inflight->funding->outpoint.txid));

wallet_inflight_add(ld->wallet, inflight);
channel_watch_inflight(ld, channel, inflight);
watch_splice_inflight(ld, inflight);

subd_send_msg(channel->owner, take(towire_channeld_got_inflight(NULL)));
}
Expand Down Expand Up @@ -830,6 +918,9 @@ static void handle_peer_splice_locked(struct channel *channel, const u8 *msg)

wallet_channel_clear_inflights(channel->peer->ld->wallet, channel);

/* That freed watchers in inflights: now watch funding tx */
channel_watch_funding(channel->peer->ld, channel);

/* 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.
Expand Down
8 changes: 8 additions & 0 deletions lightningd/channel_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,12 @@ void lockin_complete(struct channel *channel,

/* Accessor for zeroconf to tell us we've actually got an scid */
void lockin_has_completed(struct channel *channel, bool record_push);

/* Watch this incoming splice */
void watch_splice_inflight(struct lightningd *ld,
struct channel_inflight *inflight);

/* Update/set scid now this txid is mined. */
bool depthcb_update_scid(struct channel *channel,
const struct bitcoin_txid *txid);
#endif /* LIGHTNING_LIGHTNINGD_CHANNEL_CONTROL_H */
70 changes: 67 additions & 3 deletions lightningd/dual_open_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,68 @@ openchannel2_signed_deserialize(struct openchannel2_psbt_payload *payload,
return true;
}

static enum watch_result opening_depth_cb(struct lightningd *ld,
const struct bitcoin_txid *txid,
const struct bitcoin_tx *tx,
unsigned int depth,
struct channel_inflight *inflight)
{
struct txlocator *loc;
struct short_channel_id scid;

/* Usually, we're here because we're awaiting a lockin, but
* we could also mutual shutdown */
if (inflight->channel->state != DUALOPEND_AWAITING_LOCKIN)
return DELETE_WATCH;

/* Reorged out? OK, we're not committed yet. */
if (depth == 0)
return KEEP_WATCHING;

/* FIXME: Don't do this until we're actually locked in! */
loc = wallet_transaction_locate(tmpctx, ld->wallet, txid);
if (!mk_short_channel_id(&scid,
loc->blkheight, loc->index,
inflight->funding->outpoint.n)) {
channel_fail_permanent(inflight->channel,
REASON_LOCAL,
"Invalid funding scid %u:%u:%u",
loc->blkheight, loc->index,
inflight->funding->outpoint.n);
return DELETE_WATCH;
}

if (!inflight->channel->scid) {
wallet_annotate_txout(ld->wallet, &inflight->funding->outpoint,
TX_CHANNEL_FUNDING, inflight->channel->dbid);
inflight->channel->scid = tal_dup(inflight->channel, struct short_channel_id, &scid);
wallet_channel_save(ld->wallet, inflight->channel);
} else if (!short_channel_id_eq(inflight->channel->scid, &scid)) {
/* We freaked out if required when original was
* removed, so just update now */
log_info(inflight->channel->log, "Short channel id changed from %s->%s",
type_to_string(tmpctx, struct short_channel_id, inflight->channel->scid),
type_to_string(tmpctx, struct short_channel_id, &scid));
*inflight->channel->scid = scid;
wallet_channel_save(ld->wallet, inflight->channel);
}

dualopend_tell_depth(inflight->channel, txid, depth);

if (depth >= inflight->channel->minimum_depth)
update_channel_from_inflight(ld, inflight->channel, inflight);

return KEEP_WATCHING;
}

void watch_opening_inflight(struct lightningd *ld,
struct channel_inflight *inflight)
{
watch_txid(inflight, ld->topology,
&inflight->funding->outpoint.txid,
opening_depth_cb, inflight);
}

static void
openchannel2_sign_hook_cb(struct openchannel2_psbt_payload *payload STEALS)
{
Expand Down Expand Up @@ -1007,7 +1069,7 @@ openchannel2_sign_hook_cb(struct openchannel2_psbt_payload *payload STEALS)
cast_const(struct wally_psbt *,
payload->psbt));
wallet_inflight_save(payload->ld->wallet, inflight);
channel_watch_funding(payload->ld, channel);
watch_opening_inflight(payload->ld, inflight);
msg = towire_dualopend_send_tx_sigs(NULL, inflight->funding_psbt);

send_msg:
Expand Down Expand Up @@ -1835,6 +1897,9 @@ static void handle_channel_locked(struct subd *dualopend,
/* Empty out the inflights */
wallet_channel_clear_inflights(dualopend->ld->wallet, channel);

/* That freed watchers in inflights: now watch funding tx */
channel_watch_funding(dualopend->ld, channel);

/* FIXME: LND sigs/update_fee msgs? */
peer_start_channeld(channel, peer_fd, NULL, false, NULL);
return;
Expand Down Expand Up @@ -2611,8 +2676,7 @@ json_openchannel_signed(struct command *cmd,

/* Update the PSBT on disk */
wallet_inflight_save(cmd->ld->wallet, inflight);
/* Uses the channel->funding_txid, which we verified above */
channel_watch_funding(cmd->ld, channel);
watch_opening_inflight(cmd->ld, inflight);

/* Send our tx_sigs to the peer */
subd_send_msg(channel->owner,
Expand Down
3 changes: 3 additions & 0 deletions lightningd/dual_open_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ void dualopend_tell_depth(struct channel *channel,
const struct bitcoin_txid *txid,
u32 depth);

void watch_opening_inflight(struct lightningd *ld,
struct channel_inflight *inflight);

/* Close connection to an unsaved channel */
void channel_unsaved_close_conn(struct channel *channel, const char *why);

Expand Down
92 changes: 30 additions & 62 deletions lightningd/peer_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ void drop_to_chain(struct lightningd *ld, struct channel *channel,

resolve_close_command(ld, channel, cooperative, tx);
}

}

void resend_closing_transactions(struct lightningd *ld)
Expand Down Expand Up @@ -1883,9 +1882,6 @@ static enum watch_result funding_depth_cb(struct lightningd *ld,
unsigned int depth,
struct channel *channel)
{
struct short_channel_id scid;
struct txlocator *loc;

/* This is stub channel, we don't activate anything! */
if (is_stub_scid(channel->scid))
return DELETE_WATCH;
Expand Down Expand Up @@ -1954,43 +1950,8 @@ static enum watch_result funding_depth_cb(struct lightningd *ld,
return KEEP_WATCHING;
}

/* What scid is this giving us? */
loc = wallet_transaction_locate(tmpctx, ld->wallet, txid);
if (!mk_short_channel_id(&scid,
loc->blkheight, loc->index,
channel->funding.n)) {
channel_fail_permanent(channel,
REASON_LOCAL,
"Invalid funding scid %u:%u:%u",
loc->blkheight, loc->index,
channel->funding.n);
if (!depthcb_update_scid(channel, txid))
return DELETE_WATCH;
}

if (!channel->scid) {
wallet_annotate_txout(ld->wallet, &channel->funding,
TX_CHANNEL_FUNDING, channel->dbid);
channel->scid = tal_dup(channel, struct short_channel_id, &scid);

/* If we have a zeroconf channel, i.e., no scid yet
* but have exchange `channel_ready` messages, then we
* need to fire a second time, in order to trigger the
* `coin_movement` event. This is a subset of the
* `lockin_complete` function called from
* AWAITING_LOCKIN->NORMAL otherwise. */
if (channel->minimum_depth == 0)
lockin_has_completed(channel, false);

wallet_channel_save(ld->wallet, channel);
} else if (!short_channel_id_eq(channel->scid, &scid)) {
/* We freaked out if required when original was
* removed, so just update now */
log_info(channel->log, "Short channel id changed from %s->%s",
type_to_string(tmpctx, struct short_channel_id, channel->scid),
type_to_string(tmpctx, struct short_channel_id, &scid));
*channel->scid = scid;
wallet_channel_save(ld->wallet, channel);
}

/* Always tell owner about depth change */
subd_tell_depth(channel, txid, depth);
Expand Down Expand Up @@ -2115,17 +2076,6 @@ void channel_watch_funding(struct lightningd *ld, struct channel *channel)
channel_watch_wrong_funding(ld, channel);
}

void channel_watch_inflight(struct lightningd *ld,
struct channel *channel,
struct channel_inflight *inflight)
{
watch_txid(channel, ld->topology,
&inflight->funding->outpoint.txid, funding_depth_cb, channel);
watch_txo(channel, ld->topology, channel,
&inflight->funding->outpoint,
funding_spent);
}

static void json_add_peer(struct lightningd *ld,
struct json_stream *response,
struct peer *p,
Expand Down Expand Up @@ -2381,21 +2331,39 @@ static void setup_peer(struct peer *peer, u32 delay)
bool connect = false;

list_for_each(&peer->channels, channel, list) {
if (channel_state_uncommitted(channel->state))
switch (channel->state) {
case DUALOPEND_OPEN_INIT:
case DUALOPEND_OPEN_COMMITTED:
/* Nothing to watch */
continue;
/* Watching lockin may be unnecessary, but it's harmless. */
channel_watch_funding(ld, channel);

/* Also watch any inflight txs */
list_for_each(&channel->inflights, inflight, list) {
/* Don't double watch the txid that's also in
* channel->funding_txid */
if (bitcoin_txid_eq(&channel->funding.txid,
&inflight->funding->outpoint.txid))
continue;
/* Normal cases where we watch funding */
case CHANNELD_AWAITING_LOCKIN:
case CHANNELD_NORMAL:
case CHANNELD_SHUTTING_DOWN:
case CLOSINGD_SIGEXCHANGE:
/* We still want to watch spend, to tell onchaind: */
case CLOSINGD_COMPLETE:
case AWAITING_UNILATERAL:
case FUNDING_SPEND_SEEN:
case ONCHAIN:
case CLOSED:
channel_watch_funding(ld, channel);
break;

/* We need to watch all inflights which may open channel */
case DUALOPEND_AWAITING_LOCKIN:
list_for_each(&channel->inflights, inflight, list)
watch_opening_inflight(ld, inflight);
break;

channel_watch_inflight(ld, channel, inflight);
/* We need to watch all inflights which may splice */
case CHANNELD_AWAITING_SPLICE:
list_for_each(&channel->inflights, inflight, list)
watch_splice_inflight(ld, inflight);
break;
}

if (channel_state_wants_peercomms(channel->state))
connect = true;
}
Expand Down
4 changes: 1 addition & 3 deletions lightningd/peer_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,7 @@ void update_channel_from_inflight(struct lightningd *ld,
const struct channel_inflight *inflight);

void channel_watch_funding(struct lightningd *ld, struct channel *channel);
void channel_watch_inflight(struct lightningd *ld,
struct channel *channel,
struct channel_inflight *inflight);

/* If this channel has a "wrong funding" shutdown, watch that too. */
void channel_watch_wrong_funding(struct lightningd *ld, struct channel *channel);

Expand Down
Loading

0 comments on commit 854bda8

Please sign in to comment.