- for (idx, ref htlc) in per_commitment_data.0.iter().enumerate() {
- let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
- if htlc.transaction_output_index as usize >= tx.output.len() ||
- tx.output[htlc.transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
- tx.output[htlc.transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
- return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs, htlc_updated); // Corrupted per_commitment_data, fuck this user
- }
- if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
- let input = TxIn {
- previous_output: BitcoinOutPoint {
- txid: commitment_txid,
- vout: htlc.transaction_output_index,
- },
- script_sig: Script::new(),
- sequence: idx as u32, // reset to 0xfffffffd in sign_input
- witness: Vec::new(),
- };
- if htlc.cltv_expiry > height + CLTV_SHARED_CLAIM_BUFFER {
- inputs.push(input);
- values.push((tx.output[htlc.transaction_output_index as usize].value, payment_preimage));
- total_value += htlc.amount_msat / 1000;
- } else {
- let mut single_htlc_tx = Transaction {
+ for (idx, &(ref htlc, _)) in per_commitment_data.iter().enumerate() {
+ if let Some(transaction_output_index) = htlc.transaction_output_index {
+ let expected_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &a_htlc_key, &b_htlc_key, &revocation_pubkey);
+ if transaction_output_index as usize >= tx.output.len() ||
+ tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 ||
+ tx.output[transaction_output_index as usize].script_pubkey != expected_script.to_v0_p2wsh() {
+ return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs, htlc_updated); // Corrupted per_commitment_data, fuck this user
+ }
+ if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
+ let input = TxIn {
+ previous_output: BitcoinOutPoint {
+ txid: commitment_txid,
+ vout: transaction_output_index,
+ },
+ script_sig: Script::new(),
+ sequence: idx as u32, // reset to 0xfffffffd in sign_input
+ witness: Vec::new(),
+ };
+ if htlc.cltv_expiry > height + CLTV_SHARED_CLAIM_BUFFER {
+ inputs.push(input);
+ values.push((tx.output[transaction_output_index as usize].value, payment_preimage));
+ total_value += htlc.amount_msat / 1000;
+ } else {
+ let mut single_htlc_tx = Transaction {
+ version: 2,
+ lock_time: 0,
+ input: vec![input],
+ output: vec!(TxOut {
+ script_pubkey: self.destination_script.clone(),
+ value: htlc.amount_msat / 1000, //TODO: - fee
+ }),
+ };
+ let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
+ sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.0.to_vec());
+ spendable_outputs.push(SpendableOutputDescriptor::StaticOutput {
+ outpoint: BitcoinOutPoint { txid: single_htlc_tx.txid(), vout: 0 },
+ output: single_htlc_tx.output[0].clone(),
+ });
+ txn_to_broadcast.push(single_htlc_tx);
+ }
+ }
+ if !htlc.offered {
+ // TODO: If the HTLC has already expired, potentially merge it with the
+ // rest of the claim transaction, as above.
+ let input = TxIn {
+ previous_output: BitcoinOutPoint {
+ txid: commitment_txid,
+ vout: transaction_output_index,
+ },
+ script_sig: Script::new(),
+ sequence: idx as u32,
+ witness: Vec::new(),
+ };
+ let mut timeout_tx = Transaction {