Skip to content

Commit bd703b4

Browse files
committed
Add checks on inputs: sufficient, reserve, fees
1 parent 4ed2f85 commit bd703b4

File tree

1 file changed

+55
-18
lines changed

1 file changed

+55
-18
lines changed

lightning/src/ln/channel.rs

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4273,28 +4273,63 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
42734273
}
42744274
}
42754275

4276-
/// Check that a balance value meets the channel reserve requirements or violates them (below reserve).
4277-
/// The channel value is an input as opposed to using from self, so that this can be used in case of splicing
4278-
/// to checks with new channel value (before being comitted to it).
4276+
/// Check a balance against a channel reserver requirement
42794277
#[cfg(splicing)]
4280-
pub fn check_balance_meets_reserve_requirements(&self, balance: u64, channel_value: u64) -> Result<(), ChannelError> {
4278+
pub fn check_balance_meets_reserve_requirement(balance: u64, channel_value: u64, dust_limit: u64) -> (bool, u64) {
4279+
let channel_reserve = get_v2_channel_reserve_satoshis(channel_value, dust_limit);
42814280
if balance == 0 {
4282-
return Ok(());
4281+
// 0 balance is fine
4282+
(true, channel_reserve)
4283+
} else {
4284+
((balance >= channel_reserve), channel_reserve)
42834285
}
4284-
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4285-
channel_value, self.holder_dust_limit_satoshis);
4286-
if balance < holder_selected_channel_reserve_satoshis {
4286+
}
4287+
4288+
/// Check that post-splicing balance meets reserver requirements, but only if it met it pre-splice as well
4289+
#[cfg(splicing)]
4290+
pub fn check_splice_balance_meets_v2_reserve_requirement_noerr(pre_balance: u64, post_balance: u64, pre_channel_value: u64, post_channel_value: u64, dust_limit: u64) -> (bool, u64) {
4291+
match Self::check_balance_meets_reserve_requirement(
4292+
post_balance, post_channel_value, dust_limit
4293+
) {
4294+
(true, channel_reserve) => (true, channel_reserve),
4295+
(false, channel_reserve) =>
4296+
// post is not OK, check pre
4297+
match Self::check_balance_meets_reserve_requirement(
4298+
pre_balance, pre_channel_value, dust_limit
4299+
) {
4300+
(true, _) =>
4301+
// pre OK, post not -> not
4302+
(false, channel_reserve),
4303+
(false, _) =>
4304+
// post not OK, but so was pre -> OK
4305+
(true, channel_reserve),
4306+
}
4307+
}
4308+
}
4309+
4310+
/// Check that balances meet the channel reserve requirements or violates them (below reserve).
4311+
/// The channel value is an input as opposed to using from self, so that this can be used in case of splicing
4312+
/// to check with new channel value (before being comitted to it).
4313+
#[cfg(splicing)]
4314+
pub fn check_splice_balances_meet_v2_reserve_requirements(&self, self_balance_pre: u64, self_balance_post: u64, counterparty_balance_pre: u64, counterparty_balance_post: u64, channel_value_pre: u64, channel_value_post: u64) -> Result<(), ChannelError> {
4315+
let (is_ok, channel_reserve_self) = Self::check_splice_balance_meets_v2_reserve_requirement_noerr(
4316+
self_balance_pre, self_balance_post, channel_value_pre, channel_value_post,
4317+
self.holder_dust_limit_satoshis
4318+
);
4319+
if !is_ok {
42874320
return Err(ChannelError::Warn(format!(
4288-
"Balance below reserve mandated by holder, {} vs {}",
4289-
balance, holder_selected_channel_reserve_satoshis,
4321+
"Balance below reserve, mandated by holder, {} vs {}",
4322+
self_balance_post, channel_reserve_self,
42904323
)));
42914324
}
4292-
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4293-
channel_value, self.counterparty_dust_limit_satoshis);
4294-
if balance < counterparty_selected_channel_reserve_satoshis {
4325+
let (is_ok, channel_reserve_cp) = Self::check_splice_balance_meets_v2_reserve_requirement_noerr(
4326+
counterparty_balance_pre, counterparty_balance_post, channel_value_pre, channel_value_post,
4327+
self.counterparty_dust_limit_satoshis
4328+
);
4329+
if !is_ok {
42954330
return Err(ChannelError::Warn(format!(
42964331
"Balance below reserve mandated by counterparty, {} vs {}",
4297-
balance, counterparty_selected_channel_reserve_satoshis,
4332+
counterparty_balance_post, channel_reserve_cp,
42984333
)));
42994334
}
43004335
Ok(())
@@ -8609,11 +8644,13 @@ impl<SP: Deref> FundedChannel<SP> where
86098644

86108645
let pre_channel_value = self.funding.get_value_satoshis();
86118646
let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, our_funding_contribution, their_funding_contribution_satoshis);
8612-
let post_balance = PendingSplice::add_checked(self.funding.value_to_self_msat, our_funding_contribution);
8613-
// Early check for reserve requirement, assuming maximum balance of full channel value
8647+
let pre_balance_self = self.funding.value_to_self_msat;
8648+
let post_balance_self = PendingSplice::add_checked(pre_balance_self, our_funding_contribution);
8649+
let pre_balance_counterparty = pre_channel_value.saturating_sub(pre_balance_self);
8650+
let post_balance_counterparty = post_channel_value.saturating_sub(post_balance_self);
8651+
// Pre-check for reserve requirement
86148652
// This will also be checked later at tx_complete
8615-
let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8616-
8653+
let _res = self.context.check_splice_balances_meet_v2_reserve_requirements(pre_balance_self, post_balance_self, pre_balance_counterparty, post_balance_counterparty, pre_channel_value, post_channel_value)?;
86178654
Ok(())
86188655
}
86198656

0 commit comments

Comments
 (0)