use bitcoin::{secp256k1, Sequence, Witness, Txid};
use crate::util::transaction_utils;
-use crate::util::crypto::{hkdf_extract_expand_twice, sign, sign_with_aux_rand};
+use crate::crypto::utils::{hkdf_extract_expand_twice, sign, sign_with_aux_rand};
use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
use crate::chain::transaction::OutPoint;
use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
use core::ops::Deref;
use core::sync::atomic::{AtomicUsize, Ordering};
#[cfg(taproot)]
-use musig2::types::{PartialSignature, PublicNonce, SecretNonce};
+use musig2::types::{PartialSignature, PublicNonce};
use crate::io::{self, Error};
use crate::ln::features::ChannelTypeFeatures;
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
#[cfg(taproot)]
use crate::sign::taproot::TaprootChannelSigner;
use crate::util::atomic_counter::AtomicCounter;
-use crate::util::chacha20::ChaCha20;
+use crate::crypto::chacha20::ChaCha20;
use crate::util::invoice::construct_invoice_preimage;
pub(crate) mod type_resolver;
outpoint: OutPoint,
/// The output which is referenced by the given outpoint.
output: TxOut,
+ /// The `channel_keys_id` for the channel which this output came from.
+ ///
+ /// For channels which were generated on LDK 0.0.119 or later, this is the value which was
+ /// passed to the [`SignerProvider::get_destination_script`] call which provided this
+ /// output script.
+ ///
+ /// For channels which were generated prior to LDK 0.0.119, no such argument existed,
+ /// however this field may still be filled in if such data is available.
+ channel_keys_id: Option<[u8; 32]>
},
/// An output to a P2WSH script which can be spent with a single signature after an `OP_CSV`
/// delay.
impl_writeable_tlv_based_enum!(SpendableOutputDescriptor,
(0, StaticOutput) => {
(0, outpoint, required),
+ (1, channel_keys_id, option),
(2, output, required),
},
;
{ witness_weight -= 1; } // Guarantees a low R signature
input_value += descriptor.output.value;
},
- SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => {
+ SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output, .. } => {
if !output_set.insert(*outpoint) { return Err(()); }
input.push(TxIn {
previous_output: outpoint.into_bitcoin_outpoint(),
/// Policy checks should be implemented in this function, including checking the amount
/// sent to us and checking the HTLCs.
///
- /// The preimages of outgoing HTLCs that were fulfilled since the last commitment are provided.
+ /// The preimages of outbound HTLCs that were fulfilled since the last commitment are provided.
/// A validating signer should ensure that an HTLC output is removed only when the matching
/// preimage is provided, or when the value to holder is restored.
///
/// Note that all the relevant preimages will be provided, but there may also be additional
/// irrelevant or duplicate preimages.
fn validate_holder_commitment(&self, holder_tx: &HolderCommitmentTransaction,
- preimages: Vec<PaymentPreimage>) -> Result<(), ()>;
+ outbound_htlc_preimages: Vec<PaymentPreimage>) -> Result<(), ()>;
+
+ /// Validate the counterparty's revocation.
+ ///
+ /// This is required in order for the signer to make sure that the state has moved
+ /// forward and it is safe to sign the next counterparty commitment.
+ fn validate_counterparty_revocation(&self, idx: u64, secret: &SecretKey) -> Result<(), ()>;
/// Returns the holder's channel public keys and basepoints.
fn pubkeys(&self) -> &ChannelPublicKeys;
chan_utils::build_commitment_secret(&self.commitment_seed, idx)
}
- fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction, _preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
+ fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction, _outbound_htlc_preimages: Vec<PaymentPreimage>) -> Result<(), ()> {
+ Ok(())
+ }
+
+ fn validate_counterparty_revocation(&self, _idx: u64, _secret: &SecretKey) -> Result<(), ()> {
Ok(())
}
const MISSING_PARAMS_ERR: &'static str = "ChannelSigner::provide_channel_parameters must be called before signing operations";
impl EcdsaChannelSigner for InMemorySigner {
- fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
+ fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _inbound_htlc_preimages: Vec<PaymentPreimage>, _outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<(Signature, Vec<Signature>), ()> {
let trusted_tx = commitment_tx.trust();
let keys = trusted_tx.keys();
Ok((commitment_sig, htlc_sigs))
}
- fn validate_counterparty_revocation(&self, _idx: u64, _secret: &SecretKey) -> Result<(), ()> {
- Ok(())
- }
-
fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key);
let counterparty_keys = self.counterparty_pubkeys().expect(MISSING_PARAMS_ERR);
todo!()
}
- fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<All>) -> Result<(PartialSignatureWithNonce, Vec<schnorr::Signature>), ()> {
+ fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec<PaymentPreimage>, outbound_htlc_preimages: Vec<PaymentPreimage>, secp_ctx: &Secp256k1<All>) -> Result<(PartialSignatureWithNonce, Vec<schnorr::Signature>), ()> {
todo!()
}
- fn finalize_holder_commitment(&self, commitment_number: u64, commitment_tx: &HolderCommitmentTransaction, counterparty_partial_signature: PartialSignatureWithNonce, secp_ctx: &Secp256k1<All>) -> Result<PartialSignature, ()> {
+ fn finalize_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, counterparty_partial_signature: PartialSignatureWithNonce, secp_ctx: &Secp256k1<All>) -> Result<PartialSignature, ()> {
todo!()
}
let witness = keys_cache.as_ref().unwrap().0.sign_dynamic_p2wsh_input(&psbt.unsigned_tx, input_idx, &descriptor, &secp_ctx)?;
psbt.inputs[input_idx].final_script_witness = Some(witness);
},
- SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output } => {
+ SpendableOutputDescriptor::StaticOutput { ref outpoint, ref output, .. } => {
let input_idx = psbt.unsigned_tx.input.iter().position(|i| i.previous_output == outpoint.into_bitcoin_outpoint()).ok_or(())?;
let derivation_idx = if output.script_pubkey == self.destination_script {
1