Skip to content

Commit 33586fc

Browse files
committed
Store pending claims awaiting monitor update in a separate map
In the next commits we'll move to generating `PaymentClaimed` events while handling `ChannelMonitorUpdate`s rather than directly in line. Thus, as a prerequisite, here we move to storing the info required to generate the `PaymentClaimed` event in a separate map. Note that while this does introduce a new map which is written as an even value which users cannot opt out of, the map is only filled in when users use the asynchronous `ChannelMonitor` updates and after a future PR. As these are still considered beta, breaking downgrades for such users is considered acceptable in the future PR (which will likely be one LDK version later).
1 parent 8c8bb6d commit 33586fc

File tree

1 file changed

+164
-106
lines changed

1 file changed

+164
-106
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 164 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,34 @@ pub(super) enum RAACommitmentOrder {
424424
RevokeAndACKFirst,
425425
}
426426

427+
/// Information about a payment which is currently being claimed.
428+
struct ClaimingPayment {
429+
amount_msat: u64,
430+
payment_purpose: events::PaymentPurpose,
431+
receiver_node_id: PublicKey,
432+
}
433+
impl_writeable_tlv_based!(ClaimingPayment, {
434+
(0, amount_msat, required),
435+
(2, payment_purpose, required),
436+
(4, receiver_node_id, required),
437+
});
438+
427439
/// Information about claimable or being-claimed payments
428440
struct ClaimablePayments {
429441
/// Map from payment hash to the payment data and any HTLCs which are to us and can be
430442
/// failed/claimed by the user.
431443
///
432444
/// Note that, no consistency guarantees are made about the channels given here actually
433445
/// existing anymore by the time you go to read them!
446+
///
447+
/// When adding to the map, [`Self::pending_claimed_payments`] must also be checked to ensure
448+
/// we don't get a duplicate payment.
434449
claimable_htlcs: HashMap<PaymentHash, (events::PaymentPurpose, Vec<ClaimableHTLC>)>,
450+
451+
/// Map from payment hash to the payment data for HTLCs which we have begun claiming, but which
452+
/// are waiting on a [`ChannelMonitorUpdate`] to complete in order to be surfaced to the user
453+
/// as an [`events::Event::PaymentClaimed`].
454+
pending_claimed_payments: HashMap<PaymentHash, ClaimingPayment>,
435455
}
436456

437457
// Note this is only exposed in cfg(test):
@@ -1607,7 +1627,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
16071627
pending_inbound_payments: Mutex::new(HashMap::new()),
16081628
pending_outbound_payments: Mutex::new(HashMap::new()),
16091629
forward_htlcs: Mutex::new(HashMap::new()),
1610-
claimable_payments: Mutex::new(ClaimablePayments { claimable_htlcs: HashMap::new() }),
1630+
claimable_payments: Mutex::new(ClaimablePayments { claimable_htlcs: HashMap::new(), pending_claimed_payments: HashMap::new() }),
16111631
pending_intercepted_htlcs: Mutex::new(HashMap::new()),
16121632
id_to_peer: Mutex::new(HashMap::new()),
16131633
short_to_chan_info: FairRwLock::new(HashMap::new()),
@@ -3491,6 +3511,10 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
34913511
}
34923512
};
34933513
let mut claimable_payments = self.claimable_payments.lock().unwrap();
3514+
if claimable_payments.pending_claimed_payments.contains_key(&payment_hash) {
3515+
fail_htlc!(claimable_htlc, payment_hash);
3516+
continue
3517+
}
34943518
let (_, htlcs) = claimable_payments.claimable_htlcs.entry(payment_hash)
34953519
.or_insert_with(|| (purpose(), Vec::new()));
34963520
if htlcs.len() == 1 {
@@ -3563,7 +3587,12 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
35633587
check_total_value!(payment_data, payment_preimage);
35643588
},
35653589
OnionPayload::Spontaneous(preimage) => {
3566-
match self.claimable_payments.lock().unwrap().claimable_htlcs.entry(payment_hash) {
3590+
let mut claimable_payments = self.claimable_payments.lock().unwrap();
3591+
if claimable_payments.pending_claimed_payments.contains_key(&payment_hash) {
3592+
fail_htlc!(claimable_htlc, payment_hash);
3593+
continue
3594+
}
3595+
match claimable_payments.claimable_htlcs.entry(payment_hash) {
35673596
hash_map::Entry::Vacant(e) => {
35683597
let purpose = events::PaymentPurpose::SpontaneousPayment(preimage);
35693598
e.insert((purpose.clone(), vec![claimable_htlc]));
@@ -4215,126 +4244,142 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
42154244

42164245
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
42174246

4218-
let removed_source = self.claimable_payments.lock().unwrap().claimable_htlcs.remove(&payment_hash);
4219-
if let Some((payment_purpose, mut sources)) = removed_source {
4220-
assert!(!sources.is_empty());
4221-
4222-
// If we are claiming an MPP payment, we have to take special care to ensure that each
4223-
// channel exists before claiming all of the payments (inside one lock).
4224-
// Note that channel existance is sufficient as we should always get a monitor update
4225-
// which will take care of the real HTLC claim enforcement.
4226-
//
4227-
// If we find an HTLC which we would need to claim but for which we do not have a
4228-
// channel, we will fail all parts of the MPP payment. While we could wait and see if
4229-
// the sender retries the already-failed path(s), it should be a pretty rare case where
4230-
// we got all the HTLCs and then a channel closed while we were waiting for the user to
4231-
// provide the preimage, so worrying too much about the optimal handling isn't worth
4232-
// it.
4233-
let mut claimable_amt_msat = 0;
4234-
let mut expected_amt_msat = None;
4235-
let mut valid_mpp = true;
4236-
let mut errs = Vec::new();
4237-
let mut claimed_any_htlcs = false;
4238-
let mut channel_state_lock = self.channel_state.lock().unwrap();
4239-
let channel_state = &mut *channel_state_lock;
4240-
let mut receiver_node_id = Some(self.our_network_pubkey);
4241-
for htlc in sources.iter() {
4242-
let chan_id = match self.short_to_chan_info.read().unwrap().get(&htlc.prev_hop.short_channel_id) {
4243-
Some((_cp_id, chan_id)) => chan_id.clone(),
4244-
None => {
4245-
valid_mpp = false;
4247+
let mut sources = {
4248+
let mut claimable_payments = self.claimable_payments.lock().unwrap();
4249+
if let Some((payment_purpose, sources)) = claimable_payments.claimable_htlcs.remove(&payment_hash) {
4250+
let mut receiver_node_id = self.our_network_pubkey;
4251+
for htlc in sources.iter() {
4252+
if htlc.prev_hop.phantom_shared_secret.is_some() {
4253+
let phantom_pubkey = self.keys_manager.get_node_id(Recipient::PhantomNode)
4254+
.expect("Failed to get node_id for phantom node recipient");
4255+
receiver_node_id = phantom_pubkey;
42464256
break;
42474257
}
4248-
};
4258+
}
42494259

4250-
if let None = channel_state.by_id.get(&chan_id) {
4251-
valid_mpp = false;
4252-
break;
4260+
let dup_purpose = claimable_payments.pending_claimed_payments.insert(payment_hash,
4261+
ClaimingPayment { amount_msat: sources.iter().map(|source| source.value).sum(),
4262+
payment_purpose, receiver_node_id,
4263+
});
4264+
if dup_purpose.is_some() {
4265+
debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
4266+
log_error!(self.logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug",
4267+
log_bytes!(payment_hash.0));
42534268
}
4269+
sources
4270+
} else { return; }
4271+
};
4272+
debug_assert!(!sources.is_empty());
42544273

4255-
if expected_amt_msat.is_some() && expected_amt_msat != Some(htlc.total_msat) {
4256-
log_error!(self.logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!");
4257-
debug_assert!(false);
4274+
// If we are claiming an MPP payment, we have to take special care to ensure that each
4275+
// channel exists before claiming all of the payments (inside one lock).
4276+
// Note that channel existance is sufficient as we should always get a monitor update
4277+
// which will take care of the real HTLC claim enforcement.
4278+
//
4279+
// If we find an HTLC which we would need to claim but for which we do not have a
4280+
// channel, we will fail all parts of the MPP payment. While we could wait and see if
4281+
// the sender retries the already-failed path(s), it should be a pretty rare case where
4282+
// we got all the HTLCs and then a channel closed while we were waiting for the user to
4283+
// provide the preimage, so worrying too much about the optimal handling isn't worth
4284+
// it.
4285+
let mut claimable_amt_msat = 0;
4286+
let mut expected_amt_msat = None;
4287+
let mut valid_mpp = true;
4288+
let mut errs = Vec::new();
4289+
let mut claimed_any_htlcs = false;
4290+
let mut channel_state_lock = self.channel_state.lock().unwrap();
4291+
let channel_state = &mut *channel_state_lock;
4292+
for htlc in sources.iter() {
4293+
let chan_id = match self.short_to_chan_info.read().unwrap().get(&htlc.prev_hop.short_channel_id) {
4294+
Some((_cp_id, chan_id)) => chan_id.clone(),
4295+
None => {
42584296
valid_mpp = false;
42594297
break;
42604298
}
4261-
expected_amt_msat = Some(htlc.total_msat);
4262-
if let OnionPayload::Spontaneous(_) = &htlc.onion_payload {
4263-
// We don't currently support MPP for spontaneous payments, so just check
4264-
// that there's one payment here and move on.
4265-
if sources.len() != 1 {
4266-
log_error!(self.logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!");
4267-
debug_assert!(false);
4268-
valid_mpp = false;
4269-
break;
4270-
}
4271-
}
4272-
let phantom_shared_secret = htlc.prev_hop.phantom_shared_secret;
4273-
if phantom_shared_secret.is_some() {
4274-
let phantom_pubkey = self.keys_manager.get_node_id(Recipient::PhantomNode)
4275-
.expect("Failed to get node_id for phantom node recipient");
4276-
receiver_node_id = Some(phantom_pubkey)
4277-
}
4299+
};
42784300

4279-
claimable_amt_msat += htlc.value;
4280-
}
4281-
if sources.is_empty() || expected_amt_msat.is_none() {
4282-
log_info!(self.logger, "Attempted to claim an incomplete payment which no longer had any available HTLCs!");
4283-
return;
4301+
if let None = channel_state.by_id.get(&chan_id) {
4302+
valid_mpp = false;
4303+
break;
42844304
}
4285-
if claimable_amt_msat != expected_amt_msat.unwrap() {
4286-
log_info!(self.logger, "Attempted to claim an incomplete payment, expected {} msat, had {} available to claim.",
4287-
expected_amt_msat.unwrap(), claimable_amt_msat);
4288-
return;
4305+
4306+
if expected_amt_msat.is_some() && expected_amt_msat != Some(htlc.total_msat) {
4307+
log_error!(self.logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!");
4308+
debug_assert!(false);
4309+
valid_mpp = false;
4310+
break;
42894311
}
4290-
if valid_mpp {
4291-
for htlc in sources.drain(..) {
4292-
match self.claim_funds_from_hop(&mut channel_state_lock, htlc.prev_hop, payment_preimage) {
4293-
ClaimFundsFromHop::MonitorUpdateFail(pk, err, _) => {
4294-
if let msgs::ErrorAction::IgnoreError = err.err.action {
4295-
// We got a temporary failure updating monitor, but will claim the
4296-
// HTLC when the monitor updating is restored (or on chain).
4297-
log_error!(self.logger, "Temporary failure claiming HTLC, treating as success: {}", err.err.err);
4298-
claimed_any_htlcs = true;
4299-
} else { errs.push((pk, err)); }
4300-
},
4301-
ClaimFundsFromHop::PrevHopForceClosed => unreachable!("We already checked for channel existence, we can't fail here!"),
4302-
ClaimFundsFromHop::DuplicateClaim => {
4303-
// While we should never get here in most cases, if we do, it likely
4304-
// indicates that the HTLC was timed out some time ago and is no longer
4305-
// available to be claimed. Thus, it does not make sense to set
4306-
// `claimed_any_htlcs`.
4307-
},
4308-
ClaimFundsFromHop::Success(_) => claimed_any_htlcs = true,
4309-
}
4312+
expected_amt_msat = Some(htlc.total_msat);
4313+
if let OnionPayload::Spontaneous(_) = &htlc.onion_payload {
4314+
// We don't currently support MPP for spontaneous payments, so just check
4315+
// that there's one payment here and move on.
4316+
if sources.len() != 1 {
4317+
log_error!(self.logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!");
4318+
debug_assert!(false);
4319+
valid_mpp = false;
4320+
break;
43104321
}
43114322
}
4312-
mem::drop(channel_state_lock);
4313-
if !valid_mpp {
4314-
for htlc in sources.drain(..) {
4315-
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
4316-
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
4317-
let source = HTLCSource::PreviousHopData(htlc.prev_hop);
4318-
let reason = HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data);
4319-
let receiver = HTLCDestination::FailedPayment { payment_hash };
4320-
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
4323+
4324+
claimable_amt_msat += htlc.value;
4325+
}
4326+
if sources.is_empty() || expected_amt_msat.is_none() {
4327+
self.claimable_payments.lock().unwrap().pending_claimed_payments.remove(&payment_hash);
4328+
log_info!(self.logger, "Attempted to claim an incomplete payment which no longer had any available HTLCs!");
4329+
return;
4330+
}
4331+
if claimable_amt_msat != expected_amt_msat.unwrap() {
4332+
self.claimable_payments.lock().unwrap().pending_claimed_payments.remove(&payment_hash);
4333+
log_info!(self.logger, "Attempted to claim an incomplete payment, expected {} msat, had {} available to claim.",
4334+
expected_amt_msat.unwrap(), claimable_amt_msat);
4335+
return;
4336+
}
4337+
if valid_mpp {
4338+
for htlc in sources.drain(..) {
4339+
match self.claim_funds_from_hop(&mut channel_state_lock, htlc.prev_hop, payment_preimage) {
4340+
ClaimFundsFromHop::MonitorUpdateFail(pk, err, _) => {
4341+
if let msgs::ErrorAction::IgnoreError = err.err.action {
4342+
// We got a temporary failure updating monitor, but will claim the
4343+
// HTLC when the monitor updating is restored (or on chain).
4344+
log_error!(self.logger, "Temporary failure claiming HTLC, treating as success: {}", err.err.err);
4345+
claimed_any_htlcs = true;
4346+
} else { errs.push((pk, err)); }
4347+
},
4348+
ClaimFundsFromHop::PrevHopForceClosed => unreachable!("We already checked for channel existence, we can't fail here!"),
4349+
ClaimFundsFromHop::DuplicateClaim => {
4350+
// While we should never get here in most cases, if we do, it likely
4351+
// indicates that the HTLC was timed out some time ago and is no longer
4352+
// available to be claimed. Thus, it does not make sense to set
4353+
// `claimed_any_htlcs`.
4354+
},
4355+
ClaimFundsFromHop::Success(_) => claimed_any_htlcs = true,
43214356
}
43224357
}
4323-
4324-
if claimed_any_htlcs {
4325-
self.pending_events.lock().unwrap().push(events::Event::PaymentClaimed {
4326-
receiver_node_id,
4327-
payment_hash,
4328-
purpose: payment_purpose,
4329-
amount_msat: claimable_amt_msat,
4330-
});
4358+
}
4359+
mem::drop(channel_state_lock);
4360+
if !valid_mpp {
4361+
for htlc in sources.drain(..) {
4362+
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
4363+
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
4364+
let source = HTLCSource::PreviousHopData(htlc.prev_hop);
4365+
let reason = HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data);
4366+
let receiver = HTLCDestination::FailedPayment { payment_hash };
4367+
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
43314368
}
4369+
}
43324370

4333-
// Now we can handle any errors which were generated.
4334-
for (counterparty_node_id, err) in errs.drain(..) {
4335-
let res: Result<(), _> = Err(err);
4336-
let _ = handle_error!(self, res, counterparty_node_id);
4337-
}
4371+
let ClaimingPayment { amount_msat, payment_purpose: purpose, receiver_node_id } =
4372+
self.claimable_payments.lock().unwrap().pending_claimed_payments.remove(&payment_hash).unwrap();
4373+
if claimed_any_htlcs {
4374+
self.pending_events.lock().unwrap().push(events::Event::PaymentClaimed {
4375+
payment_hash, purpose, amount_msat, receiver_node_id: Some(receiver_node_id),
4376+
});
4377+
}
4378+
4379+
// Now we can handle any errors which were generated.
4380+
for (counterparty_node_id, err) in errs.drain(..) {
4381+
let res: Result<(), _> = Err(err);
4382+
let _ = handle_error!(self, res, counterparty_node_id);
43384383
}
43394384
}
43404385

@@ -7242,10 +7287,21 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelMana
72427287
if our_pending_intercepts.len() != 0 {
72437288
pending_intercepted_htlcs = Some(our_pending_intercepts);
72447289
}
7290+
7291+
let mut pending_claimed_payments = Some(&claimable_payments.pending_claimed_payments);
7292+
if pending_claimed_payments.as_ref().unwrap().is_empty() {
7293+
// LDK versions prior to 0.0.113 do not know how to read the pending claimed payments
7294+
// map. Thus, if there are no entries we skip writing a TLV for it.
7295+
pending_claimed_payments = None;
7296+
} else {
7297+
debug_assert!(false, "While we have code to serialize pending_claimed_payments, the map should always be empty until a later PR");
7298+
}
7299+
72457300
write_tlv_fields!(writer, {
72467301
(1, pending_outbound_payments_no_retry, required),
72477302
(2, pending_intercepted_htlcs, option),
72487303
(3, pending_outbound_payments, required),
7304+
(4, pending_claimed_payments, option),
72497305
(5, self.our_network_pubkey, required),
72507306
(7, self.fake_scid_rand_bytes, required),
72517307
(9, htlc_purposes, vec_type),
@@ -7572,10 +7628,12 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
75727628
let mut fake_scid_rand_bytes: Option<[u8; 32]> = None;
75737629
let mut probing_cookie_secret: Option<[u8; 32]> = None;
75747630
let mut claimable_htlc_purposes = None;
7631+
let mut pending_claimed_payments = Some(HashMap::new());
75757632
read_tlv_fields!(reader, {
75767633
(1, pending_outbound_payments_no_retry, option),
75777634
(2, pending_intercepted_htlcs, option),
75787635
(3, pending_outbound_payments, option),
7636+
(4, pending_claimed_payments, option),
75797637
(5, received_network_pubkey, option),
75807638
(7, fake_scid_rand_bytes, option),
75817639
(9, claimable_htlc_purposes, vec_type),
@@ -7834,7 +7892,7 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
78347892
pending_intercepted_htlcs: Mutex::new(pending_intercepted_htlcs.unwrap()),
78357893

78367894
forward_htlcs: Mutex::new(forward_htlcs),
7837-
claimable_payments: Mutex::new(ClaimablePayments { claimable_htlcs }),
7895+
claimable_payments: Mutex::new(ClaimablePayments { claimable_htlcs, pending_claimed_payments: pending_claimed_payments.unwrap() }),
78387896
outbound_scid_aliases: Mutex::new(outbound_scid_aliases),
78397897
id_to_peer: Mutex::new(id_to_peer),
78407898
short_to_chan_info: FairRwLock::new(short_to_chan_info),

0 commit comments

Comments
 (0)