use crate::chain::{BestBlock, WatchedOutput};
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::transaction::{OutPoint, TransactionData};
-use crate::sign::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
+use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler};
use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
use crate::chain::Filter;
use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48};
use crate::util::byte_utils;
use crate::events::{Event, EventHandler};
-use crate::events::bump_transaction::{ChannelDerivationParameters, AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent};
+use crate::events::bump_transaction::{AnchorDescriptor, BumpTransactionEvent};
use crate::prelude::*;
use core::{cmp, mem};
use bitcoin::secp256k1;
use crate::chain::chaininterface::compute_feerate_sat_per_1000_weight;
-use crate::events::bump_transaction::{ChannelDerivationParameters, HTLCDescriptor};
-use crate::sign::{ChannelSigner, EntropySource, SignerProvider};
+use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, ChannelSigner, EntropySource, SignerProvider, WriteableEcdsaChannelSigner};
use crate::ln::msgs::DecodeError;
use crate::ln::PaymentPreimage;
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
use crate::chain::chaininterface::{ConfirmationTarget, FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER};
-use crate::sign::WriteableEcdsaChannelSigner;
use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable, VecWriter};
use crate::ln::chan_utils;
use crate::ln::chan_utils::{
ANCHOR_INPUT_WITNESS_WEIGHT, HTLC_SUCCESS_INPUT_ANCHOR_WITNESS_WEIGHT,
- HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT, ChannelTransactionParameters, HTLCOutputInCommitment
+ HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT, HTLCOutputInCommitment
};
-use crate::ln::PaymentPreimage;
use crate::prelude::*;
-use crate::sign::{EcdsaChannelSigner, SignerProvider, WriteableEcdsaChannelSigner, P2WPKH_WITNESS_WEIGHT};
+use crate::sign::{
+ ChannelDerivationParameters, HTLCDescriptor, EcdsaChannelSigner, SignerProvider,
+ WriteableEcdsaChannelSigner, P2WPKH_WITNESS_WEIGHT
+};
use crate::sync::Mutex;
use crate::util::logger::Logger;
-use bitcoin::{OutPoint, PackedLockTime, PubkeyHash, Sequence, Script, Transaction, Txid, TxIn, TxOut, Witness, WPubkeyHash};
+use bitcoin::{OutPoint, PackedLockTime, PubkeyHash, Sequence, Script, Transaction, TxIn, TxOut, Witness, WPubkeyHash};
use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR;
use bitcoin::consensus::Encodable;
use bitcoin::secp256k1;
-use bitcoin::secp256k1::{PublicKey, Secp256k1};
+use bitcoin::secp256k1::Secp256k1;
use bitcoin::secp256k1::ecdsa::Signature;
const EMPTY_SCRIPT_SIG_WEIGHT: u64 = 1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64;
const BASE_INPUT_WEIGHT: u64 = BASE_INPUT_SIZE * WITNESS_SCALE_FACTOR as u64;
-/// The parameters required to derive a channel signer via [`SignerProvider`].
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct ChannelDerivationParameters {
- /// The value in satoshis of the channel we're attempting to spend the anchor output of.
- pub value_satoshis: u64,
- /// The unique identifier to re-derive the signer for the associated channel.
- pub keys_id: [u8; 32],
- /// The necessary channel parameters that need to be provided to the re-derived signer through
- /// [`ChannelSigner::provide_channel_parameters`].
- ///
- /// [`ChannelSigner::provide_channel_parameters`]: crate::sign::ChannelSigner::provide_channel_parameters
- pub transaction_parameters: ChannelTransactionParameters,
-}
-
-impl_writeable_tlv_based!(ChannelDerivationParameters, {
- (0, value_satoshis, required),
- (2, keys_id, required),
- (4, transaction_parameters, required),
-});
-
/// A descriptor used to sign for a commitment transaction's anchor output.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AnchorDescriptor {
}
}
-/// A descriptor used to sign for a commitment transaction's HTLC output.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct HTLCDescriptor {
- /// The parameters required to derive the signer for the HTLC input.
- pub channel_derivation_parameters: ChannelDerivationParameters,
- /// The txid of the commitment transaction in which the HTLC output lives.
- pub commitment_txid: Txid,
- /// The number of the commitment transaction in which the HTLC output lives.
- pub per_commitment_number: u64,
- /// The key tweak corresponding to the number of the commitment transaction in which the HTLC
- /// output lives. This tweak is applied to all the basepoints for both parties in the channel to
- /// arrive at unique keys per commitment.
- ///
- /// See <https://github.com/lightning/bolts/blob/master/03-transactions.md#keys> for more info.
- pub per_commitment_point: PublicKey,
- /// The feerate to use on the HTLC claiming transaction. This is always `0` for HTLCs
- /// originating from a channel supporting anchor outputs, otherwise it is the channel's
- /// negotiated feerate at the time the commitment transaction was built.
- pub feerate_per_kw: u32,
- /// The details of the HTLC as it appears in the commitment transaction.
- pub htlc: HTLCOutputInCommitment,
- /// The preimage, if `Some`, to claim the HTLC output with. If `None`, the timeout path must be
- /// taken.
- pub preimage: Option<PaymentPreimage>,
- /// The counterparty's signature required to spend the HTLC output.
- pub counterparty_sig: Signature
-}
-
-impl_writeable_tlv_based!(HTLCDescriptor, {
- (0, channel_derivation_parameters, required),
- (1, feerate_per_kw, (default_value, 0)),
- (2, commitment_txid, required),
- (4, per_commitment_number, required),
- (6, per_commitment_point, required),
- (8, htlc, required),
- (10, preimage, option),
- (12, counterparty_sig, required),
-});
-
-impl HTLCDescriptor {
- /// Returns the outpoint of the HTLC output in the commitment transaction. This is the outpoint
- /// being spent by the HTLC input in the HTLC transaction.
- pub fn outpoint(&self) -> OutPoint {
- OutPoint {
- txid: self.commitment_txid,
- vout: self.htlc.transaction_output_index.unwrap(),
- }
- }
-
- /// Returns the UTXO to be spent by the HTLC input, which can be obtained via
- /// [`Self::unsigned_tx_input`].
- pub fn previous_utxo<C: secp256k1::Signing + secp256k1::Verification>(&self, secp: &Secp256k1<C>) -> TxOut {
- TxOut {
- script_pubkey: self.witness_script(secp).to_v0_p2wsh(),
- value: self.htlc.amount_msat / 1000,
- }
- }
-
- /// Returns the unsigned transaction input spending the HTLC output in the commitment
- /// transaction.
- pub fn unsigned_tx_input(&self) -> TxIn {
- chan_utils::build_htlc_input(
- &self.commitment_txid, &self.htlc, &self.channel_derivation_parameters.transaction_parameters.channel_type_features
- )
- }
-
- /// Returns the delayed output created as a result of spending the HTLC output in the commitment
- /// transaction.
- pub fn tx_output<C: secp256k1::Signing + secp256k1::Verification>(&self, secp: &Secp256k1<C>) -> TxOut {
- let channel_params = self.channel_derivation_parameters.transaction_parameters.as_holder_broadcastable();
- let broadcaster_keys = channel_params.broadcaster_pubkeys();
- let counterparty_keys = channel_params.countersignatory_pubkeys();
- let broadcaster_delayed_key = chan_utils::derive_public_key(
- secp, &self.per_commitment_point, &broadcaster_keys.delayed_payment_basepoint
- );
- let counterparty_revocation_key = chan_utils::derive_public_revocation_key(
- secp, &self.per_commitment_point, &counterparty_keys.revocation_basepoint
- );
- chan_utils::build_htlc_output(
- self.feerate_per_kw, channel_params.contest_delay(), &self.htlc,
- channel_params.channel_type_features(), &broadcaster_delayed_key, &counterparty_revocation_key
- )
- }
-
- /// Returns the witness script of the HTLC output in the commitment transaction.
- pub fn witness_script<C: secp256k1::Signing + secp256k1::Verification>(&self, secp: &Secp256k1<C>) -> Script {
- let channel_params = self.channel_derivation_parameters.transaction_parameters.as_holder_broadcastable();
- let broadcaster_keys = channel_params.broadcaster_pubkeys();
- let counterparty_keys = channel_params.countersignatory_pubkeys();
- let broadcaster_htlc_key = chan_utils::derive_public_key(
- secp, &self.per_commitment_point, &broadcaster_keys.htlc_basepoint
- );
- let counterparty_htlc_key = chan_utils::derive_public_key(
- secp, &self.per_commitment_point, &counterparty_keys.htlc_basepoint
- );
- let counterparty_revocation_key = chan_utils::derive_public_revocation_key(
- secp, &self.per_commitment_point, &counterparty_keys.revocation_basepoint
- );
- chan_utils::get_htlc_redeemscript_with_explicit_keys(
- &self.htlc, channel_params.channel_type_features(), &broadcaster_htlc_key, &counterparty_htlc_key,
- &counterparty_revocation_key,
- )
- }
-
- /// Returns the fully signed witness required to spend the HTLC output in the commitment
- /// transaction.
- pub fn tx_input_witness(&self, signature: &Signature, witness_script: &Script) -> Witness {
- chan_utils::build_htlc_input_witness(
- signature, &self.counterparty_sig, &self.preimage, witness_script,
- &self.channel_derivation_parameters.transaction_parameters.channel_type_features
- )
- }
-
- /// Derives the channel signer required to sign the HTLC input.
- pub fn derive_channel_signer<S: WriteableEcdsaChannelSigner, SP: Deref>(&self, signer_provider: &SP) -> S
- where
- SP::Target: SignerProvider<Signer = S>
- {
- let mut signer = signer_provider.derive_channel_signer(
- self.channel_derivation_parameters.value_satoshis,
- self.channel_derivation_parameters.keys_id,
- );
- signer.provide_channel_parameters(&self.channel_derivation_parameters.transaction_parameters);
- signer
- }
-}
-
/// Represents the different types of transactions, originating from LDK, to be bumped.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum BumpTransactionEvent {
///
/// [`EcdsaChannelSigner`]: crate::sign::EcdsaChannelSigner
/// [`EcdsaChannelSigner::sign_holder_htlc_transaction`]: crate::sign::EcdsaChannelSigner::sign_holder_htlc_transaction
- /// [`HTLCDescriptor::tx_input_witness`]: HTLCDescriptor::tx_input_witness
HTLCResolution {
/// The unique identifier for the claim of the HTLCs in the confirmed commitment
/// transaction.
use bitcoin::hashes::hex::FromHex;
use bitcoin::hash_types::Txid;
use bitcoin::secp256k1::Message;
- use crate::events::bump_transaction::{ChannelDerivationParameters, HTLCDescriptor};
- use crate::sign::EcdsaChannelSigner;
+ use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, EcdsaChannelSigner};
use crate::ln::PaymentPreimage;
use crate::ln::channel::{HTLCOutputInCommitment ,TxCreationKeys};
use crate::ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
use bitcoin::secp256k1::schnorr;
-use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
+use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness, Txid};
use crate::util::transaction_utils;
use crate::util::crypto::{hkdf_extract_expand_twice, sign, sign_with_aux_rand};
use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
use crate::chain::transaction::OutPoint;
-use crate::events::bump_transaction::HTLCDescriptor;
use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
use crate::ln::{chan_utils, PaymentPreimage};
use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
}
}
+/// The parameters required to derive a channel signer via [`SignerProvider`].
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct ChannelDerivationParameters {
+ /// The value in satoshis of the channel we're attempting to spend the anchor output of.
+ pub value_satoshis: u64,
+ /// The unique identifier to re-derive the signer for the associated channel.
+ pub keys_id: [u8; 32],
+ /// The necessary channel parameters that need to be provided to the re-derived signer through
+ /// [`ChannelSigner::provide_channel_parameters`].
+ pub transaction_parameters: ChannelTransactionParameters,
+}
+
+impl_writeable_tlv_based!(ChannelDerivationParameters, {
+ (0, value_satoshis, required),
+ (2, keys_id, required),
+ (4, transaction_parameters, required),
+});
+
+/// A descriptor used to sign for a commitment transaction's HTLC output.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct HTLCDescriptor {
+ /// The parameters required to derive the signer for the HTLC input.
+ pub channel_derivation_parameters: ChannelDerivationParameters,
+ /// The txid of the commitment transaction in which the HTLC output lives.
+ pub commitment_txid: Txid,
+ /// The number of the commitment transaction in which the HTLC output lives.
+ pub per_commitment_number: u64,
+ /// The key tweak corresponding to the number of the commitment transaction in which the HTLC
+ /// output lives. This tweak is applied to all the basepoints for both parties in the channel to
+ /// arrive at unique keys per commitment.
+ ///
+ /// See <https://github.com/lightning/bolts/blob/master/03-transactions.md#keys> for more info.
+ pub per_commitment_point: PublicKey,
+ /// The feerate to use on the HTLC claiming transaction. This is always `0` for HTLCs
+ /// originating from a channel supporting anchor outputs, otherwise it is the channel's
+ /// negotiated feerate at the time the commitment transaction was built.
+ pub feerate_per_kw: u32,
+ /// The details of the HTLC as it appears in the commitment transaction.
+ pub htlc: HTLCOutputInCommitment,
+ /// The preimage, if `Some`, to claim the HTLC output with. If `None`, the timeout path must be
+ /// taken.
+ pub preimage: Option<PaymentPreimage>,
+ /// The counterparty's signature required to spend the HTLC output.
+ pub counterparty_sig: Signature
+}
+
+impl_writeable_tlv_based!(HTLCDescriptor, {
+ (0, channel_derivation_parameters, required),
+ (1, feerate_per_kw, (default_value, 0)),
+ (2, commitment_txid, required),
+ (4, per_commitment_number, required),
+ (6, per_commitment_point, required),
+ (8, htlc, required),
+ (10, preimage, option),
+ (12, counterparty_sig, required),
+});
+
+impl HTLCDescriptor {
+ /// Returns the outpoint of the HTLC output in the commitment transaction. This is the outpoint
+ /// being spent by the HTLC input in the HTLC transaction.
+ pub fn outpoint(&self) -> bitcoin::OutPoint {
+ bitcoin::OutPoint {
+ txid: self.commitment_txid,
+ vout: self.htlc.transaction_output_index.unwrap(),
+ }
+ }
+
+ /// Returns the UTXO to be spent by the HTLC input, which can be obtained via
+ /// [`Self::unsigned_tx_input`].
+ pub fn previous_utxo<C: secp256k1::Signing + secp256k1::Verification>(&self, secp: &Secp256k1<C>) -> TxOut {
+ TxOut {
+ script_pubkey: self.witness_script(secp).to_v0_p2wsh(),
+ value: self.htlc.amount_msat / 1000,
+ }
+ }
+
+ /// Returns the unsigned transaction input spending the HTLC output in the commitment
+ /// transaction.
+ pub fn unsigned_tx_input(&self) -> TxIn {
+ chan_utils::build_htlc_input(
+ &self.commitment_txid, &self.htlc, &self.channel_derivation_parameters.transaction_parameters.channel_type_features
+ )
+ }
+
+ /// Returns the delayed output created as a result of spending the HTLC output in the commitment
+ /// transaction.
+ pub fn tx_output<C: secp256k1::Signing + secp256k1::Verification>(&self, secp: &Secp256k1<C>) -> TxOut {
+ let channel_params = self.channel_derivation_parameters.transaction_parameters.as_holder_broadcastable();
+ let broadcaster_keys = channel_params.broadcaster_pubkeys();
+ let counterparty_keys = channel_params.countersignatory_pubkeys();
+ let broadcaster_delayed_key = chan_utils::derive_public_key(
+ secp, &self.per_commitment_point, &broadcaster_keys.delayed_payment_basepoint
+ );
+ let counterparty_revocation_key = chan_utils::derive_public_revocation_key(
+ secp, &self.per_commitment_point, &counterparty_keys.revocation_basepoint
+ );
+ chan_utils::build_htlc_output(
+ self.feerate_per_kw, channel_params.contest_delay(), &self.htlc,
+ channel_params.channel_type_features(), &broadcaster_delayed_key, &counterparty_revocation_key
+ )
+ }
+
+ /// Returns the witness script of the HTLC output in the commitment transaction.
+ pub fn witness_script<C: secp256k1::Signing + secp256k1::Verification>(&self, secp: &Secp256k1<C>) -> Script {
+ let channel_params = self.channel_derivation_parameters.transaction_parameters.as_holder_broadcastable();
+ let broadcaster_keys = channel_params.broadcaster_pubkeys();
+ let counterparty_keys = channel_params.countersignatory_pubkeys();
+ let broadcaster_htlc_key = chan_utils::derive_public_key(
+ secp, &self.per_commitment_point, &broadcaster_keys.htlc_basepoint
+ );
+ let counterparty_htlc_key = chan_utils::derive_public_key(
+ secp, &self.per_commitment_point, &counterparty_keys.htlc_basepoint
+ );
+ let counterparty_revocation_key = chan_utils::derive_public_revocation_key(
+ secp, &self.per_commitment_point, &counterparty_keys.revocation_basepoint
+ );
+ chan_utils::get_htlc_redeemscript_with_explicit_keys(
+ &self.htlc, channel_params.channel_type_features(), &broadcaster_htlc_key, &counterparty_htlc_key,
+ &counterparty_revocation_key,
+ )
+ }
+
+ /// Returns the fully signed witness required to spend the HTLC output in the commitment
+ /// transaction.
+ pub fn tx_input_witness(&self, signature: &Signature, witness_script: &Script) -> Witness {
+ chan_utils::build_htlc_input_witness(
+ signature, &self.counterparty_sig, &self.preimage, witness_script,
+ &self.channel_derivation_parameters.transaction_parameters.channel_type_features
+ )
+ }
+
+ /// Derives the channel signer required to sign the HTLC input.
+ pub fn derive_channel_signer<S: WriteableEcdsaChannelSigner, SP: Deref>(&self, signer_provider: &SP) -> S
+ where
+ SP::Target: SignerProvider<Signer = S>
+ {
+ let mut signer = signer_provider.derive_channel_signer(
+ self.channel_derivation_parameters.value_satoshis,
+ self.channel_derivation_parameters.keys_id,
+ );
+ signer.provide_channel_parameters(&self.channel_derivation_parameters.transaction_parameters);
+ signer
+ }
+}
+
/// A trait to handle Lightning channel key material without concretizing the channel type or
/// the signature mechanism.
pub trait ChannelSigner {
use bitcoin::secp256k1;
use bitcoin::secp256k1::{SecretKey, PublicKey};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
-use crate::events::bump_transaction::HTLCDescriptor;
+use crate::sign::HTLCDescriptor;
use crate::util::ser::{Writeable, Writer};
use crate::io::Error;
use crate::ln::features::ChannelTypeFeatures;