Skip to content

Commit a9e6341

Browse files
authored
Merge pull request #2048 from TheBlueMatt/2023-02-send-persist-order-a
Track claimed outbound HTLCs in ChannelMonitors
2 parents 5c6e367 + 75527db commit a9e6341

File tree

6 files changed

+291
-91
lines changed

6 files changed

+291
-91
lines changed

lightning/src/chain/channelmonitor.rs

+87-38
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::ln::{PaymentHash, PaymentPreimage};
3737
use crate::ln::msgs::DecodeError;
3838
use crate::ln::chan_utils;
3939
use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction};
40-
use crate::ln::channelmanager::HTLCSource;
40+
use crate::ln::channelmanager::{HTLCSource, SentHTLCId};
4141
use crate::chain;
4242
use crate::chain::{BestBlock, WatchedOutput};
4343
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
@@ -494,6 +494,7 @@ pub(crate) enum ChannelMonitorUpdateStep {
494494
LatestHolderCommitmentTXInfo {
495495
commitment_tx: HolderCommitmentTransaction,
496496
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
497+
claimed_htlcs: Vec<(SentHTLCId, PaymentPreimage)>,
497498
},
498499
LatestCounterpartyCommitmentTXInfo {
499500
commitment_txid: Txid,
@@ -536,6 +537,7 @@ impl ChannelMonitorUpdateStep {
536537
impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
537538
(0, LatestHolderCommitmentTXInfo) => {
538539
(0, commitment_tx, required),
540+
(1, claimed_htlcs, vec_type),
539541
(2, htlc_outputs, vec_type),
540542
},
541543
(1, LatestCounterpartyCommitmentTXInfo) => {
@@ -750,6 +752,8 @@ pub(crate) struct ChannelMonitorImpl<Signer: WriteableEcdsaChannelSigner> {
750752
/// Serialized to disk but should generally not be sent to Watchtowers.
751753
counterparty_hash_commitment_number: HashMap<PaymentHash, u64>,
752754

755+
counterparty_fulfilled_htlcs: HashMap<SentHTLCId, PaymentPreimage>,
756+
753757
// We store two holder commitment transactions to avoid any race conditions where we may update
754758
// some monitors (potentially on watchtowers) but then fail to update others, resulting in the
755759
// various monitors for one channel being out of sync, and us broadcasting a holder
@@ -1033,6 +1037,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signe
10331037
(9, self.counterparty_node_id, option),
10341038
(11, self.confirmed_commitment_tx_counterparty_output, option),
10351039
(13, self.spendable_txids_confirmed, vec_type),
1040+
(15, self.counterparty_fulfilled_htlcs, required),
10361041
});
10371042

10381043
Ok(())
@@ -1120,6 +1125,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
11201125
counterparty_claimable_outpoints: HashMap::new(),
11211126
counterparty_commitment_txn_on_chain: HashMap::new(),
11221127
counterparty_hash_commitment_number: HashMap::new(),
1128+
counterparty_fulfilled_htlcs: HashMap::new(),
11231129

11241130
prev_holder_signed_commitment_tx: None,
11251131
current_holder_commitment_tx: holder_commitment_tx,
@@ -1174,7 +1180,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
11741180
&self, holder_commitment_tx: HolderCommitmentTransaction,
11751181
htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>,
11761182
) -> Result<(), ()> {
1177-
self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs).map_err(|_| ())
1183+
self.inner.lock().unwrap().provide_latest_holder_commitment_tx(holder_commitment_tx, htlc_outputs, &Vec::new()).map_err(|_| ())
11781184
}
11791185

11801186
/// This is used to provide payment preimage(s) out-of-band during startup without updating the
@@ -1810,9 +1816,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
18101816
/// `ChannelMonitor`. This is used to determine if an HTLC was removed from the channel prior
18111817
/// to the `ChannelManager` having been persisted.
18121818
///
1813-
/// This is similar to [`Self::get_pending_outbound_htlcs`] except it includes HTLCs which were
1814-
/// resolved by this `ChannelMonitor`.
1815-
pub(crate) fn get_all_current_outbound_htlcs(&self) -> HashMap<HTLCSource, HTLCOutputInCommitment> {
1819+
/// This is similar to [`Self::get_pending_or_resolved_outbound_htlcs`] except it includes
1820+
/// HTLCs which were resolved on-chain (i.e. where the final HTLC resolution was done by an
1821+
/// event from this `ChannelMonitor`).
1822+
pub(crate) fn get_all_current_outbound_htlcs(&self) -> HashMap<HTLCSource, (HTLCOutputInCommitment, Option<PaymentPreimage>)> {
18161823
let mut res = HashMap::new();
18171824
// Just examine the available counterparty commitment transactions. See docs on
18181825
// `fail_unbroadcast_htlcs`, below, for justification.
@@ -1822,7 +1829,8 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
18221829
if let Some(ref latest_outpoints) = us.counterparty_claimable_outpoints.get($txid) {
18231830
for &(ref htlc, ref source_option) in latest_outpoints.iter() {
18241831
if let &Some(ref source) = source_option {
1825-
res.insert((**source).clone(), htlc.clone());
1832+
res.insert((**source).clone(), (htlc.clone(),
1833+
us.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).cloned()));
18261834
}
18271835
}
18281836
}
@@ -1837,9 +1845,14 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
18371845
res
18381846
}
18391847

1840-
/// Gets the set of outbound HTLCs which are pending resolution in this channel.
1848+
/// Gets the set of outbound HTLCs which are pending resolution in this channel or which were
1849+
/// resolved with a preimage from our counterparty.
1850+
///
18411851
/// This is used to reconstruct pending outbound payments on restart in the ChannelManager.
1842-
pub(crate) fn get_pending_outbound_htlcs(&self) -> HashMap<HTLCSource, HTLCOutputInCommitment> {
1852+
///
1853+
/// Currently, the preimage is unused, however if it is present in the relevant internal state
1854+
/// an HTLC is always included even if it has been resolved.
1855+
pub(crate) fn get_pending_or_resolved_outbound_htlcs(&self) -> HashMap<HTLCSource, (HTLCOutputInCommitment, Option<PaymentPreimage>)> {
18431856
let us = self.inner.lock().unwrap();
18441857
// We're only concerned with the confirmation count of HTLC transactions, and don't
18451858
// actually care how many confirmations a commitment transaction may or may not have. Thus,
@@ -1887,8 +1900,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
18871900
Some(commitment_tx_output_idx) == htlc.transaction_output_index
18881901
} else { false }
18891902
});
1890-
if !htlc_update_confd {
1891-
res.insert(source.clone(), htlc.clone());
1903+
let counterparty_resolved_preimage_opt =
1904+
us.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).cloned();
1905+
if !htlc_update_confd || counterparty_resolved_preimage_opt.is_some() {
1906+
res.insert(source.clone(), (htlc.clone(), counterparty_resolved_preimage_opt));
18921907
}
18931908
}
18941909
}
@@ -1970,6 +1985,9 @@ macro_rules! fail_unbroadcast_htlcs {
19701985
}
19711986
}
19721987
if matched_htlc { continue; }
1988+
if $self.counterparty_fulfilled_htlcs.get(&SentHTLCId::from_source(source)).is_some() {
1989+
continue;
1990+
}
19731991
$self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
19741992
if entry.height != $commitment_tx_conf_height { return true; }
19751993
match entry.event {
@@ -2041,8 +2059,23 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
20412059
// Prune HTLCs from the previous counterparty commitment tx so we don't generate failure/fulfill
20422060
// events for now-revoked/fulfilled HTLCs.
20432061
if let Some(txid) = self.prev_counterparty_commitment_txid.take() {
2044-
for &mut (_, ref mut source) in self.counterparty_claimable_outpoints.get_mut(&txid).unwrap() {
2045-
*source = None;
2062+
if self.current_counterparty_commitment_txid.unwrap() != txid {
2063+
let cur_claimables = self.counterparty_claimable_outpoints.get(
2064+
&self.current_counterparty_commitment_txid.unwrap()).unwrap();
2065+
for (_, ref source_opt) in self.counterparty_claimable_outpoints.get(&txid).unwrap() {
2066+
if let Some(source) = source_opt {
2067+
if !cur_claimables.iter()
2068+
.any(|(_, cur_source_opt)| cur_source_opt == source_opt)
2069+
{
2070+
self.counterparty_fulfilled_htlcs.remove(&SentHTLCId::from_source(source));
2071+
}
2072+
}
2073+
}
2074+
for &mut (_, ref mut source_opt) in self.counterparty_claimable_outpoints.get_mut(&txid).unwrap() {
2075+
*source_opt = None;
2076+
}
2077+
} else {
2078+
assert!(cfg!(fuzzing), "Commitment txids are unique outside of fuzzing, where hashes can collide");
20462079
}
20472080
}
20482081

@@ -2127,28 +2160,37 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
21272160
/// is important that any clones of this channel monitor (including remote clones) by kept
21282161
/// up-to-date as our holder commitment transaction is updated.
21292162
/// Panics if set_on_holder_tx_csv has never been called.
2130-
fn provide_latest_holder_commitment_tx(&mut self, holder_commitment_tx: HolderCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>) -> Result<(), &'static str> {
2131-
// block for Rust 1.34 compat
2132-
let mut new_holder_commitment_tx = {
2133-
let trusted_tx = holder_commitment_tx.trust();
2134-
let txid = trusted_tx.txid();
2135-
let tx_keys = trusted_tx.keys();
2136-
self.current_holder_commitment_number = trusted_tx.commitment_number();
2137-
HolderSignedTx {
2138-
txid,
2139-
revocation_key: tx_keys.revocation_key,
2140-
a_htlc_key: tx_keys.broadcaster_htlc_key,
2141-
b_htlc_key: tx_keys.countersignatory_htlc_key,
2142-
delayed_payment_key: tx_keys.broadcaster_delayed_payment_key,
2143-
per_commitment_point: tx_keys.per_commitment_point,
2144-
htlc_outputs,
2145-
to_self_value_sat: holder_commitment_tx.to_broadcaster_value_sat(),
2146-
feerate_per_kw: trusted_tx.feerate_per_kw(),
2147-
}
2163+
fn provide_latest_holder_commitment_tx(&mut self, holder_commitment_tx: HolderCommitmentTransaction, htlc_outputs: Vec<(HTLCOutputInCommitment, Option<Signature>, Option<HTLCSource>)>, claimed_htlcs: &[(SentHTLCId, PaymentPreimage)]) -> Result<(), &'static str> {
2164+
let trusted_tx = holder_commitment_tx.trust();
2165+
let txid = trusted_tx.txid();
2166+
let tx_keys = trusted_tx.keys();
2167+
self.current_holder_commitment_number = trusted_tx.commitment_number();
2168+
let mut new_holder_commitment_tx = HolderSignedTx {
2169+
txid,
2170+
revocation_key: tx_keys.revocation_key,
2171+
a_htlc_key: tx_keys.broadcaster_htlc_key,
2172+
b_htlc_key: tx_keys.countersignatory_htlc_key,
2173+
delayed_payment_key: tx_keys.broadcaster_delayed_payment_key,
2174+
per_commitment_point: tx_keys.per_commitment_point,
2175+
htlc_outputs,
2176+
to_self_value_sat: holder_commitment_tx.to_broadcaster_value_sat(),
2177+
feerate_per_kw: trusted_tx.feerate_per_kw(),
21482178
};
21492179
self.onchain_tx_handler.provide_latest_holder_tx(holder_commitment_tx);
21502180
mem::swap(&mut new_holder_commitment_tx, &mut self.current_holder_commitment_tx);
21512181
self.prev_holder_signed_commitment_tx = Some(new_holder_commitment_tx);
2182+
for (claimed_htlc_id, claimed_preimage) in claimed_htlcs {
2183+
#[cfg(debug_assertions)] {
2184+
let cur_counterparty_htlcs = self.counterparty_claimable_outpoints.get(
2185+
&self.current_counterparty_commitment_txid.unwrap()).unwrap();
2186+
assert!(cur_counterparty_htlcs.iter().any(|(_, source_opt)| {
2187+
if let Some(source) = source_opt {
2188+
SentHTLCId::from_source(source) == *claimed_htlc_id
2189+
} else { false }
2190+
}));
2191+
}
2192+
self.counterparty_fulfilled_htlcs.insert(*claimed_htlc_id, *claimed_preimage);
2193+
}
21522194
if self.holder_tx_signed {
21532195
return Err("Latest holder commitment signed has already been signed, update is rejected");
21542196
}
@@ -2243,10 +2285,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
22432285
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator);
22442286
for update in updates.updates.iter() {
22452287
match update {
2246-
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs } => {
2288+
ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs } => {
22472289
log_trace!(logger, "Updating ChannelMonitor with latest holder commitment transaction info");
22482290
if self.lockdown_from_offchain { panic!(); }
2249-
if let Err(e) = self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone()) {
2291+
if let Err(e) = self.provide_latest_holder_commitment_tx(commitment_tx.clone(), htlc_outputs.clone(), &claimed_htlcs) {
22502292
log_error!(logger, "Providing latest holder commitment transaction failed/was refused:");
22512293
log_error!(logger, " {}", e);
22522294
ret = Err(());
@@ -3868,6 +3910,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
38683910
let mut counterparty_node_id = None;
38693911
let mut confirmed_commitment_tx_counterparty_output = None;
38703912
let mut spendable_txids_confirmed = Some(Vec::new());
3913+
let mut counterparty_fulfilled_htlcs = Some(HashMap::new());
38713914
read_tlv_fields!(reader, {
38723915
(1, funding_spend_confirmed, option),
38733916
(3, htlcs_resolved_on_chain, vec_type),
@@ -3876,6 +3919,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
38763919
(9, counterparty_node_id, option),
38773920
(11, confirmed_commitment_tx_counterparty_output, option),
38783921
(13, spendable_txids_confirmed, vec_type),
3922+
(15, counterparty_fulfilled_htlcs, option),
38793923
});
38803924

38813925
Ok((best_block.block_hash(), ChannelMonitor::from_impl(ChannelMonitorImpl {
@@ -3904,6 +3948,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
39043948
counterparty_claimable_outpoints,
39053949
counterparty_commitment_txn_on_chain,
39063950
counterparty_hash_commitment_number,
3951+
counterparty_fulfilled_htlcs: counterparty_fulfilled_htlcs.unwrap(),
39073952

39083953
prev_holder_signed_commitment_tx,
39093954
current_holder_commitment_tx,
@@ -4077,7 +4122,6 @@ mod tests {
40774122
let fee_estimator = TestFeeEstimator { sat_per_kw: Mutex::new(253) };
40784123

40794124
let dummy_key = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
4080-
let dummy_tx = Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() };
40814125

40824126
let mut preimages = Vec::new();
40834127
{
@@ -4167,11 +4211,10 @@ mod tests {
41674211
HolderCommitmentTransaction::dummy(), best_block, dummy_key);
41684212

41694213
monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..10])).unwrap();
4170-
let dummy_txid = dummy_tx.txid();
4171-
monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);
4172-
monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
4173-
monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
4174-
monitor.provide_latest_counterparty_commitment_tx(dummy_txid, preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
4214+
monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"1").into_inner()),
4215+
preimages_slice_to_htlc_outputs!(preimages[5..15]), 281474976710655, dummy_key, &logger);
4216+
monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"2").into_inner()),
4217+
preimages_slice_to_htlc_outputs!(preimages[15..20]), 281474976710654, dummy_key, &logger);
41754218
for &(ref preimage, ref hash) in preimages.iter() {
41764219
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
41774220
monitor.provide_payment_preimage(hash, preimage, &broadcaster, &bounded_fee_estimator, &logger);
@@ -4185,13 +4228,19 @@ mod tests {
41854228
test_preimages_exist!(&preimages[0..10], monitor);
41864229
test_preimages_exist!(&preimages[15..20], monitor);
41874230

4231+
monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"3").into_inner()),
4232+
preimages_slice_to_htlc_outputs!(preimages[17..20]), 281474976710653, dummy_key, &logger);
4233+
41884234
// Now provide a further secret, pruning preimages 15-17
41894235
secret[0..32].clone_from_slice(&hex::decode("c7518c8ae4660ed02894df8976fa1a3659c1a8b4b5bec0c4b872abeba4cb8964").unwrap());
41904236
monitor.provide_secret(281474976710654, secret.clone()).unwrap();
41914237
assert_eq!(monitor.inner.lock().unwrap().payment_preimages.len(), 13);
41924238
test_preimages_exist!(&preimages[0..10], monitor);
41934239
test_preimages_exist!(&preimages[17..20], monitor);
41944240

4241+
monitor.provide_latest_counterparty_commitment_tx(Txid::from_inner(Sha256::hash(b"4").into_inner()),
4242+
preimages_slice_to_htlc_outputs!(preimages[18..20]), 281474976710652, dummy_key, &logger);
4243+
41954244
// Now update holder commitment tx info, pruning only element 18 as we still care about the
41964245
// previous commitment tx's preimages too
41974246
monitor.provide_latest_holder_commitment_tx(HolderCommitmentTransaction::dummy(), preimages_to_holder_htlcs!(preimages[0..5])).unwrap();

lightning/src/ln/channel.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::ln::features::{ChannelTypeFeatures, InitFeatures};
2727
use crate::ln::msgs;
2828
use crate::ln::msgs::{DecodeError, OptionalField, DataLossProtect};
2929
use crate::ln::script::{self, ShutdownScript};
30-
use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
30+
use crate::ln::channelmanager::{self, CounterpartyForwardingInfo, PendingHTLCStatus, HTLCSource, SentHTLCId, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA, MAX_LOCAL_BREAKDOWN_TIMEOUT};
3131
use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, htlc_success_tx_weight, htlc_timeout_tx_weight, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor, ClosingTransaction};
3232
use crate::ln::chan_utils;
3333
use crate::ln::onion_utils::HTLCFailReason;
@@ -192,6 +192,7 @@ enum OutboundHTLCState {
192192

193193
#[derive(Clone)]
194194
enum OutboundHTLCOutcome {
195+
/// LDK version 0.0.105+ will always fill in the preimage here.
195196
Success(Option<PaymentPreimage>),
196197
Failure(HTLCFailReason),
197198
}
@@ -3159,15 +3160,6 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
31593160
}
31603161
}
31613162

3162-
self.latest_monitor_update_id += 1;
3163-
let mut monitor_update = ChannelMonitorUpdate {
3164-
update_id: self.latest_monitor_update_id,
3165-
updates: vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
3166-
commitment_tx: holder_commitment_tx,
3167-
htlc_outputs: htlcs_and_sigs
3168-
}]
3169-
};
3170-
31713163
for htlc in self.pending_inbound_htlcs.iter_mut() {
31723164
let new_forward = if let &InboundHTLCState::RemoteAnnounced(ref forward_info) = &htlc.state {
31733165
Some(forward_info.clone())
@@ -3179,18 +3171,38 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
31793171
need_commitment = true;
31803172
}
31813173
}
3174+
let mut claimed_htlcs = Vec::new();
31823175
for htlc in self.pending_outbound_htlcs.iter_mut() {
31833176
if let &mut OutboundHTLCState::RemoteRemoved(ref mut outcome) = &mut htlc.state {
31843177
log_trace!(logger, "Updating HTLC {} to AwaitingRemoteRevokeToRemove due to commitment_signed in channel {}.",
31853178
log_bytes!(htlc.payment_hash.0), log_bytes!(self.channel_id));
31863179
// Grab the preimage, if it exists, instead of cloning
31873180
let mut reason = OutboundHTLCOutcome::Success(None);
31883181
mem::swap(outcome, &mut reason);
3182+
if let OutboundHTLCOutcome::Success(Some(preimage)) = reason {
3183+
// If a user (a) receives an HTLC claim using LDK 0.0.104 or before, then (b)
3184+
// upgrades to LDK 0.0.114 or later before the HTLC is fully resolved, we could
3185+
// have a `Success(None)` reason. In this case we could forget some HTLC
3186+
// claims, but such an upgrade is unlikely and including claimed HTLCs here
3187+
// fixes a bug which the user was exposed to on 0.0.104 when they started the
3188+
// claim anyway.
3189+
claimed_htlcs.push((SentHTLCId::from_source(&htlc.source), preimage));
3190+
}
31893191
htlc.state = OutboundHTLCState::AwaitingRemoteRevokeToRemove(reason);
31903192
need_commitment = true;
31913193
}
31923194
}
31933195

3196+
self.latest_monitor_update_id += 1;
3197+
let mut monitor_update = ChannelMonitorUpdate {
3198+
update_id: self.latest_monitor_update_id,
3199+
updates: vec![ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo {
3200+
commitment_tx: holder_commitment_tx,
3201+
htlc_outputs: htlcs_and_sigs,
3202+
claimed_htlcs,
3203+
}]
3204+
};
3205+
31943206
self.cur_holder_commitment_transaction_number -= 1;
31953207
// Note that if we need_commitment & !AwaitingRemoteRevoke we'll call
31963208
// build_commitment_no_status_check() next which will reset this to RAAFirst.

0 commit comments

Comments
 (0)