splice: add zero-conf splice support per BOLT #2#8985
splice: add zero-conf splice support per BOLT #2#8985vincenzopalazzo wants to merge 5 commits intoElementsProject:masterfrom
Conversation
cb99987 to
2be428c
Compare
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.
2be428c to
7ca893f
Compare
Verify that when option_zeroconf is negotiated on a channel, splice_locked fires after just 1 block instead of the usual 6, and the channel remains usable after the splice completes. Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
| if (depth == 0 && inflight->channel->minimum_depth != 0) { | ||
| return KEEP_WATCHING; | ||
| } | ||
|
|
There was a problem hiding this comment.
This is not the right place to be trying to do zero-conf. Instead we should initiate splice_locked in channeld right after sending tx_signatures which occurs in resume_splice_negotiation.
This needs to be done with extra care because this flow can occur from initiate, accepter, or during the reestablish flow. We need to make sure it's behaving correctly in each of these flows.
Probably the best approach is to take the code in handle_funding_depth that confirms the splice and move it out into it's own function so that we can additionally call it from resume_splice_negotiation.
It would be very important to duplicate the tests in test_splicing_disconnect.py with this new zero conf splice setting enabled.
There was a problem hiding this comment.
Addressed in 7bd121c.
I moved zero-conf splice_locked initiation into resume_splice_negotiation() so we send it immediately after each local tx_signatures write, which covers the initiator, accepter, and reestablish paths in one place. For the reconnect cases I also persist i_sent_sigs, cache early splice_locked until the local signature path is complete, and treat channel_ready during zero-conf reestablish as an implied peer splice_locked once we have already sent ours.
I also duplicated the disconnect regressions for zero-conf in tests/test_splicing_disconnect.py and re-ran the zero-conf happy-path splice test. Verified with targeted runs of test_splice_zeroconf, test_splice_disconnect_sig_zeroconf, and test_splice_disconnect_commit_zeroconf.
|
Because zero-conf splices are so dangerous. It's important that we make real tests for two scenarios (and actually while I'm thinking about we need tests that handle both):
I believe we need to put all this behind a config flag that is definitely off by default. We should name it something very scary, perhaps One of the weird problems this brings up, is we PROBABLY should aggressively RBF or CPFP our closes in this case up 100% of our funds. If we burn all our funds to miners, at least we can create some kind of deterrence for the peer who can easily steal our funds. Who knows, maybe we're successful at 50% going to miner fees and we save some. Another issue to be figured out, is what we're about channel |
|
Because 0-conf splices are giving a blank check to our peer and hoping they don't cash it, perhaps we should only implement 0-conf splice if they come through Swap-in-Potentiam, which requires at least 1 conf and provides at least some security. This is what acinq does. That would be a large project however 🤔. |
|
IDK but I think 0 conf splice is used by LSP anyway like the people on the issue #7002 so I think the trust assumption is different there and would be fine to have it? |
Summary
splice_lockedto be sent immediately at depth 0 for channels withoption_zeroconfnegotiated (minimum_depth == 0)tx_init_rbfon zero-conf channels (both as initiator and acceptor), since RBF would double-spend the unconfirmed funding outputFixes #7002
Test plan
pytest tests/test_splice.py)pytest tests/test_opening.py -k zeroconf)test_splice_zeroconfintegration test