X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchan_utils.rs;h=43f567933fdf7ebe25f0dcbb8c79e826fcb1d97d;hb=3ea13194e8ad3ea3493ca4ba63cd215eee105feb;hp=566fd7b00d8358182c20d9256626d41e791bce68;hpb=ba75b3ecd7f88a79ff6392a5229c4ab6c14a8591;p=rust-lightning diff --git a/lightning/src/ln/chan_utils.rs b/lightning/src/ln/chan_utils.rs index 566fd7b0..43f56793 100644 --- a/lightning/src/ln/chan_utils.rs +++ b/lightning/src/ln/chan_utils.rs @@ -485,9 +485,8 @@ pub fn build_htlc_transaction(prev_hash: &Sha256dHash, feerate_per_kw: u64, to_s /// just pass in the SecretKeys required. pub struct LocalCommitmentTransaction { tx: Transaction, - //TODO: modify Channel methods to integrate HTLC material at LocalCommitmentTransaction generation to drop Option here - local_keys: Option, - feerate_per_kw: Option, + pub(crate) local_keys: TxCreationKeys, + pub(crate) feerate_per_kw: u64, per_htlc: Vec<(HTLCOutputInCommitment, Option, Option)> } impl LocalCommitmentTransaction { @@ -502,21 +501,30 @@ impl LocalCommitmentTransaction { sequence: 0, witness: vec![vec![], vec![], vec![]] }; - Self { tx: Transaction { - version: 2, - input: vec![dummy_input], - output: Vec::new(), - lock_time: 0, - }, - local_keys: None, - feerate_per_kw: None, + let dummy_key = PublicKey::from_secret_key(&Secp256k1::new(), &SecretKey::from_slice(&[42; 32]).unwrap()); + Self { + tx: Transaction { + version: 2, + input: vec![dummy_input], + output: Vec::new(), + lock_time: 0, + }, + local_keys: TxCreationKeys { + per_commitment_point: dummy_key.clone(), + revocation_key: dummy_key.clone(), + a_htlc_key: dummy_key.clone(), + b_htlc_key: dummy_key.clone(), + a_delayed_payment_key: dummy_key.clone(), + b_payment_key: dummy_key.clone(), + }, + feerate_per_kw: 0, per_htlc: Vec::new() } } /// Generate a new LocalCommitmentTransaction based on a raw commitment transaction, /// remote signature and both parties keys - pub(crate) fn new_missing_local_sig(mut tx: Transaction, their_sig: &Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey) -> LocalCommitmentTransaction { + pub(crate) fn new_missing_local_sig(mut tx: Transaction, their_sig: &Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey, local_keys: TxCreationKeys, feerate_per_kw: u64, mut htlc_data: Vec<(HTLCOutputInCommitment, Option)>) -> LocalCommitmentTransaction { if tx.input.len() != 1 { panic!("Tried to store a commitment transaction that had input count != 1!"); } if tx.input[0].witness.len() != 0 { panic!("Tried to store a signed commitment transaction?"); } @@ -533,9 +541,10 @@ impl LocalCommitmentTransaction { } Self { tx, - local_keys: None, - feerate_per_kw: None, - per_htlc: Vec::new() + local_keys, + feerate_per_kw, + // TODO: Avoid the conversion of a Vec created likely just for this: + per_htlc: htlc_data.drain(..).map(|(a, b)| (a, b, None)).collect(), } } @@ -594,33 +603,23 @@ impl LocalCommitmentTransaction { &self.tx } - /// Set HTLC cache to generate any local HTLC transaction spending one of htlc ouput - /// from this local commitment transaction - pub(crate) fn set_htlc_cache(&mut self, local_keys: TxCreationKeys, feerate_per_kw: u64, htlc_outputs: Vec<(HTLCOutputInCommitment, Option, Option)>) { - self.local_keys = Some(local_keys); - self.feerate_per_kw = Some(feerate_per_kw); - self.per_htlc = htlc_outputs; - } - /// Add local signature for a htlc transaction, do nothing if a cached signed transaction is /// already present pub fn add_htlc_sig(&mut self, htlc_base_key: &SecretKey, htlc_index: u32, preimage: Option, local_csv: u16, secp_ctx: &Secp256k1) { - if self.local_keys.is_none() || self.feerate_per_kw.is_none() { return; } - let local_keys = self.local_keys.as_ref().unwrap(); let txid = self.txid(); for this_htlc in self.per_htlc.iter_mut() { - if this_htlc.0.transaction_output_index.unwrap() == htlc_index { + if this_htlc.0.transaction_output_index == Some(htlc_index) { if this_htlc.2.is_some() { return; } // we already have a cached htlc transaction at provided index - let mut htlc_tx = build_htlc_transaction(&txid, self.feerate_per_kw.unwrap(), local_csv, &this_htlc.0, &local_keys.a_delayed_payment_key, &local_keys.revocation_key); + let mut htlc_tx = build_htlc_transaction(&txid, self.feerate_per_kw, local_csv, &this_htlc.0, &self.local_keys.a_delayed_payment_key, &self.local_keys.revocation_key); if !this_htlc.0.offered && preimage.is_none() { return; } // if we don't have preimage for HTLC-Success, don't try to generate let htlc_secret = if !this_htlc.0.offered { preimage } else { None }; // if we have a preimage for HTLC-Timeout, don't use it that's likely a duplicate HTLC hash if this_htlc.1.is_none() { return; } // we don't have any remote signature for this htlc if htlc_tx.input.len() != 1 { return; } if htlc_tx.input[0].witness.len() != 0 { return; } - let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc.0, &local_keys.a_htlc_key, &local_keys.b_htlc_key, &local_keys.revocation_key); + 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); - if let Ok(our_htlc_key) = derive_private_key(secp_ctx, &local_keys.per_commitment_point, htlc_base_key) { + if let Ok(our_htlc_key) = derive_private_key(secp_ctx, &self.local_keys.per_commitment_point, htlc_base_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 our_sig = secp_ctx.sign(&sighash, &our_htlc_key);