Skip to content

Commit 22d39f9

Browse files
committed
Move payment claim initialization to an fn on ClaimablePayments
Here we wrap the logic which moves claimable payments from `claimable_payments` to `pending_claiming_payments` to a new utility function on `ClaimablePayments`. This will allow us to call this new logic during `ChannelManager` deserialization in a few commits.
1 parent f0035ef commit 22d39f9

File tree

1 file changed

+84
-49
lines changed

1 file changed

+84
-49
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 84 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,68 @@ struct ClaimablePayments {
899899
pending_claiming_payments: HashMap<PaymentHash, ClaimingPayment>,
900900
}
901901

902+
impl ClaimablePayments {
903+
/// Moves a payment from [`Self::claimable_payments`] to [`Self::pending_claiming_payments`].
904+
///
905+
/// The `check_onion` callback allows the caller to reject the payment based on the
906+
/// [`RecipientOnionFields`] (if any). If it returns `Err(_)`, the set of pending HTLCs will
907+
/// be returned in the `Err` variant of this method. They MUST then be failed by the caller as
908+
/// they will not be in either [`Self::claimable_payments`] or
909+
/// [`Self::pending_claiming_payments`].
910+
///
911+
/// If no payment is found, `Err(Vec::new())` is returned.
912+
fn begin_claiming_payment<CheckOnion: Fn(&Option<RecipientOnionFields>) -> Result<(), ()>, L: Deref, S: Deref>(
913+
&mut self, payment_hash: PaymentHash, node_signer: &S, logger: &L,
914+
inbound_payment_id_secret: &[u8; 32], check_onion: CheckOnion,
915+
) -> Result<(Vec<ClaimableHTLC>, ClaimingPayment), Vec<ClaimableHTLC>>
916+
where L::Target: Logger, S::Target: NodeSigner,
917+
{
918+
match self.claimable_payments.remove(&payment_hash) {
919+
Some(payment) => {
920+
let mut receiver_node_id = node_signer.get_node_id(Recipient::Node)
921+
.expect("Failed to get node_id for node recipient");
922+
for htlc in payment.htlcs.iter() {
923+
if htlc.prev_hop.phantom_shared_secret.is_some() {
924+
let phantom_pubkey = node_signer.get_node_id(Recipient::PhantomNode)
925+
.expect("Failed to get node_id for phantom node recipient");
926+
receiver_node_id = phantom_pubkey;
927+
break;
928+
}
929+
}
930+
931+
if check_onion(&payment.onion_fields).is_err() {
932+
return Err(payment.htlcs);
933+
}
934+
935+
let payment_id = payment.inbound_payment_id(inbound_payment_id_secret);
936+
let claiming_payment = self.pending_claiming_payments
937+
.entry(payment_hash)
938+
.and_modify(|_| {
939+
debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
940+
log_error!(logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug",
941+
&payment_hash);
942+
})
943+
.or_insert_with(|| {
944+
let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
945+
let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat);
946+
ClaimingPayment {
947+
amount_msat: payment.htlcs.iter().map(|source| source.value).sum(),
948+
payment_purpose: payment.purpose,
949+
receiver_node_id,
950+
htlcs,
951+
sender_intended_value,
952+
onion_fields: payment.onion_fields,
953+
payment_id: Some(payment_id),
954+
}
955+
}).clone();
956+
957+
Ok((payment.htlcs, claiming_payment))
958+
},
959+
None => Err(Vec::new())
960+
}
961+
}
962+
}
963+
902964
/// Events which we process internally but cannot be processed immediately at the generation site
903965
/// usually because we're running pre-full-init. They are handled immediately once we detect we are
904966
/// running normally, and specifically must be processed before any other non-background
@@ -6698,60 +6760,33 @@ where
66986760

66996761
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
67006762

6701-
let claiming_payment;
6702-
let sources = {
6703-
let mut claimable_payments = self.claimable_payments.lock().unwrap();
6704-
if let Some(payment) = claimable_payments.claimable_payments.remove(&payment_hash) {
6705-
let mut receiver_node_id = self.our_network_pubkey;
6706-
for htlc in payment.htlcs.iter() {
6707-
if htlc.prev_hop.phantom_shared_secret.is_some() {
6708-
let phantom_pubkey = self.node_signer.get_node_id(Recipient::PhantomNode)
6709-
.expect("Failed to get node_id for phantom node recipient");
6710-
receiver_node_id = phantom_pubkey;
6711-
break;
6763+
let (sources, claiming_payment) = {
6764+
let res = self.claimable_payments.lock().unwrap().begin_claiming_payment(
6765+
payment_hash, &self.node_signer, &self.logger, &self.inbound_payment_id_secret,
6766+
|onion_fields| {
6767+
if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = onion_fields {
6768+
if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
6769+
log_info!(self.logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}",
6770+
&payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
6771+
return Err(());
6772+
}
67126773
}
6774+
Ok(())
67136775
}
6776+
);
67146777

6715-
let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6716-
claiming_payment = claimable_payments.pending_claiming_payments
6717-
.entry(payment_hash)
6718-
.and_modify(|_| {
6719-
debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
6720-
log_error!(self.logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug",
6721-
&payment_hash);
6722-
})
6723-
.or_insert_with(|| {
6724-
let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
6725-
let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat);
6726-
ClaimingPayment {
6727-
amount_msat: payment.htlcs.iter().map(|source| source.value).sum(),
6728-
payment_purpose: payment.purpose,
6729-
receiver_node_id,
6730-
htlcs,
6731-
sender_intended_value,
6732-
onion_fields: payment.onion_fields,
6733-
payment_id: Some(payment_id),
6734-
}
6735-
}).clone();
6736-
6737-
if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = claiming_payment.onion_fields {
6738-
if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
6739-
log_info!(self.logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}",
6740-
&payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
6741-
claimable_payments.pending_claiming_payments.remove(&payment_hash);
6742-
mem::drop(claimable_payments);
6743-
for htlc in payment.htlcs {
6744-
let reason = self.get_htlc_fail_reason_from_failure_code(FailureCode::InvalidOnionPayload(None), &htlc);
6745-
let source = HTLCSource::PreviousHopData(htlc.prev_hop);
6746-
let receiver = HTLCDestination::FailedPayment { payment_hash };
6747-
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
6748-
}
6749-
return;
6778+
match res {
6779+
Ok((htlcs, payment_info)) => (htlcs, payment_info),
6780+
Err(htlcs) => {
6781+
for htlc in htlcs {
6782+
let reason = self.get_htlc_fail_reason_from_failure_code(FailureCode::InvalidOnionPayload(None), &htlc);
6783+
let source = HTLCSource::PreviousHopData(htlc.prev_hop);
6784+
let receiver = HTLCDestination::FailedPayment { payment_hash };
6785+
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
67506786
}
6787+
return;
67516788
}
6752-
6753-
payment.htlcs
6754-
} else { return; }
6789+
}
67556790
};
67566791
debug_assert!(!sources.is_empty());
67576792

0 commit comments

Comments
 (0)