Skip to content

Commit 29c61bd

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 b8ccabe commit 29c61bd

File tree

1 file changed

+59
-9
lines changed

1 file changed

+59
-9
lines changed

lightning/src/ln/channel.rs

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10819,11 +10819,21 @@ where
1081910819
)));
1082010820
}
1082110821

10822+
debug_assert_eq!(our_funding_contribution, SignedAmount::ZERO);
10823+
1082210824
// TODO(splicing): Move this check once user-provided contributions are supported for
1082310825
// counterparty-initiated splices.
1082410826
if our_funding_contribution > SignedAmount::MAX_MONEY {
1082510827
return Err(ChannelError::WarnAndDisconnect(format!(
10826-
"Channel {} cannot be spliced; our contribution exceeds total bitcoin supply: {}",
10828+
"Channel {} cannot be spliced in; our {} contribution exceeds the total bitcoin supply",
10829+
self.context.channel_id(),
10830+
our_funding_contribution,
10831+
)));
10832+
}
10833+
10834+
if our_funding_contribution < -SignedAmount::MAX_MONEY {
10835+
return Err(ChannelError::WarnAndDisconnect(format!(
10836+
"Channel {} cannot be spliced out; our {} contribution exhausts the total bitcoin supply",
1082710837
self.context.channel_id(),
1082810838
our_funding_contribution,
1082910839
)));
@@ -10832,22 +10842,38 @@ where
1083210842
let their_funding_contribution = SignedAmount::from_sat(msg.funding_contribution_satoshis);
1083310843
if their_funding_contribution > SignedAmount::MAX_MONEY {
1083410844
return Err(ChannelError::WarnAndDisconnect(format!(
10835-
"Channel {} cannot be spliced; their contribution exceeds total bitcoin supply: {}",
10845+
"Channel {} cannot be spliced in; their {} contribution exceeds the total bitcoin supply",
1083610846
self.context.channel_id(),
1083710847
their_funding_contribution,
1083810848
)));
1083910849
}
1084010850

10841-
debug_assert_eq!(our_funding_contribution, SignedAmount::ZERO);
10842-
if their_funding_contribution < SignedAmount::ZERO {
10851+
if their_funding_contribution < -SignedAmount::MAX_MONEY {
1084310852
return Err(ChannelError::WarnAndDisconnect(format!(
10844-
"Splice-out not supported, only splice in, contribution is {} ({} + {})",
10845-
their_funding_contribution + our_funding_contribution,
10853+
"Channel {} cannot be spliced out; their {} contribution exhausts the total bitcoin supply",
10854+
self.context.channel_id(),
1084610855
their_funding_contribution,
10847-
our_funding_contribution,
1084810856
)));
1084910857
}
1085010858

10859+
let their_channel_balance = Amount::from_sat(self.funding.get_value_satoshis())
10860+
- Amount::from_sat(self.funding.get_value_to_self_msat() / 1000);
10861+
let post_channel_balance = AddSigned::checked_add_signed(
10862+
their_channel_balance.to_sat(),
10863+
their_funding_contribution.to_sat(),
10864+
);
10865+
10866+
if post_channel_balance.is_none() {
10867+
return Err(ChannelError::WarnAndDisconnect(format!(
10868+
"Channel {} cannot be spliced out; their {} contribution exhausts their channel balance: {}",
10869+
self.context.channel_id(),
10870+
their_funding_contribution,
10871+
their_channel_balance,
10872+
)));
10873+
}
10874+
10875+
// TODO(splicing): Check that channel balance does not go below the channel reserve
10876+
1085110877
let splice_funding = FundingScope::for_splice(
1085210878
&self.funding,
1085310879
&self.context,
@@ -10981,10 +11007,34 @@ where
1098111007

1098211008
let their_funding_contribution = SignedAmount::from_sat(msg.funding_contribution_satoshis);
1098311009
if their_funding_contribution > SignedAmount::MAX_MONEY {
10984-
return Err(ChannelError::Warn(format!(
10985-
"Channel {} cannot be spliced; their contribution exceeds total bitcoin supply: {}",
11010+
return Err(ChannelError::WarnAndDisconnect(format!(
11011+
"Channel {} cannot be spliced in; their {} contribution exceeds the total bitcoin supply",
11012+
self.context.channel_id(),
11013+
their_funding_contribution,
11014+
)));
11015+
}
11016+
11017+
if their_funding_contribution < -SignedAmount::MAX_MONEY {
11018+
return Err(ChannelError::WarnAndDisconnect(format!(
11019+
"Channel {} cannot be spliced out; their {} contribution exhausts the total bitcoin supply",
11020+
self.context.channel_id(),
11021+
their_funding_contribution,
11022+
)));
11023+
}
11024+
11025+
let their_channel_balance = Amount::from_sat(self.funding.get_value_satoshis())
11026+
- Amount::from_sat(self.funding.get_value_to_self_msat() / 1000);
11027+
let post_channel_balance = AddSigned::checked_add_signed(
11028+
their_channel_balance.to_sat(),
11029+
their_funding_contribution.to_sat(),
11030+
);
11031+
11032+
if post_channel_balance.is_none() {
11033+
return Err(ChannelError::WarnAndDisconnect(format!(
11034+
"Channel {} cannot be spliced out; their {} contribution exhausts their channel balance: {}",
1098611035
self.context.channel_id(),
1098711036
their_funding_contribution,
11037+
their_channel_balance,
1098811038
)));
1098911039
}
1099011040

0 commit comments

Comments
 (0)