diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 0310533bae6..2d70c405565 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -2410,12 +2410,14 @@ where }, None)); } - /// Executes the given callback prividing it with a [`ChannelLock`], ensuring that no other + /// Executes the given callback providing it with a [`ChannelLock`], ensuring that no other /// operation will be executed on the referenced channel at the same time. Errors if the /// channel peer is disconnected or the channel is not in a useable state. If the callback /// returns an error, the channel value and funding outpoint are reset to the values they had - /// prior to the callback call. - pub fn with_useable_channel_lock(&self, channel_id: &[u8; 32], counter_party_node_id: &PublicKey, callback: C) -> Result + /// prior to the callback call. If `commit_tx_number` is `Some`, it will be checked against the + /// next commitment number for the requested channel, and will return an error if the two + /// values differ. + pub fn with_useable_channel_lock(&self, channel_id: &[u8; 32], counter_party_node_id: &PublicKey, commit_tx_number: Option, callback: C) -> Result where C: FnOnce(&mut ChannelLock<::Signer>) -> Result { @@ -2436,6 +2438,12 @@ where return Err(APIError::ChannelUnavailable { err: "Channel is not useable.".to_string() }); } + if let Some(commit_tx_number) = commit_tx_number { + if commit_tx_number != chan.get_cur_holder_commitment_transaction_number() - 1 { + return Err(APIError::ExternalError { err: format!("Invalid commitment transaction number, expected {} but got {}", chan.get_cur_holder_commitment_transaction_number(), commit_tx_number) }); + } + } + let channel_value = chan.context.get_value_satoshis(); let own_balance = chan.context.get_available_balances(&self.fee_estimator).balance_msat; let funding_outpoint = chan.context.channel_transaction_parameters.funding_outpoint.unwrap(); @@ -2484,7 +2492,7 @@ where } } - fn get_updated_funding_outpoint_commitment_signed_internal(&self, channel_lock: &mut ChannelLock<::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, own_balance: u64) -> Result { + fn get_updated_funding_outpoint_commitment_signed_internal(&self, channel_lock: &mut ChannelLock<::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, own_balance: u64) -> Result<(CommitmentSigned, u64), APIError> { if own_balance > channel_value_satoshis * 1000 { return Err(APIError::APIMisuseError { err: "value_to_self must be smaller than channel_value".to_string() }); } @@ -2506,8 +2514,9 @@ where let res = chan.monitor_updating_restored(&self.logger, &self.node_signer, self.genesis_hash, &self.default_configuration, self.best_block.read().unwrap().height()); + let commit_tx_number = chan.get_cur_counterparty_commitment_transaction_number(); - return Ok(res.commitment_update.unwrap().commitment_signed) + return Ok((res.commitment_update.unwrap().commitment_signed, commit_tx_number)) } fn on_commitment_signed_get_raa_internal(&self, channel_lock: &mut ChannelLock<::Signer>, commitment_signature: &secp256k1::ecdsa::Signature, htlc_signatures: &[secp256k1::ecdsa::Signature]) -> Result { @@ -2695,7 +2704,7 @@ where } /// - pub fn get_updated_funding_outpoint_commitment_signed(&self, channel_lock: &mut ChannelLock<::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, value_to_self_msat: u64) -> Result { + pub fn get_updated_funding_outpoint_commitment_signed(&self, channel_lock: &mut ChannelLock<::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, value_to_self_msat: u64) -> Result<(CommitmentSigned, u64), APIError> { self.get_updated_funding_outpoint_commitment_signed_internal(channel_lock, funding_outpoint, channel_value_satoshis, value_to_self_msat) }