@@ -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