Use rust-bitcoin's new SigHashCache instead of SignatureHashComp's
[rust-lightning] / lightning / src / ln / chan_utils.rs
index 6e29f22801a50ea4b1163233ab5ca63cecde5fc4..c5e36e2d0ceef192094f356cbb1e434fe2868bb7 100644 (file)
@@ -30,6 +30,7 @@ use util::byte_utils;
 
 use bitcoin::secp256k1::key::{SecretKey, PublicKey};
 use bitcoin::secp256k1::{Secp256k1, Signature};
+use bitcoin::secp256k1::Error as SecpError;
 use bitcoin::secp256k1;
 
 use std::{cmp, mem};
@@ -317,7 +318,7 @@ impl PreCalculatedTxCreationKeys {
        }
 
        /// The transaction per-commitment point
-       pub fn per_comitment_point(&self) -> &PublicKey {
+       pub fn per_commitment_point(&self) -> &PublicKey {
                &self.0.per_commitment_point
        }
 }
@@ -357,7 +358,7 @@ impl_writeable!(ChannelPublicKeys, 33*5, {
 
 impl TxCreationKeys {
        /// Create a new TxCreationKeys from channel base points and the per-commitment point
-       pub fn new<T: secp256k1::Signing + secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, a_delayed_payment_base: &PublicKey, a_htlc_base: &PublicKey, b_revocation_base: &PublicKey, b_htlc_base: &PublicKey) -> Result<TxCreationKeys, secp256k1::Error> {
+       pub fn derive_new<T: secp256k1::Signing + secp256k1::Verification>(secp_ctx: &Secp256k1<T>, per_commitment_point: &PublicKey, a_delayed_payment_base: &PublicKey, a_htlc_base: &PublicKey, b_revocation_base: &PublicKey, b_htlc_base: &PublicKey) -> Result<TxCreationKeys, SecpError> {
                Ok(TxCreationKeys {
                        per_commitment_point: per_commitment_point.clone(),
                        revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?,
@@ -599,11 +600,26 @@ impl LocalCommitmentTransaction {
        }
 
        /// Generate a new LocalCommitmentTransaction based on a raw commitment transaction,
-       /// remote signature and both parties keys
+       /// remote signature and both parties keys.
+       ///
+       /// The unsigned transaction outputs must be consistent with htlc_data.  This function
+       /// only checks that the shape and amounts are consistent, but does not check the scriptPubkey.
        pub fn new_missing_local_sig(unsigned_tx: Transaction, their_sig: Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u32, htlc_data: Vec<(HTLCOutputInCommitment, Option<Signature>)>) -> LocalCommitmentTransaction {
                if unsigned_tx.input.len() != 1 { panic!("Tried to store a commitment transaction that had input count != 1!"); }
                if unsigned_tx.input[0].witness.len() != 0 { panic!("Tried to store a signed commitment transaction?"); }
 
+               for htlc in &htlc_data {
+                       if let Some(index) = htlc.0.transaction_output_index {
+                               let out = &unsigned_tx.output[index as usize];
+                               if out.value != htlc.0.amount_msat / 1000 {
+                                       panic!("HTLC at index {} has incorrect amount", index);
+                               }
+                               if !out.script_pubkey.is_v0_p2wsh() {
+                                       panic!("HTLC at index {} doesn't have p2wsh scriptPubkey", index);
+                               }
+                       }
+               }
+
                Self {
                        unsigned_tx,
                        their_sig,
@@ -635,8 +651,8 @@ impl LocalCommitmentTransaction {
        /// ChannelKeys::sign_local_commitment() calls directly.
        /// Channel value is amount locked in funding_outpoint.
        pub fn get_local_sig<T: secp256k1::Signing>(&self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>) -> Signature {
-               let sighash = hash_to_message!(&bip143::SighashComponents::new(&self.unsigned_tx)
-                       .sighash_all(&self.unsigned_tx.input[0], funding_redeemscript, channel_value_satoshis)[..]);
+               let sighash = hash_to_message!(&bip143::SigHashCache::new(&self.unsigned_tx)
+                       .signature_hash(0, funding_redeemscript, channel_value_satoshis, SigHashType::All)[..]);
                secp_ctx.sign(&sighash, funding_key)
        }
 
@@ -676,7 +692,7 @@ impl LocalCommitmentTransaction {
 
                                let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc.0, &self.local_keys.a_htlc_key, &self.local_keys.b_htlc_key, &self.local_keys.revocation_key);
 
-                               let sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, this_htlc.0.amount_msat / 1000)[..]);
+                               let sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, this_htlc.0.amount_msat / 1000, SigHashType::All)[..]);
                                ret.push(Some(secp_ctx.sign(&sighash, &our_htlc_key)));
                        } else {
                                ret.push(None);