Skip to content

Commit cb99987

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 376468f commit cb99987

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

channeld/channeld.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4099,6 +4099,16 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg)
40994099
}
41004100
}
41014101
else if (type == WIRE_TX_INIT_RBF) {
4102+
/* BOLT #2:
4103+
* The sender:
4104+
* - MUST NOT send `tx_init_rbf` if `option_zeroconf`
4105+
* has been negotiated.
4106+
*/
4107+
if (channel_type_has(peer->channel->type, OPT_ZEROCONF))
4108+
peer_failed_warn(peer->pps, &peer->channel_id,
4109+
"Peer sent tx_init_rbf but channel"
4110+
" uses option_zeroconf");
4111+
41024112
if (!fromwire_tx_init_rbf(tmpctx, inmsg,
41034113
&channel_id,
41044114
&locktime,
@@ -4793,6 +4803,16 @@ static void handle_splice_stfu_success(struct peer *peer)
47934803
&peer->channel->funding_pubkey[LOCAL]);
47944804
}
47954805
else { /* RBF attempt */
4806+
/* BOLT #2:
4807+
* The sender:
4808+
* - MUST NOT send `tx_init_rbf` if `option_zeroconf`
4809+
* has been negotiated.
4810+
*/
4811+
if (channel_type_has(peer->channel->type, OPT_ZEROCONF))
4812+
peer_failed_warn(peer->pps, &peer->channel_id,
4813+
"Cannot RBF splice: channel uses"
4814+
" option_zeroconf");
4815+
47964816
init_rbf_tlvs = tlv_tx_init_rbf_tlvs_new(tmpctx);
47974817
init_rbf_tlvs->funding_output_contribution = tal(init_rbf_tlvs, s64);
47984818
*init_rbf_tlvs->funding_output_contribution = peer->splicing->opener_relative;

lightningd/channel_control.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,8 +685,10 @@ static enum watch_result splice_depth_cb(struct lightningd *ld,
685685
return DELETE_WATCH;
686686
}
687687

688-
/* Reorged out? OK, we're not committed yet. */
689-
if (depth == 0) {
688+
/* Reorged out? OK, we're not committed yet.
689+
* But for zero-conf channels (minimum_depth == 0), depth 0 means
690+
* we should send splice_locked immediately per BOLT #2. */
691+
if (depth == 0 && inflight->channel->minimum_depth != 0) {
690692
return KEEP_WATCHING;
691693
}
692694

0 commit comments

Comments
 (0)