Skip to content

Commit f55e102

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 e0a535c commit f55e102

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,9 @@ 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, this is the
365+
/// amount of the output of that transaction (ie `htlc_value_satoshis` minus fees).
366+
onchain_value_satoshis: Option<u64>,
364367
htlc_value_satoshis: Option<u64>,
365368
/// None in the second case, above, ie when there is no relevant output in the commitment
366369
/// transaction which appeared on chain.
@@ -392,6 +395,9 @@ enum OnchainEvent {
392395
/// signature.
393396
HTLCSpendConfirmation {
394397
commitment_tx_output_idx: u32,
398+
/// If the HTLC was claimed by an HTLC-Success or HTLC-Timeout transaction, this is the
399+
/// amount of the output of that transaction (ie `htlc_value_satoshis` minus fees).
400+
onchain_value_satoshis: Option<u64>,
395401
/// If the claim was made by either party with a preimage, this is filled in
396402
preimage: Option<PaymentPreimage>,
397403
/// If the claim was made by us on an inbound HTLC against a local commitment transaction,
@@ -439,6 +445,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
439445
(1, htlc_value_satoshis, option),
440446
(2, payment_hash, required),
441447
(3, commitment_tx_output_idx, option),
448+
(5, onchain_value_satoshis, option),
442449
},
443450
(1, MaturingOutput) => {
444451
(0, descriptor, required),
@@ -449,6 +456,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
449456
},
450457
(5, HTLCSpendConfirmation) => {
451458
(0, commitment_tx_output_idx, required),
459+
(1, onchain_value_satoshis, option),
452460
(2, preimage, option),
453461
(4, on_to_local_output_csv, option),
454462
},
@@ -1729,6 +1737,7 @@ macro_rules! fail_unbroadcast_htlcs {
17291737
source: (**source).clone(),
17301738
payment_hash: htlc.payment_hash.clone(),
17311739
htlc_value_satoshis: Some(htlc.amount_msat / 1000),
1740+
onchain_value_satoshis: None,
17321741
commitment_tx_output_idx: None,
17331742
},
17341743
};
@@ -2661,7 +2670,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
26612670
// Produce actionable events from on-chain events having reached their threshold.
26622671
for entry in onchain_events_reaching_threshold_conf.drain(..) {
26632672
match entry.event {
2664-
OnchainEvent::HTLCUpdate { ref source, payment_hash, htlc_value_satoshis, commitment_tx_output_idx } => {
2673+
OnchainEvent::HTLCUpdate { ref source, payment_hash, htlc_value_satoshis, commitment_tx_output_idx, .. } => {
26652674
// Check for duplicate HTLC resolutions.
26662675
#[cfg(debug_assertions)]
26672676
{
@@ -2902,6 +2911,14 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29022911
#[cfg(not(fuzzing))]
29032912
let offered_timeout_claim = witness_items == 5 && htlctype == Some(HTLCType::OfferedHTLC);
29042913

2914+
let claim_via_htlc_tx = accepted_preimage_claim || offered_timeout_claim;
2915+
if claim_via_htlc_tx {
2916+
// If the claim was via an HTLC-Timeout/HTLC-Success transaction, it must be a
2917+
// 1-in-1-out transaction as its pre-signed.
2918+
debug_assert_eq!(tx.input.len(), 1);
2919+
debug_assert_eq!(tx.output.len(), 1); // If anchors are enabled this should be 2
2920+
}
2921+
29052922
let mut payment_preimage = PaymentPreimage([0; 32]);
29062923
if accepted_preimage_claim {
29072924
payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
@@ -2940,13 +2957,14 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29402957
}
29412958

29422959
macro_rules! check_htlc_valid_counterparty {
2943-
($counterparty_txid: expr, $htlc_output: expr) => {
2960+
($counterparty_txid: expr, $htlc_output: expr, $htlc_value_sats: expr) => {
29442961
if let Some(txid) = $counterparty_txid {
29452962
for &(ref pending_htlc, ref pending_source) in self.counterparty_claimable_outpoints.get(&txid).unwrap() {
29462963
if pending_htlc.payment_hash == $htlc_output.payment_hash && pending_htlc.amount_msat == $htlc_output.amount_msat {
29472964
if let &Some(ref source) = pending_source {
29482965
log_claim!("revoked counterparty commitment tx", false, pending_htlc, true);
2949-
payment_data = Some(((**source).clone(), $htlc_output.payment_hash, $htlc_output.amount_msat));
2966+
payment_data = Some(((**source).clone(), $htlc_output.payment_hash,
2967+
pending_htlc.amount_msat, $htlc_value_sats));
29502968
break;
29512969
}
29522970
}
@@ -2959,18 +2977,24 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29592977
($htlcs: expr, $tx_info: expr, $holder_tx: expr) => {
29602978
for (ref htlc_output, source_option) in $htlcs {
29612979
if Some(input.previous_output.vout) == htlc_output.transaction_output_index {
2980+
let htlc_value_sats = if claim_via_htlc_tx {
2981+
tx.output.iter().map(|txout| txout.value).sum::<u64>()
2982+
} else { htlc_output.amount_msat / 1000 };
29622983
if let Some(ref source) = source_option {
29632984
log_claim!($tx_info, $holder_tx, htlc_output, true);
29642985
// We have a resolution of an HTLC either from one of our latest
29652986
// holder commitment transactions or an unrevoked counterparty commitment
29662987
// transaction. This implies we either learned a preimage, the HTLC
29672988
// has timed out, or we screwed up. In any case, we should now
29682989
// resolve the source HTLC with the original sender.
2969-
payment_data = Some(((*source).clone(), htlc_output.payment_hash, htlc_output.amount_msat));
2990+
payment_data = Some(((*source).clone(), htlc_output.payment_hash,
2991+
htlc_output.amount_msat, htlc_value_sats));
29702992
} else if !$holder_tx {
2971-
check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid, htlc_output);
2993+
check_htlc_valid_counterparty!(self.current_counterparty_commitment_txid,
2994+
htlc_output, htlc_value_sats);
29722995
if payment_data.is_none() {
2973-
check_htlc_valid_counterparty!(self.prev_counterparty_commitment_txid, htlc_output);
2996+
check_htlc_valid_counterparty!(self.prev_counterparty_commitment_txid,
2997+
htlc_output, htlc_value_sats);
29742998
}
29752999
}
29763000
if payment_data.is_none() {
@@ -2981,6 +3005,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
29813005
txid: tx.txid(), height, transaction: Some(tx.clone()),
29823006
event: OnchainEvent::HTLCSpendConfirmation {
29833007
commitment_tx_output_idx: input.previous_output.vout,
3008+
onchain_value_satoshis: Some(htlc_value_sats),
29843009
preimage: if accepted_preimage_claim || offered_preimage_claim {
29853010
Some(payment_preimage) } else { None },
29863011
// If this is a payment to us (!outbound_htlc, above),
@@ -3023,7 +3048,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30233048

30243049
// Check that scan_commitment, above, decided there is some source worth relaying an
30253050
// HTLC resolution backwards to and figure out whether we learned a preimage from it.
3026-
if let Some((source, payment_hash, amount_msat)) = payment_data {
3051+
if let Some((source, payment_hash, amount_msat, onchain_amount_sat)) = payment_data {
30273052
if accepted_preimage_claim {
30283053
if !self.pending_monitor_events.iter().any(
30293054
|update| if let &MonitorEvent::HTLCEvent(ref upd) = update { upd.source == source } else { false }) {
@@ -3035,6 +3060,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30353060
commitment_tx_output_idx: input.previous_output.vout,
30363061
preimage: Some(payment_preimage),
30373062
on_to_local_output_csv: None,
3063+
onchain_value_satoshis: Some(onchain_amount_sat),
30383064
},
30393065
});
30403066
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
@@ -3057,6 +3083,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30573083
commitment_tx_output_idx: input.previous_output.vout,
30583084
preimage: Some(payment_preimage),
30593085
on_to_local_output_csv: None,
3086+
onchain_value_satoshis: Some(onchain_amount_sat),
30603087
},
30613088
});
30623089
self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate {
@@ -3084,6 +3111,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30843111
source, payment_hash,
30853112
htlc_value_satoshis: Some(amount_msat / 1000),
30863113
commitment_tx_output_idx: Some(input.previous_output.vout),
3114+
onchain_value_satoshis: Some(onchain_amount_sat),
30873115
},
30883116
};
30893117
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)