Skip to content

Commit 719189e

Browse files
committed
fix Fail post reserve requirements only if pre was OK
1 parent bbc3c65 commit 719189e

File tree

1 file changed

+57
-21
lines changed

1 file changed

+57
-21
lines changed

lightning/src/ln/channel.rs

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4095,30 +4095,64 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
40954095
}
40964096
}
40974097

4098+
/// Check a balance against a channel reserver requirement
4099+
#[cfg(splicing)]
4100+
pub fn check_balance_meets_reserve_requirement(balance: u64, channel_value: u64, dust_limit: u64) -> (bool, u64) {
4101+
let channel_reserve = get_v2_channel_reserve_satoshis(channel_value, dust_limit);
4102+
if balance == 0 {
4103+
// 0 balance is fine
4104+
(true, channel_reserve)
4105+
} else {
4106+
((balance >= channel_reserve), channel_reserve)
4107+
}
4108+
}
4109+
4110+
/// Check that post-splicing balance meets reserver requirements, but only if it met it pre-splice as well
4111+
#[cfg(splicing)]
4112+
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) {
4113+
match Self::check_balance_meets_reserve_requirement(
4114+
post_balance, post_channel_value, dust_limit
4115+
) {
4116+
(true, channel_reserve) => (true, channel_reserve),
4117+
(false, channel_reserve) =>
4118+
// post is not OK, check pre
4119+
match Self::check_balance_meets_reserve_requirement(
4120+
pre_balance, pre_channel_value, dust_limit
4121+
) {
4122+
(true, _) =>
4123+
// pre OK, post not -> not
4124+
(false, channel_reserve),
4125+
(false, _) =>
4126+
// post not OK, but so was pre -> OK
4127+
(true, channel_reserve),
4128+
}
4129+
}
4130+
}
4131+
40984132
/// Check that balances meet the channel reserve requirements or violates them (below reserve).
40994133
/// The channel value is an input as opposed to using from self, so that this can be used in case of splicing
41004134
/// to check with new channel value (before being comitted to it).
41014135
#[cfg(splicing)]
4102-
pub fn check_balance_meets_v2_reserve_requirements(&self, self_balance: u64, counterparty_balance: u64, channel_value: u64) -> Result<(), ChannelError> {
4103-
if self_balance > 0 {
4104-
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4105-
channel_value, self.holder_dust_limit_satoshis);
4106-
if self_balance < holder_selected_channel_reserve_satoshis {
4107-
return Err(ChannelError::Warn(format!(
4108-
"Balance below reserve mandated by holder, {} vs {}",
4109-
self_balance, holder_selected_channel_reserve_satoshis,
4110-
)));
4111-
}
4136+
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> {
4137+
let (is_ok, channel_reserve_self) = Self::check_splice_balance_meets_v2_reserve_requirement_noerr(
4138+
self_balance_pre, self_balance_post, channel_value_pre, channel_value_post,
4139+
self.holder_dust_limit_satoshis
4140+
);
4141+
if !is_ok {
4142+
return Err(ChannelError::Warn(format!(
4143+
"Balance below reserve, mandated by holder, {} vs {}",
4144+
self_balance_post, channel_reserve_self,
4145+
)));
41124146
}
4113-
if counterparty_balance > 0 {
4114-
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4115-
channel_value, self.counterparty_dust_limit_satoshis);
4116-
if counterparty_balance < counterparty_selected_channel_reserve_satoshis {
4117-
return Err(ChannelError::Warn(format!(
4118-
"Balance below reserve mandated by counterparty, {} vs {}",
4119-
counterparty_balance, counterparty_selected_channel_reserve_satoshis,
4120-
)));
4121-
}
4147+
let (is_ok, channel_reserve_cp) = Self::check_splice_balance_meets_v2_reserve_requirement_noerr(
4148+
counterparty_balance_pre, counterparty_balance_post, channel_value_pre, channel_value_post,
4149+
self.counterparty_dust_limit_satoshis
4150+
);
4151+
if !is_ok {
4152+
return Err(ChannelError::Warn(format!(
4153+
"Balance below reserve mandated by counterparty, {} vs {}",
4154+
counterparty_balance_post, channel_reserve_cp,
4155+
)));
41224156
}
41234157
Ok(())
41244158
}
@@ -8534,11 +8568,13 @@ impl<SP: Deref> FundedChannel<SP> where
85348568

85358569
let pre_channel_value = self.funding.get_value_satoshis();
85368570
let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, our_funding_contribution, their_funding_contribution_satoshis);
8537-
let post_balance_self = PendingSplice::add_checked(self.funding.value_to_self_msat, our_funding_contribution);
8571+
let pre_balance_self = self.funding.value_to_self_msat;
8572+
let post_balance_self = PendingSplice::add_checked(pre_balance_self, our_funding_contribution);
8573+
let pre_balance_counterparty = pre_channel_value.saturating_sub(pre_balance_self);
85388574
let post_balance_counterparty = post_channel_value.saturating_sub(post_balance_self);
85398575
// Pre-check for reserve requirement
85408576
// This will also be checked later at tx_complete
8541-
let _res = self.context.check_balance_meets_v2_reserve_requirements(post_balance_self, post_balance_counterparty, post_channel_value)?;
8577+
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)?;
85428578
Ok(())
85438579
}
85448580

0 commit comments

Comments
 (0)