Skip to content

Commit 8a596fb

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 20b6809 commit 8a596fb

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
@@ -10817,11 +10817,21 @@ where
1081710817
)));
1081810818
}
1081910819

10820+
debug_assert_eq!(our_funding_contribution, SignedAmount::ZERO);
10821+
1082010822
// TODO(splicing): Move this check once user-provided contributions are supported for
1082110823
// counterparty-initiated splices.
1082210824
if our_funding_contribution > SignedAmount::MAX_MONEY {
1082310825
return Err(ChannelError::WarnAndDisconnect(format!(
10824-
"Channel {} cannot be spliced; our contribution exceeds total bitcoin supply: {}",
10826+
"Channel {} cannot be spliced in; our {} contribution exceeds the total bitcoin supply",
10827+
self.context.channel_id(),
10828+
our_funding_contribution,
10829+
)));
10830+
}
10831+
10832+
if our_funding_contribution < -SignedAmount::MAX_MONEY {
10833+
return Err(ChannelError::WarnAndDisconnect(format!(
10834+
"Channel {} cannot be spliced out; our {} contribution exhausts the total bitcoin supply",
1082510835
self.context.channel_id(),
1082610836
our_funding_contribution,
1082710837
)));
@@ -10830,22 +10840,38 @@ where
1083010840
let their_funding_contribution = SignedAmount::from_sat(msg.funding_contribution_satoshis);
1083110841
if their_funding_contribution > SignedAmount::MAX_MONEY {
1083210842
return Err(ChannelError::WarnAndDisconnect(format!(
10833-
"Channel {} cannot be spliced; their contribution exceeds total bitcoin supply: {}",
10843+
"Channel {} cannot be spliced in; their {} contribution exceeds the total bitcoin supply",
1083410844
self.context.channel_id(),
1083510845
their_funding_contribution,
1083610846
)));
1083710847
}
1083810848

10839-
debug_assert_eq!(our_funding_contribution, SignedAmount::ZERO);
10840-
if their_funding_contribution < SignedAmount::ZERO {
10849+
if their_funding_contribution < -SignedAmount::MAX_MONEY {
1084110850
return Err(ChannelError::WarnAndDisconnect(format!(
10842-
"Splice-out not supported, only splice in, contribution is {} ({} + {})",
10843-
their_funding_contribution + our_funding_contribution,
10851+
"Channel {} cannot be spliced out; their {} contribution exhausts the total bitcoin supply",
10852+
self.context.channel_id(),
1084410853
their_funding_contribution,
10845-
our_funding_contribution,
1084610854
)));
1084710855
}
1084810856

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

1098011006
let their_funding_contribution = SignedAmount::from_sat(msg.funding_contribution_satoshis);
1098111007
if their_funding_contribution > SignedAmount::MAX_MONEY {
10982-
return Err(ChannelError::Warn(format!(
10983-
"Channel {} cannot be spliced; their contribution exceeds total bitcoin supply: {}",
11008+
return Err(ChannelError::WarnAndDisconnect(format!(
11009+
"Channel {} cannot be spliced in; their {} contribution exceeds the total bitcoin supply",
11010+
self.context.channel_id(),
11011+
their_funding_contribution,
11012+
)));
11013+
}
11014+
11015+
if their_funding_contribution < -SignedAmount::MAX_MONEY {
11016+
return Err(ChannelError::WarnAndDisconnect(format!(
11017+
"Channel {} cannot be spliced out; their {} contribution exhausts the total bitcoin supply",
11018+
self.context.channel_id(),
11019+
their_funding_contribution,
11020+
)));
11021+
}
11022+
11023+
let their_channel_balance = Amount::from_sat(self.funding.get_value_satoshis())
11024+
- Amount::from_sat(self.funding.get_value_to_self_msat() / 1000);
11025+
let post_channel_balance = AddSigned::checked_add_signed(
11026+
their_channel_balance.to_sat(),
11027+
their_funding_contribution.to_sat(),
11028+
);
11029+
11030+
if post_channel_balance.is_none() {
11031+
return Err(ChannelError::WarnAndDisconnect(format!(
11032+
"Channel {} cannot be spliced out; their {} contribution exhausts their channel balance: {}",
1098411033
self.context.channel_id(),
1098511034
their_funding_contribution,
11035+
their_channel_balance,
1098611036
)));
1098711037
}
1098811038

0 commit comments

Comments
 (0)