Skip to content

Commit e3624d1

Browse files
committed
Gate counterparty splices behind a confirmation depth
On 0-conf channels splice_locked is sent the moment tx_signatures are exchanged because the channel's minimum_depth is 0. That's fine when we initiated the splice since we built the funding output, but on a counterparty-initiated splice it means we lock in a funding output we didn't construct and the counterparty can double-spend the splice transaction out from under us. Bumps rust-lightning to cb5bdef1, which adds a ChannelHandshakeConfig::splice_minimum_depth override that only kicks in when is_initiator is false, and surfaces it on Config as inbound_splice_minimum_depth. Default is Some(6) so the library is safe out of the box. An LSP may want to lower this for better UX with a small safety trade-off. MDK-798
1 parent e650a50 commit e3624d1

2 files changed

Lines changed: 30 additions & 12 deletions

File tree

Cargo.toml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ default = []
4242
# lightning-macros = { version = "0.2.0" }
4343

4444
# Branch: https://github.com/moneydevkit/rust-lightning/commits/lsp-0.2.0/
45-
lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c", features = ["std"] }
46-
lightning-types = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c" }
47-
lightning-invoice = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c", features = ["std"] }
48-
lightning-net-tokio = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c" }
49-
lightning-persister = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c", features = ["tokio"] }
50-
lightning-background-processor = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c" }
51-
lightning-rapid-gossip-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c" }
52-
lightning-block-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c", features = ["rest-client", "rpc-client", "tokio"] }
53-
lightning-transaction-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
54-
lightning-liquidity = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c", features = ["std"] }
55-
lightning-macros = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c" }
45+
lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b", features = ["std"] }
46+
lightning-types = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b" }
47+
lightning-invoice = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b", features = ["std"] }
48+
lightning-net-tokio = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b" }
49+
lightning-persister = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b", features = ["tokio"] }
50+
lightning-background-processor = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b" }
51+
lightning-rapid-gossip-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b" }
52+
lightning-block-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b", features = ["rest-client", "rpc-client", "tokio"] }
53+
lightning-transaction-sync = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b", features = ["esplora-async-https", "time", "electrum-rustls-ring"] }
54+
lightning-liquidity = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b", features = ["std"] }
55+
lightning-macros = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b" }
5656

5757
#lightning = { path = "../rust-lightning/lightning", features = ["std"] }
5858
#lightning-types = { path = "../rust-lightning/lightning-types" }
@@ -101,7 +101,7 @@ winapi = { version = "0.3", features = ["winbase"] }
101101
[dev-dependencies]
102102
# lightning = { version = "0.2.0", features = ["std", "_test_utils"] }
103103
# Branch: https://github.com/moneydevkit/rust-lightning/commits/lsp-0.2.0/
104-
lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "a10b923620e58ec6d25286a10406aaaf58a1c35c", features = ["std", "_test_utils"] }
104+
lightning = { git = "https://github.com/moneydevkit/rust-lightning", rev = "cb5bdef1664245a80a4981da12ce862f15d8765b", features = ["std", "_test_utils"] }
105105
#lightning = { path = "../rust-lightning/lightning", features = ["std", "_test_utils"] }
106106
proptest = "1.0.0"
107107
regex = "1.5.6"

src/config.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ pub(crate) const EXTERNAL_PATHFINDING_SCORES_SYNC_TIMEOUT_SECS: u64 = 5;
120120
/// | `log_level` | Debug |
121121
/// | `anchor_channels_config` | Some(..) |
122122
/// | `route_parameters` | None |
123+
/// | `inbound_splice_minimum_depth` | Some(6) |
123124
///
124125
/// See [`AnchorChannelsConfig`] and [`RouteParametersConfig`] for more information regarding their
125126
/// respective default values.
@@ -184,6 +185,21 @@ pub struct Config {
184185
/// **Note:** If unset, default parameters will be used, and you will be able to override the
185186
/// parameters on a per-payment basis in the corresponding method calls.
186187
pub route_parameters: Option<RouteParametersConfig>,
188+
/// The minimum confirmation depth required before we send `splice_locked` for splices
189+
/// initiated by our counterparty.
190+
///
191+
/// On 0-conf channels, `splice_locked` would otherwise be sent immediately after
192+
/// `tx_signatures` are exchanged. That is safe for self-initiated splices (we built the
193+
/// funding output) but unsafe for counterparty-initiated splices: the counterparty could
194+
/// double-spend the splice transaction after we've already locked it in. This setting gates
195+
/// counterparty-initiated splices behind a configurable confirmation depth.
196+
///
197+
/// Has no effect on self-initiated splices or on non-0-conf channels (which already enforce
198+
/// their own `minimum_depth`).
199+
///
200+
/// If set to `None`, counterparty-initiated splices inherit the channel's `minimum_depth`,
201+
/// which is `0` for 0-conf channels.
202+
pub inbound_splice_minimum_depth: Option<u32>,
187203
}
188204

189205
impl Default for Config {
@@ -198,6 +214,7 @@ impl Default for Config {
198214
anchor_channels_config: Some(AnchorChannelsConfig::default()),
199215
route_parameters: None,
200216
node_alias: None,
217+
inbound_splice_minimum_depth: Some(6),
201218
}
202219
}
203220
}
@@ -325,6 +342,7 @@ pub(crate) fn default_user_config(config: &Config) -> UserConfig {
325342
user_config.manually_accept_inbound_channels = true;
326343
user_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx =
327344
config.anchor_channels_config.is_some();
345+
user_config.channel_handshake_config.splice_minimum_depth = config.inbound_splice_minimum_depth;
328346
user_config.reject_inbound_splices = false;
329347

330348
if may_announce_channel(config).is_err() {

0 commit comments

Comments
 (0)