- if let Some(htlc_outputs) = self.counterparty_claimable_outpoints.get(&commitment_txid) {
- if let Some(revocation_points) = self.their_cur_revocation_points {
- let revocation_point_option =
- // If the counterparty commitment tx is the latest valid state, use their latest
- // per-commitment point
- if revocation_points.0 == commitment_number { Some(&revocation_points.1) }
- else if let Some(point) = revocation_points.2.as_ref() {
- // If counterparty commitment tx is the state previous to the latest valid state, use
- // their previous per-commitment point (non-atomicity of revocation means it's valid for
- // them to temporarily have two valid commitment txns from our viewpoint)
- if revocation_points.0 == commitment_number + 1 { Some(point) } else { None }
- } else { None };
- if let Some(revocation_point) = revocation_point_option {
- for (_, &(ref htlc, _)) in htlc_outputs.iter().enumerate() {
- if let Some(transaction_output_index) = htlc.transaction_output_index {
- if let Some(transaction) = tx {
- if transaction_output_index as usize >= transaction.output.len() ||
- transaction.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
- return claimable_outpoints; // Corrupted per_commitment_data, fuck this user
- }
- }
- let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
- if preimage.is_some() || !htlc.offered {
- let counterparty_htlc_outp = if htlc.offered { PackageSolvingData::CounterpartyOfferedHTLCOutput(CounterpartyOfferedHTLCOutput::build(*revocation_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, preimage.unwrap(), htlc.clone())) } else { PackageSolvingData::CounterpartyReceivedHTLCOutput(CounterpartyReceivedHTLCOutput::build(*revocation_point, self.counterparty_commitment_params.counterparty_delayed_payment_base_key, self.counterparty_commitment_params.counterparty_htlc_base_key, htlc.clone())) };
- let aggregation = if !htlc.offered { false } else { true };
- let counterparty_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc.cltv_expiry,aggregation, 0);
- claimable_outpoints.push(counterparty_package);
- }
- }
+ let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None;
+
+ let htlc_outputs = match self.counterparty_claimable_outpoints.get(&commitment_txid) {
+ Some(outputs) => outputs,
+ None => return (claimable_outpoints, to_counterparty_output_info),
+ };
+ let per_commitment_points = match self.their_cur_per_commitment_points {
+ Some(points) => points,
+ None => return (claimable_outpoints, to_counterparty_output_info),
+ };
+
+ let per_commitment_point =
+ // If the counterparty commitment tx is the latest valid state, use their latest
+ // per-commitment point
+ if per_commitment_points.0 == commitment_number { &per_commitment_points.1 }
+ else if let Some(point) = per_commitment_points.2.as_ref() {
+ // If counterparty commitment tx is the state previous to the latest valid state, use
+ // their previous per-commitment point (non-atomicity of revocation means it's valid for
+ // them to temporarily have two valid commitment txns from our viewpoint)
+ if per_commitment_points.0 == commitment_number + 1 {
+ point
+ } else { return (claimable_outpoints, to_counterparty_output_info); }
+ } else { return (claimable_outpoints, to_counterparty_output_info); };
+
+ if let Some(transaction) = tx {
+ let revokeable_p2wsh_opt =
+ if let Ok(revocation_pubkey) = chan_utils::derive_public_revocation_key(
+ &self.secp_ctx, &per_commitment_point, &self.holder_revocation_basepoint)
+ {
+ if let Ok(delayed_key) = chan_utils::derive_public_key(&self.secp_ctx,
+ &per_commitment_point,
+ &self.counterparty_commitment_params.counterparty_delayed_payment_base_key)
+ {
+ Some(chan_utils::get_revokeable_redeemscript(&revocation_pubkey,
+ self.counterparty_commitment_params.on_counterparty_tx_csv,
+ &delayed_key).to_v0_p2wsh())
+ } else {
+ debug_assert!(false, "Failed to derive a delayed payment key for a commitment state we accepted");
+ None
+ }
+ } else {
+ debug_assert!(false, "Failed to derive a revocation pubkey key for a commitment state we accepted");
+ None
+ };
+ if let Some(revokeable_p2wsh) = revokeable_p2wsh_opt {
+ for (idx, outp) in transaction.output.iter().enumerate() {
+ if outp.script_pubkey == revokeable_p2wsh {
+ to_counterparty_output_info =
+ Some((idx.try_into().expect("Can't have > 2^32 outputs"), outp.value));