Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check and return commit tx number #10

Merged
merged 2 commits into from
Nov 1, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ pub use crate::ln::outbound_payment::{PaymentSendFailure, Retry, RetryableSendFa
use crate::ln::script::ShutdownScript;
use super::msgs::{CommitmentSigned, RevokeAndACK};

pub type NumberedCommitmentSigned = (CommitmentSigned, u64);

// We hold various information about HTLC relay in the HTLC objects in Channel itself:
//
// Upon receipt of an HTLC from a peer, we'll give it a PendingHTLCStatus indicating if it should
Expand Down Expand Up @@ -2410,12 +2412,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<C, RV>(&self, channel_id: &[u8; 32], counter_party_node_id: &PublicKey, callback: C) -> Result<RV, APIError>
/// 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<C, RV>(&self, channel_id: &[u8; 32], counter_party_node_id: &PublicKey, commit_tx_number: Option<u64>, callback: C) -> Result<RV, APIError>
where
C: FnOnce(&mut ChannelLock<<SP::Target as SignerProvider>::Signer>) -> Result<RV, APIError>
{
Expand All @@ -2436,6 +2440,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();
Expand Down Expand Up @@ -2484,7 +2494,7 @@ where
}
}

fn get_updated_funding_outpoint_commitment_signed_internal(&self, channel_lock: &mut ChannelLock<<SP::Target as SignerProvider>::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, own_balance: u64) -> Result<CommitmentSigned, APIError> {
fn get_updated_funding_outpoint_commitment_signed_internal(&self, channel_lock: &mut ChannelLock<<SP::Target as SignerProvider>::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, own_balance: u64) -> Result<(CommitmentSigned, u64), APIError> {
luckysori marked this conversation as resolved.
Show resolved Hide resolved
if own_balance > channel_value_satoshis * 1000 {
return Err(APIError::APIMisuseError { err: "value_to_self must be smaller than channel_value".to_string() });
}
Expand All @@ -2506,8 +2516,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<<SP::Target as SignerProvider>::Signer>, commitment_signature: &secp256k1::ecdsa::Signature, htlc_signatures: &[secp256k1::ecdsa::Signature]) -> Result<msgs::RevokeAndACK, APIError> {
Expand Down Expand Up @@ -2694,22 +2705,24 @@ where
self.close_channel_internal(channel_id, counterparty_node_id, target_feerate_sats_per_1000_weight, shutdown_script)
}

///
pub fn get_updated_funding_outpoint_commitment_signed(&self, channel_lock: &mut ChannelLock<<SP::Target as SignerProvider>::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, value_to_self_msat: u64) -> Result<CommitmentSigned, APIError> {
/// Updates the funding output and returns the `CommitmentSigned` message for the updated
/// commitment transaction, as well as the commitment transaction number.
pub fn get_updated_funding_outpoint_commitment_signed(&self, channel_lock: &mut ChannelLock<<SP::Target as SignerProvider>::Signer>, funding_outpoint: &OutPoint, channel_value_satoshis: u64, value_to_self_msat: u64) -> Result<NumberedCommitmentSigned, APIError> {
self.get_updated_funding_outpoint_commitment_signed_internal(channel_lock, funding_outpoint, channel_value_satoshis, value_to_self_msat)
}

///
/// Process and validates the given commitment signature and returns the RAA to be given to the
/// counterparty on success.
pub fn on_commitment_signed_get_raa(&self, channel_lock: &mut ChannelLock<<SP::Target as SignerProvider>::Signer>, commitment_signature: &secp256k1::ecdsa::Signature, htlc_signatures: &[secp256k1::ecdsa::Signature]) -> Result<RevokeAndACK, APIError> {
self.on_commitment_signed_get_raa_internal(channel_lock, commitment_signature, htlc_signatures)
}

///
/// Process the given RAA message.
pub fn revoke_and_ack_commitment(&self, channel_lock: &mut ChannelLock<<SP::Target as SignerProvider>::Signer>, revoke_and_ack: &RevokeAndACK) -> Result<(), APIError> {
self.revoke_and_ack_commitment_internal(channel_lock, revoke_and_ack)
}

///
/// Set the funding outpoint for the channel to the given values.
pub fn set_funding_outpoint(&self, channel_lock: &mut ChannelLock<<SP::Target as SignerProvider>::Signer>, funding_output: &OutPoint, channel_value_satoshis: u64, value_to_self_msat: u64) {
self.set_funding_outpoint_internal(channel_lock, funding_output, channel_value_satoshis, value_to_self_msat);
}
Expand Down
Loading