Skip to content

Commit 361ba90

Browse files
committed
(XXX: Release notes) 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. As these are still considered beta, breaking downgrades for such users is considered acceptable here.
1 parent 440c3ee commit 361ba90

File tree

1 file changed

+161
-105
lines changed

1 file changed

+161
-105
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 161 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,18 @@ pub(super) enum RAACommitmentOrder {
396396
RevokeAndACKFirst,
397397
}
398398

399+
/// Information about a payment which is currently being claimed.
400+
struct PendingClaimingPayment {
401+
amount_msat: u64,
402+
payment_purpose: events::PaymentPurpose,
403+
receiver_node_id: PublicKey,
404+
}
405+
impl_writeable_tlv_based!(PendingClaimingPayment, {
406+
(0, amount_msat, required),
407+
(2, payment_purpose, required),
408+
(4, receiver_node_id, required),
409+
});
410+
399411
// Note this is only exposed in cfg(test):
400412
pub(super) struct ChannelHolder<Signer: Sign> {
401413
pub(super) by_id: HashMap<[u8; 32], Channel<Signer>>,
@@ -761,6 +773,13 @@ pub struct ChannelManager<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
761773
/// See `ChannelManager` struct-level documentation for lock order requirements.
762774
claimable_htlcs: Mutex<HashMap<PaymentHash, (events::PaymentPurpose, Vec<ClaimableHTLC>)>>,
763775

776+
/// Map from payment hash to the payment data for HTLCs which we have begun claiming, but which
777+
/// are waiting on a [`ChannelMonitorUpdate`] to complete in order to be surfaced to the user
778+
/// as an [`events::Event::PaymentClaimed`].
779+
///
780+
/// See `ChannelManager` struct-level documentation for lock order requirements.
781+
pending_claimed_payments: Mutex<HashMap<PaymentHash, PendingClaimingPayment>>,
782+
764783
/// The set of outbound SCID aliases across all our channels, including unconfirmed channels
765784
/// and some closed channels which reached a usable state prior to being closed. This is used
766785
/// only to avoid duplicates, and is not persisted explicitly to disk, but rebuilt from the
@@ -1566,6 +1585,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
15661585
pending_outbound_payments: Mutex::new(HashMap::new()),
15671586
forward_htlcs: Mutex::new(HashMap::new()),
15681587
claimable_htlcs: Mutex::new(HashMap::new()),
1588+
pending_claimed_payments: Mutex::new(HashMap::new()),
15691589
id_to_peer: Mutex::new(HashMap::new()),
15701590
short_to_chan_info: FairRwLock::new(HashMap::new()),
15711591

@@ -3347,6 +3367,10 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
33473367
}
33483368
};
33493369
let mut claimable_htlcs = self.claimable_htlcs.lock().unwrap();
3370+
if self.pending_claimed_payments.lock().unwrap().contains_key(&payment_hash) {
3371+
fail_htlc!(claimable_htlc, payment_hash);
3372+
continue
3373+
}
33503374
let (_, htlcs) = claimable_htlcs.entry(payment_hash)
33513375
.or_insert_with(|| (purpose(), Vec::new()));
33523376
if htlcs.len() == 1 {
@@ -3419,7 +3443,12 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
34193443
check_total_value!(payment_data, payment_preimage);
34203444
},
34213445
OnionPayload::Spontaneous(preimage) => {
3422-
match self.claimable_htlcs.lock().unwrap().entry(payment_hash) {
3446+
let mut claimable_htlcs = self.claimable_htlcs.lock().unwrap();
3447+
if self.pending_claimed_payments.lock().unwrap().contains_key(&payment_hash) {
3448+
fail_htlc!(claimable_htlc, payment_hash);
3449+
continue
3450+
}
3451+
match claimable_htlcs.entry(payment_hash) {
34233452
hash_map::Entry::Vacant(e) => {
34243453
let purpose = events::PaymentPurpose::SpontaneousPayment(preimage);
34253454
e.insert((purpose.clone(), vec![claimable_htlc]));
@@ -4069,127 +4098,142 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
40694098

40704099
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
40714100

4072-
let removed_source = self.claimable_htlcs.lock().unwrap().remove(&payment_hash);
4073-
if let Some((payment_purpose, mut sources)) = removed_source {
4074-
assert!(!sources.is_empty());
4075-
4076-
// If we are claiming an MPP payment, we have to take special care to ensure that each
4077-
// channel exists before claiming all of the payments (inside one lock).
4078-
// Note that channel existance is sufficient as we should always get a monitor update
4079-
// which will take care of the real HTLC claim enforcement.
4080-
//
4081-
// If we find an HTLC which we would need to claim but for which we do not have a
4082-
// channel, we will fail all parts of the MPP payment. While we could wait and see if
4083-
// the sender retries the already-failed path(s), it should be a pretty rare case where
4084-
// we got all the HTLCs and then a channel closed while we were waiting for the user to
4085-
// provide the preimage, so worrying too much about the optimal handling isn't worth
4086-
// it.
4087-
let mut claimable_amt_msat = 0;
4088-
let mut expected_amt_msat = None;
4089-
let mut valid_mpp = true;
4090-
let mut errs = Vec::new();
4091-
let mut claimed_any_htlcs = false;
4092-
let mut channel_state_lock = self.channel_state.lock().unwrap();
4093-
let channel_state = &mut *channel_state_lock;
4094-
let mut receiver_node_id = Some(self.our_network_pubkey);
4095-
for htlc in sources.iter() {
4096-
let chan_id = match self.short_to_chan_info.read().unwrap().get(&htlc.prev_hop.short_channel_id) {
4097-
Some((_cp_id, chan_id)) => chan_id.clone(),
4098-
None => {
4099-
valid_mpp = false;
4101+
let mut sources = {
4102+
if let Some((payment_purpose, sources)) = self.claimable_htlcs.lock().unwrap().remove(&payment_hash) {
4103+
let mut receiver_node_id = self.our_network_pubkey;
4104+
for htlc in sources.iter() {
4105+
if htlc.prev_hop.phantom_shared_secret.is_some() {
4106+
let phantom_pubkey = self.keys_manager.get_node_id(Recipient::PhantomNode)
4107+
.expect("Failed to get node_id for phantom node recipient");
4108+
receiver_node_id = phantom_pubkey;
41004109
break;
41014110
}
4102-
};
4111+
}
41034112

4104-
if let None = channel_state.by_id.get(&chan_id) {
4105-
valid_mpp = false;
4106-
break;
4113+
let dup_purpose = self.pending_claimed_payments.lock().unwrap().insert(payment_hash,
4114+
PendingClaimingPayment { amount_msat: sources.iter().map(|source| source.value).sum(),
4115+
payment_purpose, receiver_node_id,
4116+
});
4117+
if dup_purpose.is_some() {
4118+
debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
4119+
log_error!(self.logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug",
4120+
log_bytes!(payment_hash.0));
41074121
}
4122+
sources
4123+
} else { return; }
4124+
};
4125+
debug_assert!(!sources.is_empty());
41084126

4109-
if expected_amt_msat.is_some() && expected_amt_msat != Some(htlc.total_msat) {
4110-
log_error!(self.logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!");
4111-
debug_assert!(false);
4127+
// If we are claiming an MPP payment, we have to take special care to ensure that each
4128+
// channel exists before claiming all of the payments (inside one lock).
4129+
// Note that channel existance is sufficient as we should always get a monitor update
4130+
// which will take care of the real HTLC claim enforcement.
4131+
//
4132+
// If we find an HTLC which we would need to claim but for which we do not have a
4133+
// channel, we will fail all parts of the MPP payment. While we could wait and see if
4134+
// the sender retries the already-failed path(s), it should be a pretty rare case where
4135+
// we got all the HTLCs and then a channel closed while we were waiting for the user to
4136+
// provide the preimage, so worrying too much about the optimal handling isn't worth
4137+
// it.
4138+
let mut claimable_amt_msat = 0;
4139+
let mut expected_amt_msat = None;
4140+
let mut valid_mpp = true;
4141+
let mut errs = Vec::new();
4142+
let mut claimed_any_htlcs = false;
4143+
let mut channel_state_lock = self.channel_state.lock().unwrap();
4144+
let channel_state = &mut *channel_state_lock;
4145+
for htlc in sources.iter() {
4146+
let chan_id = match self.short_to_chan_info.read().unwrap().get(&htlc.prev_hop.short_channel_id) {
4147+
Some((_cp_id, chan_id)) => chan_id.clone(),
4148+
None => {
41124149
valid_mpp = false;
41134150
break;
41144151
}
4115-
expected_amt_msat = Some(htlc.total_msat);
4116-
if let OnionPayload::Spontaneous(_) = &htlc.onion_payload {
4117-
// We don't currently support MPP for spontaneous payments, so just check
4118-
// that there's one payment here and move on.
4119-
if sources.len() != 1 {
4120-
log_error!(self.logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!");
4121-
debug_assert!(false);
4122-
valid_mpp = false;
4123-
break;
4124-
}
4125-
}
4126-
let phantom_shared_secret = htlc.prev_hop.phantom_shared_secret;
4127-
if phantom_shared_secret.is_some() {
4128-
let phantom_pubkey = self.keys_manager.get_node_id(Recipient::PhantomNode)
4129-
.expect("Failed to get node_id for phantom node recipient");
4130-
receiver_node_id = Some(phantom_pubkey)
4131-
}
4152+
};
41324153

4133-
claimable_amt_msat += htlc.value;
4134-
}
4135-
if sources.is_empty() || expected_amt_msat.is_none() {
4136-
log_info!(self.logger, "Attempted to claim an incomplete payment which no longer had any available HTLCs!");
4137-
return;
4154+
if let None = channel_state.by_id.get(&chan_id) {
4155+
valid_mpp = false;
4156+
break;
41384157
}
4139-
if claimable_amt_msat != expected_amt_msat.unwrap() {
4140-
log_info!(self.logger, "Attempted to claim an incomplete payment, expected {} msat, had {} available to claim.",
4141-
expected_amt_msat.unwrap(), claimable_amt_msat);
4142-
return;
4158+
4159+
if expected_amt_msat.is_some() && expected_amt_msat != Some(htlc.total_msat) {
4160+
log_error!(self.logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!");
4161+
debug_assert!(false);
4162+
valid_mpp = false;
4163+
break;
41434164
}
4144-
if valid_mpp {
4145-
for htlc in sources.drain(..) {
4146-
match self.claim_funds_from_hop(&mut channel_state_lock, htlc.prev_hop, payment_preimage) {
4147-
ClaimFundsFromHop::MonitorUpdateFail(pk, err, _) => {
4148-
if let msgs::ErrorAction::IgnoreError = err.err.action {
4149-
// We got a temporary failure updating monitor, but will claim the
4150-
// HTLC when the monitor updating is restored (or on chain).
4151-
log_error!(self.logger, "Temporary failure claiming HTLC, treating as success: {}", err.err.err);
4152-
claimed_any_htlcs = true;
4153-
} else { errs.push((pk, err)); }
4154-
},
4155-
ClaimFundsFromHop::PrevHopForceClosed => unreachable!("We already checked for channel existence, we can't fail here!"),
4156-
ClaimFundsFromHop::DuplicateClaim => {
4157-
// While we should never get here in most cases, if we do, it likely
4158-
// indicates that the HTLC was timed out some time ago and is no longer
4159-
// available to be claimed. Thus, it does not make sense to set
4160-
// `claimed_any_htlcs`.
4161-
},
4162-
ClaimFundsFromHop::Success(_) => claimed_any_htlcs = true,
4163-
}
4165+
expected_amt_msat = Some(htlc.total_msat);
4166+
if let OnionPayload::Spontaneous(_) = &htlc.onion_payload {
4167+
// We don't currently support MPP for spontaneous payments, so just check
4168+
// that there's one payment here and move on.
4169+
if sources.len() != 1 {
4170+
log_error!(self.logger, "Somehow ended up with an MPP spontaneous payment - this should not be reachable!");
4171+
debug_assert!(false);
4172+
valid_mpp = false;
4173+
break;
41644174
}
41654175
}
4166-
mem::drop(channel_state_lock);
4167-
if !valid_mpp {
4168-
for htlc in sources.drain(..) {
4169-
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
4170-
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
4171-
self.best_block.read().unwrap().height()));
4172-
self.fail_htlc_backwards_internal(
4173-
HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash,
4174-
HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_height_data },
4175-
HTLCDestination::FailedPayment { payment_hash } );
4176+
4177+
claimable_amt_msat += htlc.value;
4178+
}
4179+
if sources.is_empty() || expected_amt_msat.is_none() {
4180+
self.pending_claimed_payments.lock().unwrap().remove(&payment_hash);
4181+
log_info!(self.logger, "Attempted to claim an incomplete payment which no longer had any available HTLCs!");
4182+
return;
4183+
}
4184+
if claimable_amt_msat != expected_amt_msat.unwrap() {
4185+
self.pending_claimed_payments.lock().unwrap().remove(&payment_hash);
4186+
log_info!(self.logger, "Attempted to claim an incomplete payment, expected {} msat, had {} available to claim.",
4187+
expected_amt_msat.unwrap(), claimable_amt_msat);
4188+
return;
4189+
}
4190+
if valid_mpp {
4191+
for htlc in sources.drain(..) {
4192+
match self.claim_funds_from_hop(&mut channel_state_lock, htlc.prev_hop, payment_preimage) {
4193+
ClaimFundsFromHop::MonitorUpdateFail(pk, err, _) => {
4194+
if let msgs::ErrorAction::IgnoreError = err.err.action {
4195+
// We got a temporary failure updating monitor, but will claim the
4196+
// HTLC when the monitor updating is restored (or on chain).
4197+
log_error!(self.logger, "Temporary failure claiming HTLC, treating as success: {}", err.err.err);
4198+
claimed_any_htlcs = true;
4199+
} else { errs.push((pk, err)); }
4200+
},
4201+
ClaimFundsFromHop::PrevHopForceClosed => unreachable!("We already checked for channel existence, we can't fail here!"),
4202+
ClaimFundsFromHop::DuplicateClaim => {
4203+
// While we should never get here in most cases, if we do, it likely
4204+
// indicates that the HTLC was timed out some time ago and is no longer
4205+
// available to be claimed. Thus, it does not make sense to set
4206+
// `claimed_any_htlcs`.
4207+
},
4208+
ClaimFundsFromHop::Success(_) => claimed_any_htlcs = true,
41764209
}
41774210
}
4178-
4179-
if claimed_any_htlcs {
4180-
self.pending_events.lock().unwrap().push(events::Event::PaymentClaimed {
4181-
receiver_node_id,
4182-
payment_hash,
4183-
purpose: payment_purpose,
4184-
amount_msat: claimable_amt_msat,
4185-
});
4211+
}
4212+
mem::drop(channel_state_lock);
4213+
if !valid_mpp {
4214+
for htlc in sources.drain(..) {
4215+
let mut htlc_msat_height_data = byte_utils::be64_to_array(htlc.value).to_vec();
4216+
htlc_msat_height_data.extend_from_slice(&byte_utils::be32_to_array(
4217+
self.best_block.read().unwrap().height()));
4218+
self.fail_htlc_backwards_internal(
4219+
HTLCSource::PreviousHopData(htlc.prev_hop), &payment_hash,
4220+
HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_height_data },
4221+
HTLCDestination::FailedPayment { payment_hash } );
41864222
}
4223+
}
41874224

4188-
// Now we can handle any errors which were generated.
4189-
for (counterparty_node_id, err) in errs.drain(..) {
4190-
let res: Result<(), _> = Err(err);
4191-
let _ = handle_error!(self, res, counterparty_node_id);
4192-
}
4225+
let PendingClaimingPayment { amount_msat, payment_purpose: purpose, receiver_node_id } =
4226+
self.pending_claimed_payments.lock().unwrap().remove(&payment_hash).unwrap();
4227+
if claimed_any_htlcs {
4228+
self.pending_events.lock().unwrap().push(events::Event::PaymentClaimed {
4229+
payment_hash, purpose, amount_msat, receiver_node_id: Some(receiver_node_id),
4230+
});
4231+
}
4232+
4233+
// Now we can handle any errors which were generated.
4234+
for (counterparty_node_id, err) in errs.drain(..) {
4235+
let res: Result<(), _> = Err(err);
4236+
let _ = handle_error!(self, res, counterparty_node_id);
41934237
}
41944238
}
41954239

@@ -6991,8 +7035,17 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable for ChannelMana
69917035
_ => {},
69927036
}
69937037
}
7038+
7039+
let mut pending_claimed_payments = Some(self.pending_claimed_payments.lock().unwrap());
7040+
if pending_claimed_payments.as_ref().unwrap().is_empty() {
7041+
// LDK versions prior to 0.0.113 do not know how to read the pending claimed payments
7042+
// map. Thus, if there are no entries we skip writing a TLV for it.
7043+
pending_claimed_payments = None;
7044+
}
7045+
69947046
write_tlv_fields!(writer, {
69957047
(1, pending_outbound_payments_no_retry, required),
7048+
(2, pending_claimed_payments, option),
69967049
(3, pending_outbound_payments, required),
69977050
(5, self.our_network_pubkey, required),
69987051
(7, self.fake_scid_rand_bytes, required),
@@ -7310,8 +7363,10 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
73107363
let mut fake_scid_rand_bytes: Option<[u8; 32]> = None;
73117364
let mut probing_cookie_secret: Option<[u8; 32]> = None;
73127365
let mut claimable_htlc_purposes = None;
7366+
let mut pending_claimed_payments = Some(HashMap::new());
73137367
read_tlv_fields!(reader, {
73147368
(1, pending_outbound_payments_no_retry, option),
7369+
(2, pending_claimed_payments, option),
73157370
(3, pending_outbound_payments, option),
73167371
(5, received_network_pubkey, option),
73177372
(7, fake_scid_rand_bytes, option),
@@ -7537,6 +7592,7 @@ impl<'a, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
75377592

75387593
forward_htlcs: Mutex::new(forward_htlcs),
75397594
claimable_htlcs: Mutex::new(claimable_htlcs),
7595+
pending_claimed_payments: Mutex::new(pending_claimed_payments.unwrap()),
75407596
outbound_scid_aliases: Mutex::new(outbound_scid_aliases),
75417597
id_to_peer: Mutex::new(id_to_peer),
75427598
short_to_chan_info: FairRwLock::new(short_to_chan_info),

0 commit comments

Comments
 (0)