Merge pull request #2675 from yellowred/delayed_payment_key_types
[rust-lightning] / lightning / src / util / test_channel_signer.rs
index 99240873f326a860e99c67a27c948381c36d380c..9c6a1e30224a14b21eff915b3bc3666f96e7b2d5 100644 (file)
@@ -9,7 +9,8 @@
 
 use crate::ln::channel::{ANCHOR_OUTPUT_VALUE_SATOSHI, MIN_CHAN_DUST_LIMIT_SATOSHIS};
 use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, HolderCommitmentTransaction, CommitmentTransaction, ChannelTransactionParameters, TrustedCommitmentTransaction, ClosingTransaction};
-use crate::ln::{chan_utils, msgs, PaymentPreimage};
+use crate::ln::channel_keys::{HtlcKey};
+use crate::ln::{msgs, PaymentPreimage};
 use crate::sign::{WriteableEcdsaChannelSigner, InMemorySigner, ChannelSigner, EcdsaChannelSigner};
 
 use crate::prelude::*;
@@ -17,13 +18,15 @@ use core::cmp;
 use crate::sync::{Mutex, Arc};
 #[cfg(test)] use crate::sync::MutexGuard;
 
-use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
-use bitcoin::util::sighash;
+use bitcoin::blockdata::transaction::Transaction;
+use bitcoin::hashes::Hash;
+use bitcoin::sighash;
+use bitcoin::sighash::EcdsaSighashType;
 
 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;
@@ -56,6 +59,9 @@ pub struct TestChannelSigner {
        /// Channel state used for policy enforcement
        pub state: Arc<Mutex<EnforcementState>>,
        pub disable_revocation_policy_check: bool,
+       /// When `true` (the default), the signer will respond immediately with signatures. When `false`,
+       /// the signer will return an error indicating that it is unavailable.
+       pub available: Arc<Mutex<bool>>,
 }
 
 impl PartialEq for TestChannelSigner {
@@ -71,7 +77,8 @@ impl TestChannelSigner {
                Self {
                        inner,
                        state,
-                       disable_revocation_policy_check: false
+                       disable_revocation_policy_check: false,
+                       available: Arc::new(Mutex::new(true)),
                }
        }
 
@@ -84,7 +91,8 @@ impl TestChannelSigner {
                Self {
                        inner,
                        state,
-                       disable_revocation_policy_check
+                       disable_revocation_policy_check,
+                       available: Arc::new(Mutex::new(true)),
                }
        }
 
@@ -94,6 +102,16 @@ impl TestChannelSigner {
        pub fn get_enforcement_state(&self) -> MutexGuard<EnforcementState> {
                self.state.lock().unwrap()
        }
+
+       /// Marks the signer's availability.
+       ///
+       /// When `true`, methods are forwarded to the underlying signer as normal. When `false`, some
+       /// methods will return `Err` indicating that the signer is unavailable. Intended to be used for
+       /// testing asynchronous signing.
+       #[cfg(test)]
+       pub fn set_available(&self, available: bool) {
+               *self.available.lock().unwrap() = available;
+       }
 }
 
 impl ChannelSigner for TestChannelSigner {
@@ -133,6 +151,9 @@ impl EcdsaChannelSigner for TestChannelSigner {
                self.verify_counterparty_commitment_tx(commitment_tx, secp_ctx);
 
                {
+                       if !*self.available.lock().unwrap() {
+                               return Err(());
+                       }
                        let mut state = self.state.lock().unwrap();
                        let actual_commitment_number = commitment_tx.commitment_number();
                        let last_commitment_number = state.last_counterparty_commitment;
@@ -149,6 +170,9 @@ impl EcdsaChannelSigner for TestChannelSigner {
        }
 
        fn validate_counterparty_revocation(&self, idx: u64, _secret: &SecretKey) -> Result<(), ()> {
+               if !*self.available.lock().unwrap() {
+                       return Err(());
+               }
                let mut state = self.state.lock().unwrap();
                assert!(idx == state.last_counterparty_revoked_commitment || idx == state.last_counterparty_revoked_commitment - 1, "expecting to validate the current or next counterparty revocation - trying {}, current {}", idx, state.last_counterparty_revoked_commitment);
                state.last_counterparty_revoked_commitment = idx;
@@ -156,6 +180,9 @@ impl EcdsaChannelSigner for TestChannelSigner {
        }
 
        fn sign_holder_commitment(&self, commitment_tx: &HolderCommitmentTransaction, secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()> {
+               if !*self.available.lock().unwrap() {
+                       return Err(());
+               }
                let trusted_tx = self.verify_holder_commitment_tx(commitment_tx, secp_ctx);
                let state = self.state.lock().unwrap();
                let commitment_number = trusted_tx.commitment_number();
@@ -206,11 +233,12 @@ impl EcdsaChannelSigner for TestChannelSigner {
                        let sighash = &sighash::SighashCache::new(&*htlc_tx).segwit_signature_hash(
                                input, &witness_script, htlc_descriptor.htlc.amount_msat / 1000, sighash_type
                        ).unwrap();
-                       let countersignatory_htlc_key = chan_utils::derive_public_key(
-                               &secp_ctx, &htlc_descriptor.per_commitment_point, &self.inner.counterparty_pubkeys().unwrap().htlc_basepoint
+                       let countersignatory_htlc_key = HtlcKey::from_basepoint(
+                               &secp_ctx, &self.inner.counterparty_pubkeys().unwrap().htlc_basepoint, &htlc_descriptor.per_commitment_point,
                        );
+
                        secp_ctx.verify_ecdsa(
-                               &hash_to_message!(&sighash), &htlc_descriptor.counterparty_sig, &countersignatory_htlc_key
+                               &hash_to_message!(sighash.as_byte_array()), &htlc_descriptor.counterparty_sig, &countersignatory_htlc_key.to_public_key()
                        ).unwrap();
                }
                Ok(self.inner.sign_holder_htlc_transaction(htlc_tx, input, htlc_descriptor, secp_ctx).unwrap())