Skip to content

Commit 2be428c

Browse files
splice: add zero-conf splice support per BOLT #2
When option_zeroconf is negotiated on a channel, send splice_locked immediately at depth 0 instead of waiting for confirmations. Also prohibit tx_init_rbf on zero-conf channels since RBF would double-spend the unconfirmed funding output. This implements the spec requirements from lightning/bolts#1160: - splice_depth_cb: allow depth==0 through for minimum_depth==0 channels - handle_splice_stfu_success: block RBF initiation on zero-conf - splice_acceptor: reject incoming tx_init_rbf on zero-conf Changelog-Added: splice: Support zero-conf splicing on channels with option_zeroconf negotiated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 9737ef5 commit 2be428c

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

channeld/channeld.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4224,6 +4224,16 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg)
42244224
}
42254225
}
42264226
else if (type == WIRE_TX_INIT_RBF) {
4227+
/* BOLT #2:
4228+
* The sender:
4229+
* - MUST NOT send `tx_init_rbf` if `option_zeroconf`
4230+
* has been negotiated.
4231+
*/
4232+
if (channel_type_has(peer->channel->type, OPT_ZEROCONF))
4233+
peer_failed_warn(peer->pps, &peer->channel_id,
4234+
"Peer sent tx_init_rbf but channel"
4235+
" uses option_zeroconf");
4236+
42274237
if (!fromwire_tx_init_rbf(tmpctx, inmsg,
42284238
&channel_id,
42294239
&locktime,
@@ -4918,6 +4928,16 @@ static void handle_splice_stfu_success(struct peer *peer)
49184928
&peer->channel->funding_pubkey[LOCAL]);
49194929
}
49204930
else { /* RBF attempt */
4931+
/* BOLT #2:
4932+
* The sender:
4933+
* - MUST NOT send `tx_init_rbf` if `option_zeroconf`
4934+
* has been negotiated.
4935+
*/
4936+
if (channel_type_has(peer->channel->type, OPT_ZEROCONF))
4937+
peer_failed_warn(peer->pps, &peer->channel_id,
4938+
"Cannot RBF splice: channel uses"
4939+
" option_zeroconf");
4940+
49214941
init_rbf_tlvs = tlv_tx_init_rbf_tlvs_new(tmpctx);
49224942
init_rbf_tlvs->funding_output_contribution = tal(init_rbf_tlvs, s64);
49234943
*init_rbf_tlvs->funding_output_contribution = peer->splicing->opener_relative;

lightningd/channel_control.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,13 @@ static enum watch_result splice_depth_cb(struct lightningd *ld,
699699
return DELETE_WATCH;
700700
}
701701

702+
/* Reorged out? OK, we're not committed yet.
703+
* But for zero-conf channels (minimum_depth == 0), depth 0 means
704+
* we should send splice_locked immediately per BOLT #2. */
705+
if (depth == 0 && inflight->channel->minimum_depth != 0) {
706+
return KEEP_WATCHING;
707+
}
708+
702709
if (inflight->channel->owner) {
703710
log_debug(inflight->channel->log, "splice_depth_cb: sending funding depth scid: %s",
704711
fmt_short_channel_id(tmpctx, *inflight->scid));

0 commit comments

Comments
 (0)