lightningd: don't share funding_depth_cb for non-funding txs.

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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-10-02 09:29:51 +10:30
parent 1cd53ae53e
commit 854bda81ac
8 changed files with 225 additions and 84 deletions

View file

@ -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)
@ -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)));
}
@ -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.

View file

@ -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 */

View file

@ -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)
{
@ -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:
@ -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;
@ -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,

View file

@ -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);

View file

@ -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)
@ -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;
@ -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);
@ -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,
@ -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;
channel_watch_inflight(ld, channel, inflight);
/* 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;
/* 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;
}

View file

@ -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);

View file

@ -198,6 +198,10 @@ void db_commit_transaction(struct db *db UNNEEDED)
/* Generated stub for delete_channel */
void delete_channel(struct channel *channel STEALS UNNEEDED)
{ fprintf(stderr, "delete_channel called!\n"); abort(); }
/* Generated stub for depthcb_update_scid */
bool depthcb_update_scid(struct channel *channel UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "depthcb_update_scid called!\n"); abort(); }
/* Generated stub for dev_disconnect_permanent */
bool dev_disconnect_permanent(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "dev_disconnect_permanent called!\n"); abort(); }
@ -654,9 +658,6 @@ void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
void lockin_complete(struct channel *channel UNNEEDED,
enum channel_state expected_state UNNEEDED)
{ fprintf(stderr, "lockin_complete called!\n"); abort(); }
/* Generated stub for lockin_has_completed */
void lockin_has_completed(struct channel *channel UNNEEDED, bool record_push UNNEEDED)
{ fprintf(stderr, "lockin_has_completed called!\n"); abort(); }
/* Generated stub for log_ */
void log_(struct logger *logger UNNEEDED, enum log_level level UNNEEDED,
const struct node_id *node_id UNNEEDED,
@ -952,11 +953,6 @@ void try_reconnect(const tal_t *ctx UNNEEDED,
/* Generated stub for version */
const char *version(void)
{ fprintf(stderr, "version called!\n"); abort(); }
/* Generated stub for wallet_annotate_txout */
void wallet_annotate_txout(struct wallet *w UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED,
enum wallet_tx_type type UNNEEDED, u64 channel UNNEEDED)
{ fprintf(stderr, "wallet_annotate_txout called!\n"); abort(); }
/* Generated stub for wallet_channel_save */
void wallet_channel_save(struct wallet *w UNNEEDED, struct channel *chan UNNEEDED)
{ fprintf(stderr, "wallet_channel_save called!\n"); abort(); }
@ -1005,10 +1001,14 @@ struct amount_msat wallet_total_forward_fees(struct wallet *w UNNEEDED)
void wallet_transaction_add(struct wallet *w UNNEEDED, const struct wally_tx *tx UNNEEDED,
const u32 blockheight UNNEEDED, const u32 txindex UNNEEDED)
{ fprintf(stderr, "wallet_transaction_add called!\n"); abort(); }
/* Generated stub for wallet_transaction_locate */
struct txlocator *wallet_transaction_locate(const tal_t *ctx UNNEEDED, struct wallet *w UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "wallet_transaction_locate called!\n"); abort(); }
/* Generated stub for watch_opening_inflight */
void watch_opening_inflight(struct lightningd *ld UNNEEDED,
struct channel_inflight *inflight UNNEEDED)
{ fprintf(stderr, "watch_opening_inflight called!\n"); abort(); }
/* Generated stub for watch_splice_inflight */
void watch_splice_inflight(struct lightningd *ld UNNEEDED,
struct channel_inflight *inflight UNNEEDED)
{ fprintf(stderr, "watch_splice_inflight called!\n"); abort(); }
/* Generated stub for watch_txid_ */
struct txwatch *watch_txid_(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,

View file

@ -139,6 +139,10 @@ struct onionreply *create_onionreply(const tal_t *ctx UNNEEDED,
const struct secret *shared_secret UNNEEDED,
const u8 *failure_msg UNNEEDED)
{ fprintf(stderr, "create_onionreply called!\n"); abort(); }
/* Generated stub for depthcb_update_scid */
bool depthcb_update_scid(struct channel *channel UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED)
{ fprintf(stderr, "depthcb_update_scid called!\n"); abort(); }
/* Generated stub for derive_channel_id */
void derive_channel_id(struct channel_id *channel_id UNNEEDED,
const struct bitcoin_outpoint *outpoint UNNEEDED)
@ -442,9 +446,6 @@ void kill_uncommitted_channel(struct uncommitted_channel *uc UNNEEDED,
void lockin_complete(struct channel *channel UNNEEDED,
enum channel_state expected_state UNNEEDED)
{ fprintf(stderr, "lockin_complete called!\n"); abort(); }
/* Generated stub for lockin_has_completed */
void lockin_has_completed(struct channel *channel UNNEEDED, bool record_push UNNEEDED)
{ fprintf(stderr, "lockin_has_completed called!\n"); abort(); }
/* Generated stub for logv */
void logv(struct logger *logger UNNEEDED, enum log_level level UNNEEDED, const struct node_id *node_id UNNEEDED,
bool call_notifier UNNEEDED, const char *fmt UNNEEDED, va_list ap UNNEEDED)
@ -898,6 +899,14 @@ const char *wait_index_name(enum wait_index index UNNEEDED)
/* Generated stub for wait_subsystem_name */
const char *wait_subsystem_name(enum wait_subsystem subsystem UNNEEDED)
{ fprintf(stderr, "wait_subsystem_name called!\n"); abort(); }
/* Generated stub for watch_opening_inflight */
void watch_opening_inflight(struct lightningd *ld UNNEEDED,
struct channel_inflight *inflight UNNEEDED)
{ fprintf(stderr, "watch_opening_inflight called!\n"); abort(); }
/* Generated stub for watch_splice_inflight */
void watch_splice_inflight(struct lightningd *ld UNNEEDED,
struct channel_inflight *inflight UNNEEDED)
{ fprintf(stderr, "watch_splice_inflight called!\n"); abort(); }
/* Generated stub for watch_txid_ */
struct txwatch *watch_txid_(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,