/// transaction which appeared on chain.
commitment_tx_output_idx: Option<u32>,
},
+ /// An output waiting on [`ANTI_REORG_DELAY`] confirmations before we hand the user the
+ /// [`SpendableOutputDescriptor`].
MaturingOutput {
descriptor: SpendableOutputDescriptor,
},
/// * an inbound HTLC is claimed by us (with a preimage).
/// * a revoked-state HTLC transaction was broadcasted, which was claimed by the revocation
/// signature.
+ /// * a revoked-state HTLC transaction was broadcasted, which was claimed by an
+ /// HTLC-Success/HTLC-Failure transaction (and is still claimable with a revocation
+ /// signature).
HTLCSpendConfirmation {
commitment_tx_output_idx: u32,
/// If the claim was made by either party with a preimage, this is filled in
#[derive(PartialEq)]
struct IrrevocablyResolvedHTLC {
commitment_tx_output_idx: u32,
+ /// The txid of the transaction which resolved the HTLC, this may be a commitment (if the HTLC
+ /// was not present in the confirmed commitment transaction), HTLC-Success, or HTLC-Timeout
+ /// transaction.
+ resolving_txid: Option<Txid>, // Added as optional, but always filled in, in 0.0.110
/// Only set if the HTLC claim was ours using a payment preimage
payment_preimage: Option<PaymentPreimage>,
}
impl_writeable_tlv_based!(IrrevocablyResolvedHTLC, {
(0, commitment_tx_output_idx, required),
+ (1, resolving_txid, option),
(2, payment_preimage, option),
});
htlc_value_satoshis,
}));
if let Some(idx) = commitment_tx_output_idx {
- self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC { commitment_tx_output_idx: idx, payment_preimage: None });
+ self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC {
+ commitment_tx_output_idx: idx, resolving_txid: Some(entry.txid),
+ payment_preimage: None,
+ });
}
},
OnchainEvent::MaturingOutput { descriptor } => {
});
},
OnchainEvent::HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. } => {
- self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC { commitment_tx_output_idx, payment_preimage: preimage });
+ self.htlcs_resolved_on_chain.push(IrrevocablyResolvedHTLC {
+ commitment_tx_output_idx, resolving_txid: Some(entry.txid),
+ payment_preimage: preimage,
+ });
},
OnchainEvent::FundingSpendConfirmation { commitment_tx_to_counterparty_output, .. } => {
self.funding_spend_confirmed = Some(entry.txid);
log_error!(logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}!",
$tx_info, input.previous_output.txid, input.previous_output.vout, tx.txid(),
if outbound_htlc { "outbound" } else { "inbound" }, log_bytes!($htlc.payment_hash.0),
- if revocation_sig_claim { "revocation sig" } else { "preimage claim after we'd passed the HTLC resolution back" });
+ if revocation_sig_claim { "revocation sig" } else { "preimage claim after we'd passed the HTLC resolution back. We can likely claim the HTLC output with a revocation claim" });
} else {
log_info!(logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}",
$tx_info, input.previous_output.txid, input.previous_output.vout, tx.txid(),
if payment_data.is_none() {
log_claim!($tx_info, $holder_tx, htlc_output, false);
let outbound_htlc = $holder_tx == htlc_output.offered;
- if !outbound_htlc || revocation_sig_claim {
- self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
- txid: tx.txid(), height, transaction: Some(tx.clone()),
- event: OnchainEvent::HTLCSpendConfirmation {
- commitment_tx_output_idx: input.previous_output.vout,
- preimage: if accepted_preimage_claim || offered_preimage_claim {
- Some(payment_preimage) } else { None },
- // If this is a payment to us (!outbound_htlc, above),
- // wait for the CSV delay before dropping the HTLC from
- // claimable balance if the claim was an HTLC-Success
- // transaction.
- on_to_local_output_csv: if accepted_preimage_claim {
- Some(self.on_holder_tx_csv) } else { None },
- },
- });
- } else {
- // Outbound claims should always have payment_data, unless
- // we've already failed the HTLC as the commitment transaction
- // which was broadcasted was revoked. In that case, we should
- // spend the HTLC output here immediately, and expose that fact
- // as a Balance, something which we do not yet do.
- // TODO: Track the above as claimable!
- }
+ self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
+ txid: tx.txid(), height, transaction: Some(tx.clone()),
+ event: OnchainEvent::HTLCSpendConfirmation {
+ commitment_tx_output_idx: input.previous_output.vout,
+ preimage: if accepted_preimage_claim || offered_preimage_claim {
+ Some(payment_preimage) } else { None },
+ // If this is a payment to us (ie !outbound_htlc), wait for
+ // the CSV delay before dropping the HTLC from claimable
+ // balance if the claim was an HTLC-Success transaction (ie
+ // accepted_preimage_claim).
+ on_to_local_output_csv: if accepted_preimage_claim && !outbound_htlc {
+ Some(self.on_holder_tx_csv) } else { None },
+ },
+ });
continue 'outer_loop;
}
}