@@ -4129,33 +4129,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
41294129 }
41304130 }
41314131
4132- /// Check that a balance value meets the channel reserve requirements or violates them (below reserve).
4133- /// The channel value is an input as opposed to using from self, so that this can be used in case of splicing
4134- /// to checks with new channel value (before being comitted to it).
4135- #[cfg(splicing)]
4136- pub fn check_balance_meets_reserve_requirements(&self, balance: u64, channel_value: u64) -> Result<(), ChannelError> {
4137- if balance == 0 {
4138- return Ok(());
4139- }
4140- let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4141- channel_value, self.holder_dust_limit_satoshis);
4142- if balance < holder_selected_channel_reserve_satoshis {
4143- return Err(ChannelError::Warn(format!(
4144- "Balance below reserve mandated by holder, {} vs {}",
4145- balance, holder_selected_channel_reserve_satoshis,
4146- )));
4147- }
4148- let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
4149- channel_value, self.counterparty_dust_limit_satoshis);
4150- if balance < counterparty_selected_channel_reserve_satoshis {
4151- return Err(ChannelError::Warn(format!(
4152- "Balance below reserve mandated by counterparty, {} vs {}",
4153- balance, counterparty_selected_channel_reserve_satoshis,
4154- )));
4155- }
4156- Ok(())
4157- }
4158-
41594132 /// Get the commitment tx fee for the local's (i.e. our) next commitment transaction based on the
41604133 /// number of pending HTLCs that are on track to be in our next commitment tx.
41614134 ///
@@ -8377,74 +8350,66 @@ impl<SP: Deref> FundedChannel<SP> where
83778350 }
83788351 }
83798352
8380- /// Initiate splicing
8353+ /// Initiate splicing.
8354+ /// - our_funding_inputs: the inputs we contribute to the new funding transaction.
8355+ /// Includes the witness weight for this input (e.g. P2WPKH_WITNESS_WEIGHT=109 for typical P2WPKH inputs).
83818356 #[cfg(splicing)]
83828357 pub fn splice_channel(&mut self, our_funding_contribution_satoshis: i64,
8383- our_funding_inputs: Vec<(TxIn, Transaction, Weight)>, funding_feerate_perkw: u32, locktime: u32,
8384- ) -> Result<msgs::SpliceInit, ChannelError> {
8358+ _our_funding_inputs: &Vec<(TxIn, Transaction, Weight)>,
8359+ funding_feerate_per_kw: u32, locktime: u32,
8360+ ) -> Result<msgs::SpliceInit, APIError> {
83858361 // Check if a splice has been initiated already.
8386- // Note: this could be handled more nicely, and support multiple outstanding splice's, the incoming splice_ack matters anyways.
8362+ // Note: only a single outstanding splice is supported (per spec)
83878363 if let Some(splice_info) = &self.pending_splice_pre {
8388- return Err(ChannelError::Warn(format!(
8389- "Channel has already a splice pending, contribution {}", splice_info.our_funding_contribution
8390- )));
8364+ return Err(APIError::APIMisuseError { err: format!(
8365+ "Channel {} cannot be spliced, as it has already a splice pending (contribution {})",
8366+ self.context.channel_id(), splice_info.our_funding_contribution
8367+ )});
83918368 }
83928369
8393- if !matches!(self.context.channel_state, ChannelState::ChannelReady(_)) {
8394- return Err(ChannelError::Warn(format!("Cannot initiate splicing, as channel is not Ready")));
8370+ if !self.context.is_live() {
8371+ return Err(APIError::APIMisuseError { err: format!(
8372+ "Channel {} cannot be spliced, as channel is not live",
8373+ self.context.channel_id()
8374+ )});
83958375 }
83968376
8397- let pre_channel_value = self.funding.get_value_satoshis();
8398- // Sanity check: capacity cannot decrease below 0
8399- if (pre_channel_value as i64).saturating_add(our_funding_contribution_satoshis) < 0 {
8400- return Err(ChannelError::Warn(format!(
8401- "Post-splicing channel value cannot be negative. It was {} + {}",
8402- pre_channel_value, our_funding_contribution_satoshis
8403- )));
8404- }
8377+ // TODO(splicing): check for quiescence
84058378
84068379 if our_funding_contribution_satoshis < 0 {
8407- return Err(ChannelError::Warn( format!(
8408- "TODO(splicing): Splice-out not supported, only splice in, contribution {}",
8409- our_funding_contribution_satoshis,
8410- )) );
8380+ return Err(APIError::APIMisuseError { err: format!(
8381+ "TODO(splicing): Splice-out not supported, only splice in; channel ID {} , contribution {}",
8382+ self.context.channel_id(), our_funding_contribution_satoshis,
8383+ )} );
84118384 }
84128385
8413- // Note: post-splice channel value is not yet known at this point, counterpary contribution is not known
8386+ // TODO(splicing): Once splice-out is supported, check that channel balance does not go below 0
8387+ // (or below channel reserve)
8388+
8389+ // Note: post-splice channel value is not yet known at this point, counterparty contribution is not known
84148390 // (Cannot test for miminum required post-splice channel value)
84158391
8416- // Check that inputs are sufficient to cover our contribution
8417- let sum_input: i64 = our_funding_inputs.into_iter().map(
8418- |(txin, tx, _)| tx.output.get(txin.previous_output.vout as usize).map(|tx| tx.value.to_sat() as i64).unwrap_or(0)
8419- ).sum();
8420- if sum_input < our_funding_contribution_satoshis {
8421- return Err(ChannelError::Warn(format!(
8422- "Provided inputs are insufficient for our contribution, {} {}",
8423- sum_input, our_funding_contribution_satoshis,
8424- )));
8425- }
84268392
84278393 self.pending_splice_pre = Some(PendingSplice {
84288394 our_funding_contribution: our_funding_contribution_satoshis,
84298395 });
84308396
8431- let msg = self.get_splice_init(our_funding_contribution_satoshis, funding_feerate_perkw , locktime);
8397+ let msg = self.get_splice_init(our_funding_contribution_satoshis, funding_feerate_per_kw , locktime);
84328398 Ok(msg)
84338399 }
84348400
84358401 /// Get the splice message that can be sent during splice initiation.
84368402 #[cfg(splicing)]
84378403 pub fn get_splice_init(&self, our_funding_contribution_satoshis: i64,
8438- funding_feerate_perkw : u32, locktime: u32,
8404+ funding_feerate_per_kw : u32, locktime: u32,
84398405 ) -> msgs::SpliceInit {
8440- // Reuse the existing funding pubkey, in spite of the channel value changing
8441- // (though at this point we don't know the new value yet, due tue the optional counterparty contribution)
8406+ // TODO(splicing): The exisiting pubkey is reused, but a new one should be generated. See #3542.
84428407 // Note that channel_keys_id is supposed NOT to change
84438408 let funding_pubkey = self.funding.get_holder_pubkeys().funding_pubkey.clone();
84448409 msgs::SpliceInit {
84458410 channel_id: self.context.channel_id,
84468411 funding_contribution_satoshis: our_funding_contribution_satoshis,
8447- funding_feerate_perkw ,
8412+ funding_feerate_per_kw ,
84488413 locktime,
84498414 funding_pubkey,
84508415 require_confirmed_inputs: None,
@@ -8466,20 +8431,11 @@ impl<SP: Deref> FundedChannel<SP> where
84668431 )));
84678432 }
84688433
8469- if !matches!(self.context.channel_state, ChannelState::ChannelReady(_)) {
8470- return Err(ChannelError::Warn(format!("Splicing requested on a channel that is not Ready")));
8471- }
8472-
8473- let pre_channel_value = self.funding.get_value_satoshis();
8474- // Sanity check: capacity cannot decrease below 0
8475- if (pre_channel_value as i64)
8476- .saturating_add(their_funding_contribution_satoshis)
8477- .saturating_add(our_funding_contribution_satoshis) < 0
8478- {
8479- return Err(ChannelError::Warn(format!(
8480- "Post-splicing channel value cannot be negative. It was {} + {} + {}",
8481- pre_channel_value, their_funding_contribution_satoshis, our_funding_contribution_satoshis,
8482- )));
8434+ // - If it has received shutdown:
8435+ // MUST send a warning and close the connection or send an error
8436+ // and fail the channel.
8437+ if !self.context.is_live() {
8438+ return Err(ChannelError::Warn(format!("Splicing requested on a channel that is not live")));
84838439 }
84848440
84858441 if their_funding_contribution_satoshis.saturating_add(our_funding_contribution_satoshis) < 0 {
@@ -8489,11 +8445,12 @@ impl<SP: Deref> FundedChannel<SP> where
84898445 )));
84908446 }
84918447
8492- let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, their_funding_contribution_satoshis, our_funding_contribution_satoshis);
8493- let post_balance = PendingSplice::add_checked(self.funding.value_to_self_msat, our_funding_contribution_satoshis);
8494- // Early check for reserve requirement, assuming maximum balance of full channel value
8495- // This will also be checked later at tx_complete
8496- let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8448+ // TODO(splicing): Once splice acceptor can contribute, check that inputs are sufficient,
8449+ // similarly to the check in `splice_channel`.
8450+
8451+ // Note on channel reserve requirement pre-check: as the splice acceptor does not contribute,
8452+ // it can't go below reserve, therefore no pre-check is done here.
8453+ // TODO(splicing): Once splice acceptor can contribute, add reserve pre-check, similar to the one in `splice_ack`.
84978454
84988455 // TODO(splicing): Store msg.funding_pubkey
84998456 // TODO(splicing): Apply start of splice (splice_start)
@@ -8506,7 +8463,8 @@ impl<SP: Deref> FundedChannel<SP> where
85068463 /// Get the splice_ack message that can be sent in response to splice initiation.
85078464 #[cfg(splicing)]
85088465 pub fn get_splice_ack(&self, our_funding_contribution_satoshis: i64) -> msgs::SpliceAck {
8509- // Reuse the existing funding pubkey, in spite of the channel value changing
8466+ // TODO(splicing): The exisiting pubkey is reused, but a new one should be generated. See #3542.
8467+ // Note that channel_keys_id is supposed NOT to change
85108468 let funding_pubkey = self.funding.get_holder_pubkeys().funding_pubkey;
85118469 msgs::SpliceAck {
85128470 channel_id: self.context.channel_id,
@@ -8518,24 +8476,14 @@ impl<SP: Deref> FundedChannel<SP> where
85188476
85198477 /// Handle splice_ack
85208478 #[cfg(splicing)]
8521- pub fn splice_ack(&mut self, msg: &msgs::SpliceAck) -> Result<(), ChannelError> {
8522- let their_funding_contribution_satoshis = msg.funding_contribution_satoshis;
8523-
8479+ pub fn splice_ack(&mut self, _msg: &msgs::SpliceAck) -> Result<(), ChannelError> {
85248480 // check if splice is pending
8525- let pending_splice = if let Some(pending_splice) = &self.pending_splice_pre {
8526- pending_splice
8527- } else {
8481+ if self.pending_splice_pre.is_none() {
85288482 return Err(ChannelError::Warn(format!("Channel is not in pending splice")));
85298483 };
85308484
8531- let our_funding_contribution = pending_splice.our_funding_contribution;
8532-
8533- let pre_channel_value = self.funding.get_value_satoshis();
8534- let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, our_funding_contribution, their_funding_contribution_satoshis);
8535- let post_balance = PendingSplice::add_checked(self.funding.value_to_self_msat, our_funding_contribution);
8536- // Early check for reserve requirement, assuming maximum balance of full channel value
8537- // This will also be checked later at tx_complete
8538- let _res = self.context.check_balance_meets_reserve_requirements(post_balance, post_channel_value)?;
8485+ // TODO(splicing): Pre-check for reserve requirement
8486+ // (Note: It should also be checked later at tx_complete)
85398487 Ok(())
85408488 }
85418489
@@ -12906,15 +12854,15 @@ mod tests {
1290612854 );
1290712855 }
1290812856
12909- #[cfg(all(test, splicing) )]
12857+ #[cfg(splicing)]
1291012858 fn get_pre_and_post(pre_channel_value: u64, our_funding_contribution: i64, their_funding_contribution: i64) -> (u64, u64) {
1291112859 use crate::ln::channel::PendingSplice;
1291212860
1291312861 let post_channel_value = PendingSplice::compute_post_value(pre_channel_value, our_funding_contribution, their_funding_contribution);
1291412862 (pre_channel_value, post_channel_value)
1291512863 }
1291612864
12917- #[cfg(all(test, splicing) )]
12865+ #[cfg(splicing)]
1291812866 #[test]
1291912867 fn test_splice_compute_post_value() {
1292012868 {
0 commit comments