X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchan_utils.rs;h=9699cc78a1a3253a7635277d22c133a3517b2804;hb=746f25aed06c19b3a4d4bfb25d15b3b08ed410a0;hp=bbf0be78893d12e02d62595fb5936410e212ac3d;hpb=f7211fbf7907508a9ff2744ed56e60ed736e931d;p=rust-lightning diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index bbf0be78..9699cc78 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -8,7 +8,7 @@ // licenses. //! Various utilities for building scripts and deriving keys related to channels. These are -//! largely of interest for those implementing chain::keysinterface::Sign message signing by hand. +//! largely of interest for those implementing the traits on [`chain::keysinterface`] by hand. use bitcoin::blockdata::script::{Script,Builder}; use bitcoin::blockdata::opcodes; @@ -21,6 +21,7 @@ use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::ripemd160::Hash as Ripemd160; use bitcoin::hash_types::{Txid, PubkeyHash}; +use crate::chain::keysinterface::EntropySource; use crate::ln::{PaymentHash, PaymentPreimage}; use crate::ln::msgs::DecodeError; use crate::util::ser::{Readable, Writeable, Writer}; @@ -39,7 +40,7 @@ use crate::util::transaction_utils::sort_outputs; use crate::ln::channel::{INITIAL_COMMITMENT_NUMBER, ANCHOR_OUTPUT_VALUE_SATOSHI}; use core::ops::Deref; use crate::chain; -use crate::util::crypto::sign; +use crate::util::crypto::{sign, sign_with_aux_rand}; /// Maximum number of one-way in-flight HTLC (protocol-level value). pub const MAX_HTLCS: u16 = 483; @@ -660,13 +661,17 @@ pub fn make_funding_redeemscript(broadcaster: &PublicKey, countersignatory: &Pub let broadcaster_funding_key = broadcaster.serialize(); let countersignatory_funding_key = countersignatory.serialize(); + make_funding_redeemscript_from_slices(&broadcaster_funding_key, &countersignatory_funding_key) +} + +pub(crate) fn make_funding_redeemscript_from_slices(broadcaster_funding_key: &[u8], countersignatory_funding_key: &[u8]) -> Script { let builder = Builder::new().push_opcode(opcodes::all::OP_PUSHNUM_2); if broadcaster_funding_key[..] < countersignatory_funding_key[..] { - builder.push_slice(&broadcaster_funding_key) - .push_slice(&countersignatory_funding_key) + builder.push_slice(broadcaster_funding_key) + .push_slice(countersignatory_funding_key) } else { - builder.push_slice(&countersignatory_funding_key) - .push_slice(&broadcaster_funding_key) + builder.push_slice(countersignatory_funding_key) + .push_slice(broadcaster_funding_key) }.push_opcode(opcodes::all::OP_PUSHNUM_2).push_opcode(opcodes::all::OP_CHECKMULTISIG).into_script() } @@ -807,7 +812,7 @@ pub fn build_anchor_input_witness(funding_key: &PublicKey, funding_sig: &Signatu /// /// Normally, this is converted to the broadcaster/countersignatory-organized DirectedChannelTransactionParameters /// before use, via the as_holder_broadcastable and as_counterparty_broadcastable functions. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct ChannelTransactionParameters { /// Holder public keys pub holder_pubkeys: ChannelPublicKeys, @@ -831,7 +836,7 @@ pub struct ChannelTransactionParameters { } /// Late-bound per-channel counterparty data used to build transactions. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct CounterpartyChannelTransactionParameters { /// Counter-party public keys pub pubkeys: ChannelPublicKeys, @@ -980,7 +985,7 @@ impl_writeable_tlv_based!(HolderCommitmentTransaction, { impl HolderCommitmentTransaction { #[cfg(test)] - pub fn dummy() -> Self { + pub fn dummy(htlcs: &mut Vec<(HTLCOutputInCommitment, ())>) -> Self { let secp_ctx = Secp256k1::new(); let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); let dummy_sig = sign(&secp_ctx, &secp256k1::Message::from_slice(&[42; 32]).unwrap(), &SecretKey::from_slice(&[42; 32]).unwrap()); @@ -1008,12 +1013,16 @@ impl HolderCommitmentTransaction { opt_anchors: None, opt_non_zero_fee_anchors: None, }; - let mut htlcs_with_aux: Vec<(_, ())> = Vec::new(); - let inner = CommitmentTransaction::new_with_auxiliary_htlc_data(0, 0, 0, false, dummy_key.clone(), dummy_key.clone(), keys, 0, &mut htlcs_with_aux, &channel_parameters.as_counterparty_broadcastable()); + let mut counterparty_htlc_sigs = Vec::new(); + for _ in 0..htlcs.len() { + counterparty_htlc_sigs.push(dummy_sig); + } + let inner = CommitmentTransaction::new_with_auxiliary_htlc_data(0, 0, 0, false, dummy_key.clone(), dummy_key.clone(), keys, 0, htlcs, &channel_parameters.as_counterparty_broadcastable()); + htlcs.sort_by_key(|htlc| htlc.0.transaction_output_index); HolderCommitmentTransaction { inner, counterparty_sig: dummy_sig, - counterparty_htlc_sigs: Vec::new(), + counterparty_htlc_sigs, holder_sig_first: false } } @@ -1073,12 +1082,20 @@ impl BuiltCommitmentTransaction { hash_to_message!(sighash) } - /// Sign a transaction, either because we are counter-signing the counterparty's transaction or - /// because we are about to broadcast a holder transaction. - pub fn sign(&self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1) -> Signature { + /// Signs the counterparty's commitment transaction. + pub fn sign_counterparty_commitment(&self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1) -> Signature { let sighash = self.get_sighash_all(funding_redeemscript, channel_value_satoshis); sign(secp_ctx, &sighash, funding_key) } + + /// Signs the holder commitment transaction because we are about to broadcast it. + pub fn sign_holder_commitment( + &self, funding_key: &SecretKey, funding_redeemscript: &Script, channel_value_satoshis: u64, + entropy_source: &ES, secp_ctx: &Secp256k1 + ) -> Signature where ES::Target: EntropySource { + let sighash = self.get_sighash_all(funding_redeemscript, channel_value_satoshis); + sign_with_aux_rand(secp_ctx, &sighash, funding_key, entropy_source) + } } /// This class tracks the per-transaction information needed to build a closing transaction and will @@ -1268,7 +1285,7 @@ impl CommitmentTransaction { /// /// Only include HTLCs that are above the dust limit for the channel. /// - /// (C-not exported) due to the generic though we likely should expose a version without + /// This is not exported to bindings users due to the generic though we likely should expose a version without pub fn new_with_auxiliary_htlc_data(commitment_number: u64, to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, opt_anchors: bool, broadcaster_funding_key: PublicKey, countersignatory_funding_key: PublicKey, keys: TxCreationKeys, feerate_per_kw: u32, htlcs_with_aux: &mut Vec<(HTLCOutputInCommitment, T)>, channel_parameters: &DirectedChannelTransactionParameters) -> CommitmentTransaction { // Sort outputs and populate output indices while keeping track of the auxiliary data let (outputs, htlcs) = Self::internal_build_outputs(&keys, to_broadcaster_value_sat, to_countersignatory_value_sat, htlcs_with_aux, channel_parameters, opt_anchors, &broadcaster_funding_key, &countersignatory_funding_key).unwrap(); @@ -1294,7 +1311,7 @@ impl CommitmentTransaction { /// Use non-zero fee anchors /// - /// (C-not exported) due to move, and also not likely to be useful for binding users + /// This is not exported to bindings users due to move, and also not likely to be useful for binding users pub fn with_non_zero_fee_anchors(mut self) -> Self { self.opt_non_zero_fee_anchors = Some(()); self @@ -1475,7 +1492,7 @@ impl CommitmentTransaction { /// which were included in this commitment transaction in output order. /// The transaction index is always populated. /// - /// (C-not exported) as we cannot currently convert Vec references to/from C, though we should + /// This is not exported to bindings users as we cannot currently convert Vec references to/from C, though we should /// expose a less effecient version which creates a Vec of references in the future. pub fn htlcs(&self) -> &Vec { &self.htlcs @@ -1555,7 +1572,10 @@ impl<'a> TrustedCommitmentTransaction<'a> { /// The returned Vec has one entry for each HTLC, and in the same order. /// /// This function is only valid in the holder commitment context, it always uses EcdsaSighashType::All. - pub fn get_htlc_sigs(&self, htlc_base_key: &SecretKey, channel_parameters: &DirectedChannelTransactionParameters, secp_ctx: &Secp256k1) -> Result, ()> { + pub fn get_htlc_sigs( + &self, htlc_base_key: &SecretKey, channel_parameters: &DirectedChannelTransactionParameters, + entropy_source: &ES, secp_ctx: &Secp256k1, + ) -> Result, ()> where ES::Target: EntropySource { let inner = self.inner; let keys = &inner.keys; let txid = inner.built.txid; @@ -1569,7 +1589,7 @@ impl<'a> TrustedCommitmentTransaction<'a> { let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key); let sighash = hash_to_message!(&sighash::SighashCache::new(&htlc_tx).segwit_signature_hash(0, &htlc_redeemscript, this_htlc.amount_msat / 1000, EcdsaSighashType::All).unwrap()[..]); - ret.push(sign(secp_ctx, &sighash, &holder_htlc_key)); + ret.push(sign_with_aux_rand(secp_ctx, &sighash, &holder_htlc_key, entropy_source)); } Ok(ret) } @@ -1635,7 +1655,7 @@ mod tests { use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment}; use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1}; use crate::util::test_utils; - use crate::chain::keysinterface::{KeysInterface, BaseSign, SignerProvider}; + use crate::chain::keysinterface::{ChannelSigner, SignerProvider}; use bitcoin::{Network, Txid}; use bitcoin::hashes::Hash; use crate::ln::PaymentHash;