Skip to content

Commit 925f220

Browse files
committed
Track HTLC on-chain value for HTLC-Success/-Timeout txn for balance
This adds tracking in the HTLC resolution of the HTLC-Success/HTLC-Timeout amounts so that we can use them in the coming commits for the `get_claimable_balance` amounts.
1 parent d657f0a commit 925f220

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ enum OnchainEvent {
361361
HTLCUpdate {
362362
source: HTLCSource,
363363
payment_hash: PaymentHash,
364+
/// If the HTLC was claimed by an HTLC-Success or HTLC-Timeout transaction (ie when the
365+
/// HTLC exists on chain), this is the amount of the output of that transaction (ie
366+
/// `htlc_value_satoshis` minus fees).
367+
onchain_value_satoshis: Option<u64>,
364368
htlc_value_satoshis: Option<u64>,
365369
/// None in the second case, above, ie when there is no relevant output in the commitment
366370
/// transaction which appeared on chain.
@@ -392,6 +396,10 @@ enum OnchainEvent {
392396
/// signature.
393397
HTLCSpendConfirmation {
394398
commitment_tx_output_idx: u32,
399+
/// If the HTLC was claimed by an HTLC-Success or HTLC-Timeout transaction (ie when the
400+
/// HTLC was not claimed via the revocation path), this is the amount of the output of that
401+
/// transaction (ie `htlc_value_satoshis` minus fees).
402+
onchain_value_satoshis: Option<u64>,
395403
/// If the claim was made by either party with a preimage, this is filled in
396404
preimage: Option<PaymentPreimage>,
397405
/// If the claim was made by us on an inbound HTLC against a local commitment transaction,
@@ -439,6 +447,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
439447
(1, htlc_value_satoshis, option),
440448
(2, payment_hash, required),
441449
(3, commitment_tx_output_idx, option),
450+
(5, onchain_value_satoshis, option),
442451
},
443452
(1, MaturingOutput) => {
444453
(0, descriptor, required),
@@ -449,6 +458,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
449458
},
450459
(5, HTLCSpendConfirmation) => {
451460
(0, commitment_tx_output_idx, required),
461+
(1, onchain_value_satoshis, option),
452462
(2, preimage, option),
453463
(4, on_to_local_output_csv, option),
454464
},
@@ -1734,6 +1744,7 @@ macro_rules! fail_unbroadcast_htlcs {
17341744
source: (**source).clone(),
17351745
payment_hash: htlc.payment_hash.clone(),
17361746
htlc_value_satoshis: Some(htlc.amount_msat / 1000),
1747+
onchain_value_satoshis: None,
17371748
commitment_tx_output_idx: None,
17381749
},
17391750
};
@@ -2666,7 +2677,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
26662677
// Produce actionable events from on-chain events having reached their threshold.
26672678
for entry in onchain_events_reaching_threshold_conf.drain(..) {
26682679
match entry.event {
2669-
OnchainEvent::HTLCUpdate { ref source, payment_hash, htlc_value_satoshis, commitment_tx_output_idx } => {
2680+
OnchainEvent::HTLCUpdate { ref source, payment_hash, htlc_value_satoshis, commitment_tx_output_idx, .. } => {
26702681
// Check for duplicate HTLC resolutions.
26712682
#[cfg(debug_assertions)]
26722683
{
@@ -2907,6 +2918,15 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29072918
#[cfg(not(fuzzing))]
29082919
let offered_timeout_claim = witness_items == 5 && htlctype == Some(HTLCType::OfferedHTLC);
29092920

2921+
let claim_via_htlc_tx = accepted_preimage_claim || offered_timeout_claim;
2922+
if claim_via_htlc_tx {
2923+
// If the claim was via an HTLC-Timeout/HTLC-Success transaction, it must be a
2924+
// 1-in-1-out transaction as its pre-signed.
2925+
// Note that if anchors are available these both may vary.
2926+
debug_assert_eq!(tx.input.len(), 1);
2927+
debug_assert_eq!(tx.output.len(), 1);
2928+
}
2929+
29102930
let mut payment_preimage = PaymentPreimage([0; 32]);
29112931
if accepted_preimage_claim {
29122932
payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
@@ -2945,13 +2965,14 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29452965
}
29462966

29472967
macro_rules! check_htlc_valid_counterparty {
2948-
($counterparty_txid: expr, $htlc_output: expr) => {
2968+
($counterparty_txid: expr, $htlc_output: expr, $htlc_value_sats: expr) => {
29492969
if let Some(txid) = $counterparty_txid {
29502970
for &(ref pending_htlc, ref pending_source) in self.counterparty_claimable_outpoints.get(&txid).unwrap() {
29512971
if pending_htlc.payment_hash == $htlc_output.payment_hash && pending_htlc.amount_msat == $htlc_output.amount_msat {
29522972
if let &Some(ref source) = pending_source {
29532973
log_claim!("revoked counterparty commitment tx", false, pending_htlc, true);
2954-
payment_data = Some(((**source).clone(), $htlc_output.payment_hash, $htlc_output.amount_msat));
2974+
payment_data = Some(((**source).clone(), $htlc_output.payment_hash,
2975+
pending_htlc.amount_msat, $htlc_value_sats));
29552976
break;
29562977
}
29572978
}
@@ -2964,18 +2985,24 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29642985
($htlcs: expr, $tx_info: expr, $holder_tx: expr) => {
29652986
for (ref htlc_output, source_option) in $htlcs {
29662987
if Some(input.previous_output.vout) == htlc_output.transaction_output_index {
2988+
let htlc_value_sats = if claim_via_htlc_tx {
2989+
tx.output.iter().map(|txout| txout.value).sum::<u64>()
2990+
} else { htlc_output.amount_msat / 1000 };
29672991
if let Some(ref source) = source_option {
29682992
log_claim!($tx_info, $holder_tx, htlc_output, true);
29692993
// We have a resolution of an HTLC either from one of our latest
29702994
// holder commitment transactions or an unrevoked counterparty commitment
29712995
// transaction. This implies we either learned a preimage, the HTLC
29722996
// has timed out, or we screwed up. In any case, we should now
29732997
// resolve the source HTLC with the original sender.
2974-
payment_data = Some(((*source).clone(), htlc_output.payment_hash, htlc_output.amount_msat));
2998+
payment_data = Some(((*source).clone(), htlc_output.payment_hash,
2999+
htlc_output.amount_msat, htlc_value_sats));
29753000
} else if !$holder_tx {
2976-
check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid, htlc_output);
3001+
check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid,
3002+
htlc_output, htlc_value_sats);
29773003
if payment_data.is_none() {
2978-
check_htlc_valid_counterparty!(self.prev_counterparty_commitment_txid, htlc_output);
3004+
check_htlc_valid_counterparty!(self.prev_counterparty_commitment_txid,
3005+
htlc_output, htlc_value_sats);
29793006
}
29803007
}
29813008
if payment_data.is_none() {
@@ -2986,6 +3013,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29863013
txid: tx.txid(), height, transaction: Some(tx.clone()),
29873014
event: OnchainEvent::HTLCSpendConfirmation {
29883015
commitment_tx_output_idx: input.previous_output.vout,
3016+
onchain_value_satoshis: Some(htlc_value_sats),
29893017
preimage: if accepted_preimage_claim || offered_preimage_claim {
29903018
Some(payment_preimage) } else { None },
29913019
// If this is a payment to us (!outbound_htlc, above),
@@ -3028,7 +3056,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30283056

30293057
// Check that scan_commitment, above, decided there is some source worth relaying an
30303058
// HTLC resolution backwards to and figure out whether we learned a preimage from it.
3031-
if let Some((source, payment_hash, amount_msat)) = payment_data {
3059+
if let Some((source, payment_hash, amount_msat, onchain_amount_sat)) = payment_data {
30323060
if accepted_preimage_claim {
30333061
if !self.pending_monitor_events.iter().any(
30343062
|update| if let &MonitorEvent::HTLCEvent(ref upd) = update { upd.source == source } else { false }) {
@@ -3040,6 +3068,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30403068
commitment_tx_output_idx: input.previous_output.vout,
30413069
preimage: Some(payment_preimage),
30423070
on_to_local_output_csv: None,
3071+
onchain_value_satoshis: Some(onchain_amount_sat),
30433072
},
30443073
});
30453074
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
@@ -3062,6 +3091,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30623091
commitment_tx_output_idx: input.previous_output.vout,
30633092
preimage: Some(payment_preimage),
30643093
on_to_local_output_csv: None,
3094+
onchain_value_satoshis: Some(onchain_amount_sat),
30653095
},
30663096
});
30673097
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
@@ -3089,6 +3119,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30893119
source, payment_hash,
30903120
htlc_value_satoshis: Some(amount_msat / 1000),
30913121
commitment_tx_output_idx: Some(input.previous_output.vout),
3122+
onchain_value_satoshis: Some(onchain_amount_sat),
30923123
},
30933124
};
30943125
log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height {})", log_bytes!(payment_hash.0), entry.confirmation_threshold());

0 commit comments

Comments
 (0)