- /// Expose raw htlc transaction, guarante witness is complete if non-empty
- pub fn htlc_with_valid_witness(&self, htlc_index: u32) -> &Option<Transaction> {
- for this_htlc in self.per_htlc.iter() {
- if this_htlc.0.transaction_output_index.unwrap() == htlc_index {
- return &this_htlc.2;
- }
+
+ /// Gets a signed HTLC transaction given a preimage (for !htlc.offered) and the local HTLC transaction signature.
+ pub(crate) fn get_signed_htlc_tx(&self, htlc_index: usize, signature: &Signature, preimage: &Option<PaymentPreimage>, local_csv: u16) -> Transaction {
+ let txid = self.txid();
+ let this_htlc = &self.per_htlc[htlc_index];
+ assert!(this_htlc.0.transaction_output_index.is_some());
+ // if we don't have preimage for an HTLC-Success, we can't generate an HTLC transaction.
+ if !this_htlc.0.offered && preimage.is_none() { unreachable!(); }
+ // Further, we should never be provided the preimage for an HTLC-Timeout transaction.
+ if this_htlc.0.offered && preimage.is_some() { unreachable!(); }
+
+ 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);
+ // Channel should have checked that we have a remote signature for this HTLC at
+ // creation, and we should have a sensible htlc transaction:
+ assert!(this_htlc.1.is_some());
+
+ 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);
+
+ // First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element.
+ htlc_tx.input[0].witness.push(Vec::new());
+
+ htlc_tx.input[0].witness.push(this_htlc.1.unwrap().serialize_der().to_vec());
+ htlc_tx.input[0].witness.push(signature.serialize_der().to_vec());
+ htlc_tx.input[0].witness[1].push(SigHashType::All as u8);
+ htlc_tx.input[0].witness[2].push(SigHashType::All as u8);
+
+ if this_htlc.0.offered {
+ // Due to BIP146 (MINIMALIF) this must be a zero-length element to relay.
+ htlc_tx.input[0].witness.push(Vec::new());
+ } else {
+ htlc_tx.input[0].witness.push(preimage.unwrap().0.to_vec());