X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchan_utils.rs;h=c5e36e2d0ceef192094f356cbb1e434fe2868bb7;hb=9d8efecadf4d5f966223b352ffc0a65a8fdfd263;hp=b5d4d490774ecf8eb8c044501f926c7f74236ae3;hpb=093fcaba68ab9d96e4570d0a4d9bcbdecc03a67f;p=rust-lightning diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index b5d4d490..c5e36e2d 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -1,3 +1,12 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + //! Various utilities for building scripts and deriving keys related to channels. These are //! largely of interest for those implementing chain::keysinterface::ChannelKeys message signing //! by hand. @@ -21,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}; @@ -308,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 } } @@ -348,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(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, a_delayed_payment_base: &PublicKey, a_htlc_base: &PublicKey, b_revocation_base: &PublicKey, b_htlc_base: &PublicKey) -> Result { + pub fn derive_new(secp_ctx: &Secp256k1, per_commitment_point: &PublicKey, a_delayed_payment_base: &PublicKey, a_htlc_base: &PublicKey, b_revocation_base: &PublicKey, b_htlc_base: &PublicKey) -> Result { Ok(TxCreationKeys { per_commitment_point: per_commitment_point.clone(), revocation_key: derive_public_revocation_key(&secp_ctx, &per_commitment_point, &b_revocation_base)?, @@ -590,11 +600,26 @@ impl LocalCommitmentTransaction { } /// Generate a new LocalCommitmentTransaction based on a raw commitment transaction, - /// remote signature and both parties keys - pub(crate) 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)>) -> LocalCommitmentTransaction { + /// 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)>) -> 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, @@ -626,8 +651,8 @@ impl LocalCommitmentTransaction { /// ChannelKeys::sign_local_commitment() calls directly. /// Channel value is amount locked in funding_outpoint. pub fn get_local_sig(&self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1) -> 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) } @@ -667,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);