Skip to content

Commit 74e68b0

Browse files
committed
Support accepting splice-out
When a counterparty sends splice_init with a negative contribution, they are requesting to remove funds from a channel. Remove conditions guarding against this and check that they have enough channel balance to cover the removed funds.
1 parent 604762a commit 74e68b0

1 file changed

Lines changed: 59 additions & 9 deletions

File tree

lightning/src/ln/channel.rs

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10826,11 +10826,21 @@ where
1082610826
)));
1082710827
}
1082810828

10829+
debug_assert_eq!(our_funding_contribution, SignedAmount::ZERO);
10830+
1082910831
// TODO(splicing): Move this check once user-provided contributions are supported for
1083010832
// counterparty-initiated splices.
1083110833
if our_funding_contribution > SignedAmount::MAX_MONEY {
1083210834
return Err(ChannelError::WarnAndDisconnect(format!(
10833-
"Channel {} cannot be spliced; our contribution exceeds total bitcoin supply: {}",
10835+
"Channel {} cannot be spliced in; our {} contribution exceeds the total bitcoin supply",
10836+
self.context.channel_id(),
10837+
our_funding_contribution,
10838+
)));
10839+
}
10840+
10841+
if our_funding_contribution < -SignedAmount::MAX_MONEY {
10842+
return Err(ChannelError::WarnAndDisconnect(format!(
10843+
"Channel {} cannot be spliced out; our {} contribution exhausts the total bitcoin supply",
1083410844
self.context.channel_id(),
1083510845
our_funding_contribution,
1083610846
)));
@@ -10839,22 +10849,38 @@ where
1083910849
let their_funding_contribution = SignedAmount::from_sat(msg.funding_contribution_satoshis);
1084010850
if their_funding_contribution > SignedAmount::MAX_MONEY {
1084110851
return Err(ChannelError::WarnAndDisconnect(format!(
10842-
"Channel {} cannot be spliced; their contribution exceeds total bitcoin supply: {}",
10852+
"Channel {} cannot be spliced in; their {} contribution exceeds the total bitcoin supply",
1084310853
self.context.channel_id(),
1084410854
their_funding_contribution,
1084510855
)));
1084610856
}
1084710857

10848-
debug_assert_eq!(our_funding_contribution, SignedAmount::ZERO);
10849-
if their_funding_contribution < SignedAmount::ZERO {
10858+
if their_funding_contribution < -SignedAmount::MAX_MONEY {
1085010859
return Err(ChannelError::WarnAndDisconnect(format!(
10851-
"Splice-out not supported, only splice in, contribution is {} ({} + {})",
10852-
their_funding_contribution + our_funding_contribution,
10860+
"Channel {} cannot be spliced out; their {} contribution exhausts the total bitcoin supply",
10861+
self.context.channel_id(),
1085310862
their_funding_contribution,
10854-
our_funding_contribution,
1085510863
)));
1085610864
}
1085710865

10866+
let their_channel_balance = Amount::from_sat(self.funding.get_value_satoshis())
10867+
- Amount::from_sat(self.funding.get_value_to_self_msat() / 1000);
10868+
let post_channel_balance = AddSigned::checked_add_signed(
10869+
their_channel_balance.to_sat(),
10870+
their_funding_contribution.to_sat(),
10871+
);
10872+
10873+
if post_channel_balance.is_none() {
10874+
return Err(ChannelError::WarnAndDisconnect(format!(
10875+
"Channel {} cannot be spliced out; their {} contribution exhausts their channel balance: {}",
10876+
self.context.channel_id(),
10877+
their_funding_contribution,
10878+
their_channel_balance,
10879+
)));
10880+
}
10881+
10882+
// TODO(splicing): Check that channel balance does not go below the channel reserve
10883+
1085810884
let splice_funding = FundingScope::for_splice(
1085910885
&self.funding,
1086010886
&self.context,
@@ -10988,10 +11014,34 @@ where
1098811014

1098911015
let their_funding_contribution = SignedAmount::from_sat(msg.funding_contribution_satoshis);
1099011016
if their_funding_contribution > SignedAmount::MAX_MONEY {
10991-
return Err(ChannelError::Warn(format!(
10992-
"Channel {} cannot be spliced; their contribution exceeds total bitcoin supply: {}",
11017+
return Err(ChannelError::WarnAndDisconnect(format!(
11018+
"Channel {} cannot be spliced in; their {} contribution exceeds the total bitcoin supply",
11019+
self.context.channel_id(),
11020+
their_funding_contribution,
11021+
)));
11022+
}
11023+
11024+
if their_funding_contribution < -SignedAmount::MAX_MONEY {
11025+
return Err(ChannelError::WarnAndDisconnect(format!(
11026+
"Channel {} cannot be spliced out; their {} contribution exhausts the total bitcoin supply",
11027+
self.context.channel_id(),
11028+
their_funding_contribution,
11029+
)));
11030+
}
11031+
11032+
let their_channel_balance = Amount::from_sat(self.funding.get_value_satoshis())
11033+
- Amount::from_sat(self.funding.get_value_to_self_msat() / 1000);
11034+
let post_channel_balance = AddSigned::checked_add_signed(
11035+
their_channel_balance.to_sat(),
11036+
their_funding_contribution.to_sat(),
11037+
);
11038+
11039+
if post_channel_balance.is_none() {
11040+
return Err(ChannelError::WarnAndDisconnect(format!(
11041+
"Channel {} cannot be spliced out; their {} contribution exhausts their channel balance: {}",
1099311042
self.context.channel_id(),
1099411043
their_funding_contribution,
11044+
their_channel_balance,
1099511045
)));
1099611046
}
1099711047

0 commit comments

Comments
 (0)