X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fsign%2Fmod.rs;h=4e418f049bbc9867a7a2a7920706e17c135ed23e;hb=75a1c47b192b693c08645d6a6697ad6d37839220;hp=9de3ed8dc534ff9d08721d5640ddbb7fa717541a;hpb=88ce7d6575dd376e98e680d0c0813c7b79151773;p=rust-lightning diff --git a/lightning/src/sign/mod.rs b/lightning/src/sign/mod.rs index 9de3ed8d..4e418f04 100644 --- a/lightning/src/sign/mod.rs +++ b/lightning/src/sign/mod.rs @@ -57,7 +57,7 @@ use core::convert::TryInto; 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}; @@ -215,6 +215,15 @@ pub enum SpendableOutputDescriptor { 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. @@ -278,6 +287,7 @@ pub enum SpendableOutputDescriptor { impl_writeable_tlv_based_enum!(SpendableOutputDescriptor, (0, StaticOutput) => { (0, outpoint, required), + (1, channel_keys_id, option), (2, output, required), }, ; @@ -378,7 +388,7 @@ impl SpendableOutputDescriptor { { 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(), @@ -584,14 +594,20 @@ pub trait ChannelSigner { /// 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) -> Result<(), ()>; + outbound_htlc_preimages: Vec) -> 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; @@ -1070,7 +1086,11 @@ impl ChannelSigner for InMemorySigner { chan_utils::build_commitment_secret(&self.commitment_seed, idx) } - fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction, _preimages: Vec) -> Result<(), ()> { + fn validate_holder_commitment(&self, _holder_tx: &HolderCommitmentTransaction, _outbound_htlc_preimages: Vec) -> Result<(), ()> { + Ok(()) + } + + fn validate_counterparty_revocation(&self, _idx: u64, _secret: &SecretKey) -> Result<(), ()> { Ok(()) } @@ -1092,7 +1112,7 @@ impl ChannelSigner for InMemorySigner { 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, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { + fn sign_counterparty_commitment(&self, commitment_tx: &CommitmentTransaction, _inbound_htlc_preimages: Vec, _outbound_htlc_preimages: Vec, secp_ctx: &Secp256k1) -> Result<(Signature, Vec), ()> { let trusted_tx = commitment_tx.trust(); let keys = trusted_tx.keys(); @@ -1121,10 +1141,6 @@ impl EcdsaChannelSigner for InMemorySigner { 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) -> Result { let funding_pubkey = PublicKey::from_secret_key(secp_ctx, &self.funding_key); let counterparty_keys = self.counterparty_pubkeys().expect(MISSING_PARAMS_ERR); @@ -1244,11 +1260,11 @@ impl TaprootChannelSigner for InMemorySigner { todo!() } - fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, preimages: Vec, secp_ctx: &Secp256k1) -> Result<(PartialSignatureWithNonce, Vec), ()> { + fn partially_sign_counterparty_commitment(&self, counterparty_nonce: PublicNonce, commitment_tx: &CommitmentTransaction, inbound_htlc_preimages: Vec, outbound_htlc_preimages: Vec, secp_ctx: &Secp256k1) -> Result<(PartialSignatureWithNonce, Vec), ()> { todo!() } - fn finalize_holder_commitment(&self, commitment_number: u64, commitment_tx: &HolderCommitmentTransaction, counterparty_partial_signature: PartialSignatureWithNonce, secp_ctx: &Secp256k1) -> Result { + fn finalize_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, counterparty_partial_signature: PartialSignatureWithNonce, secp_ctx: &Secp256k1) -> Result { todo!() } @@ -1540,7 +1556,7 @@ impl KeysManager { 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