@@ -4130,33 +4130,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
41304130 }
41314131 }
41324132
4133- /// Check that a balance value meets the channel reserve requirements or violates them (below reserve).
4134- /// The channel value is an input as opposed to using from self, so that this can be used in case of splicing
4135- /// to checks with new channel value (before being comitted to it).
4136- #[cfg(splicing)]
4137- pub fn check_balance_meets_reserve_requirements(&self, balance: u64, channel_value: u64) -> Result<(), ChannelError> {
4138- if balance == 0 {
4139- return Ok(());
4140- }
4141- let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4142- channel_value, self.holder_dust_limit_satoshis);
4143- if balance < holder_selected_channel_reserve_satoshis {
4144- return Err(ChannelError::Warn(format!(
4145- "Balance below reserve mandated by holder, {} vs {}",
4146- balance, holder_selected_channel_reserve_satoshis,
4147- )));
4148- }
4149- let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4150- channel_value, self.counterparty_dust_limit_satoshis);
4151- if balance < counterparty_selected_channel_reserve_satoshis {
4152- return Err(ChannelError::Warn(format!(
4153- "Balance below reserve mandated by counterparty, {} vs {}",
4154- balance, counterparty_selected_channel_reserve_satoshis,
4155- )));
4156- }
4157- Ok(())
4158- }
4159-
41604133 /// Get the commitment tx fee for the local's (i.e. our) next commitment transaction based on the
41614134 /// number of pending HTLCs that are on track to be in our next commitment tx.
41624135 ///
@@ -8378,74 +8351,66 @@ impl<SP: Deref> FundedChannel<SP> where
83788351 }
83798352 }
83808353
8381- /// Initiate splicing
8354+ /// Initiate splicing.
8355+ /// - our_funding_inputs: the inputs we contribute to the new funding transaction.
8356+ /// Includes the witness weight for this input (e.g. P2WPKH_WITNESS_WEIGHT=109 for typical P2WPKH inputs).
83828357 #[cfg(splicing)]
83838358 pub fn splice_channel(&mut self, our_funding_contribution_satoshis: i64,
8384- our_funding_inputs: Vec<(TxIn, Transaction, Weight)>, funding_feerate_perkw: u32, locktime: u32,
8385- ) -> Result<msgs::SpliceInit, ChannelError> {
8359+ _our_funding_inputs: &Vec<(TxIn, Transaction, Weight)>,
8360+ funding_feerate_per_kw: u32, locktime: u32,
8361+ ) -> Result<msgs::SpliceInit, APIError> {
83868362 // Check if a splice has been initiated already.
8387- // Note: this could be handled more nicely, and support multiple outstanding splice's, the incoming splice_ack matters anyways.
8363+ // Note: only a single outstanding splice is supported (per spec)
83888364 if let Some(splice_info) = &self.pending_splice_pre {
8389- return Err(ChannelError::Warn(format!(
8390- "Channel has already a splice pending, contribution {}", splice_info.our_funding_contribution
8391- )));
8365+ return Err(APIError::APIMisuseError { err: format!(
8366+ "Channel {} cannot be spliced, as it has already a splice pending (contribution {})",
8367+ self.context.channel_id(), splice_info.our_funding_contribution
8368+ )});
83928369 }
83938370
8394- if !matches!(self.context.channel_state, ChannelState::ChannelReady(_)) {
8395- return Err(ChannelError::Warn(format!("Cannot initiate splicing, as channel is not Ready")));
8371+ if !self.context.is_live() {
8372+ return Err(APIError::APIMisuseError { err: format!(
8373+ "Channel {} cannot be spliced, as channel is not live",
8374+ self.context.channel_id()
8375+ )});
83968376 }
83978377
8398- let pre_channel_value = self.funding.get_value_satoshis();
8399- // Sanity check: capacity cannot decrease below 0
8400- if (pre_channel_value as i64).saturating_add(our_funding_contribution_satoshis) < 0 {
8401- return Err(ChannelError::Warn(format!(
8402- "Post-splicing channel value cannot be negative. It was {} + {}",
8403- pre_channel_value, our_funding_contribution_satoshis
8404- )));
8405- }
8378+ // TODO(splicing): check for quiescence
84068379
84078380 if our_funding_contribution_satoshis < 0 {
8408- return Err(ChannelError::Warn( format!(
8409- "TODO(splicing): Splice-out not supported, only splice in, contribution {}",
8410- our_funding_contribution_satoshis,
8411- )) );
8381+ return Err(APIError::APIMisuseError { err: format!(
8382+ "TODO(splicing): Splice-out not supported, only splice in; channel ID {} , contribution {}",
8383+ self.context.channel_id(), our_funding_contribution_satoshis,
8384+ )} );
84128385 }
84138386
8414- // Note: post-splice channel value is not yet known at this point, counterpary contribution is not known
8387+ // TODO(splicing): Once splice-out is supported, check that channel balance does not go below 0
8388+ // (or below channel reserve)
8389+
8390+ // Note: post-splice channel value is not yet known at this point, counterparty contribution is not known
84158391 // (Cannot test for miminum required post-splice channel value)
84168392
8417- // Check that inputs are sufficient to cover our contribution
8418- let sum_input: i64 = our_funding_inputs.into_iter().map(
8419- |(txin, tx, _)| tx.output.get(txin.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0)
8420- ).sum();
8421- if sum_input < our_funding_contribution_satoshis {
8422- return Err(ChannelError::Warn(format!(
8423- "Provided inputs are insufficient for our contribution, {} {}",
8424- sum_input, our_funding_contribution_satoshis,
8425- )));
8426- }
84278393
84288394 self.pending_splice_pre = Some(PendingSplice {
84298395 our_funding_contribution: our_funding_contribution_satoshis,
84308396 });
84318397
8432- let msg = self.get_splice_init(our_funding_contribution_satoshis, funding_feerate_perkw , locktime);
8398+ let msg = self.get_splice_init(our_funding_contribution_satoshis, funding_feerate_per_kw , locktime);
84338399 Ok(msg)
84348400 }
84358401
84368402 /// Get the splice message that can be sent during splice initiation.
84378403 #[cfg(splicing)]
84388404 pub fn get_splice_init(&self, our_funding_contribution_satoshis: i64,
8439- funding_feerate_perkw : u32, locktime: u32,
8405+ funding_feerate_per_kw : u32, locktime: u32,
84408406 ) -> msgs::SpliceInit {
8441- // Reuse the existing funding pubkey, in spite of the channel value changing
8442- // (though at this point we don't know the new value yet, due tue the optional counterparty contribution)
8407+ // TODO(splicing): The exisiting pubkey is reused, but a new one should be generated. See #3542.
84438408 // Note that channel_keys_id is supposed NOT to change
84448409 let funding_pubkey = self.funding.get_holder_pubkeys().funding_pubkey.clone();
84458410 msgs::SpliceInit {
84468411 channel_id: self.context.channel_id,
84478412 funding_contribution_satoshis: our_funding_contribution_satoshis,
8448- funding_feerate_perkw ,
8413+ funding_feerate_per_kw ,
84498414 locktime,
84508415 funding_pubkey,
84518416 require_confirmed_inputs: None,
@@ -8467,20 +8432,11 @@ impl<SP: Deref> FundedChannel<SP> where
84678432 )));
84688433 }
84698434
8470- if !matches!(self.context.channel_state, ChannelState::ChannelReady(_)) {
8471- return Err(ChannelError::Warn(format!("Splicing requested on a channel that is not Ready")));
8472- }
8473-
8474- let pre_channel_value = self.funding.get_value_satoshis();
8475- // Sanity check: capacity cannot decrease below 0
8476- if (pre_channel_value as i64)
8477- .saturating_add(their_funding_contribution_satoshis)
8478- .saturating_add(our_funding_contribution_satoshis) < 0
8479- {
8480- return Err(ChannelError::Warn(format!(
8481- "Post-splicing channel value cannot be negative. It was {} + {} + {}",
8482- pre_channel_value, their_funding_contribution_satoshis, our_funding_contribution_satoshis,
8483- )));
8435+ // - If it has received shutdown:
8436+ // MUST send a warning and close the connection or send an error
8437+ // and fail the channel.
8438+ if !self.context.is_live() {
8439+ return Err(ChannelError::Warn(format!("Splicing requested on a channel that is not live")));
84848440 }
84858441
84868442 if their_funding_contribution_satoshis.saturating_add(our_funding_contribution_satoshis) < 0 {
@@ -8490,11 +8446,12 @@ impl<SP: Deref> FundedChannel<SP> where
84908446 )));
84918447 }
84928448
8493- let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, their_funding_contribution_satoshis, our_funding_contribution_satoshis);
8494- let post_balance = PendingSplice::add_checked(self.funding.value_to_self_msat, our_funding_contribution_satoshis);
8495- // Early check for reserve requirement, assuming maximum balance of full channel value
8496- // This will also be checked later at tx_complete
8497- let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8449+ // TODO(splicing): Once splice acceptor can contribute, check that inputs are sufficient,
8450+ // similarly to the check in `splice_channel`.
8451+
8452+ // Note on channel reserve requirement pre-check: as the splice acceptor does not contribute,
8453+ // it can't go below reserve, therefore no pre-check is done here.
8454+ // TODO(splicing): Once splice acceptor can contribute, add reserve pre-check, similar to the one in `splice_ack`.
84988455
84998456 // TODO(splicing): Store msg.funding_pubkey
85008457 // TODO(splicing): Apply start of splice (splice_start)
@@ -8507,7 +8464,8 @@ impl<SP: Deref> FundedChannel<SP> where
85078464 /// Get the splice_ack message that can be sent in response to splice initiation.
85088465 #[cfg(splicing)]
85098466 pub fn get_splice_ack(&self, our_funding_contribution_satoshis: i64) -> msgs::SpliceAck {
8510- // Reuse the existing funding pubkey, in spite of the channel value changing
8467+ // TODO(splicing): The exisiting pubkey is reused, but a new one should be generated. See #3542.
8468+ // Note that channel_keys_id is supposed NOT to change
85118469 let funding_pubkey = self.funding.get_holder_pubkeys().funding_pubkey;
85128470 msgs::SpliceAck {
85138471 channel_id: self.context.channel_id,
@@ -8519,24 +8477,14 @@ impl<SP: Deref> FundedChannel<SP> where
85198477
85208478 /// Handle splice_ack
85218479 #[cfg(splicing)]
8522- pub fn splice_ack(&mut self, msg: &msgs::SpliceAck) -> Result<(), ChannelError> {
8523- let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
8524-
8480+ pub fn splice_ack(&mut self, _msg: &msgs::SpliceAck) -> Result<(), ChannelError> {
85258481 // check if splice is pending
8526- let pending_splice = if let Some(pending_splice) = &self.pending_splice_pre {
8527- pending_splice
8528- } else {
8482+ if self.pending_splice_pre.is_none() {
85298483 return Err(ChannelError::Warn(format!("Channel is not in pending splice")));
85308484 };
85318485
8532- let our_funding_contribution = pending_splice.our_funding_contribution;
8533-
8534- let pre_channel_value = self.funding.get_value_satoshis();
8535- let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, our_funding_contribution, their_funding_contribution_satoshis);
8536- let post_balance = PendingSplice::add_checked(self.funding.value_to_self_msat, our_funding_contribution);
8537- // Early check for reserve requirement, assuming maximum balance of full channel value
8538- // This will also be checked later at tx_complete
8539- let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8486+ // TODO(splicing): Pre-check for reserve requirement
8487+ // (Note: It should also be checked later at tx_complete)
85408488 Ok(())
85418489 }
85428490
@@ -12907,15 +12855,15 @@ mod tests {
1290712855 );
1290812856 }
1290912857
12910- #[cfg(all(test, splicing) )]
12858+ #[cfg(splicing)]
1291112859 fn get_pre_and_post(pre_channel_value: u64, our_funding_contribution: i64, their_funding_contribution: i64) -> (u64, u64) {
1291212860 use crate::ln::channel::PendingSplice;
1291312861
1291412862 let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, our_funding_contribution, their_funding_contribution);
1291512863 (pre_channel_value, post_channel_value)
1291612864 }
1291712865
12918- #[cfg(all(test, splicing) )]
12866+ #[cfg(splicing)]
1291912867 #[test]
1292012868 fn test_splice_compute_post_value() {
1292112869 {
0 commit comments