Skip to content

Commit 1cce52c

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 6be25b0 commit 1cce52c

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
@@ -891,6 +891,68 @@ struct ClaimablePayments {
891891
pending_claiming_payments: HashMap<PaymentHash, ClaimingPayment>,
892892
}
893893

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

66906752
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
66916753

6692-
let claiming_payment;
6693-
let sources = {
6694-
let mut claimable_payments = self.claimable_payments.lock().unwrap();
6695-
if let Some(payment) = claimable_payments.claimable_payments.remove(&payment_hash) {
6696-
let mut receiver_node_id = self.our_network_pubkey;
6697-
for htlc in payment.htlcs.iter() {
6698-
if htlc.prev_hop.phantom_shared_secret.is_some() {
6699-
let phantom_pubkey = self.node_signer.get_node_id(Recipient::PhantomNode)
6700-
.expect("Failed to get node_id for phantom node recipient");
6701-
receiver_node_id = phantom_pubkey;
6702-
break;
6754+
let (sources, claiming_payment) = {
6755+
let res = self.claimable_payments.lock().unwrap().begin_claiming_payment(
6756+
payment_hash, &self.node_signer, &self.logger, &self.inbound_payment_id_secret,
6757+
|onion_fields| {
6758+
if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = onion_fields {
6759+
if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
6760+
log_info!(self.logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}",
6761+
&payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
6762+
return Err(());
6763+
}
67036764
}
6765+
Ok(())
67046766
}
6767+
);
67056768

6706-
let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6707-
claiming_payment = claimable_payments.pending_claiming_payments
6708-
.entry(payment_hash)
6709-
.and_modify(|_| {
6710-
debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
6711-
log_error!(self.logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug",
6712-
&payment_hash);
6713-
})
6714-
.or_insert_with(|| {
6715-
let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
6716-
let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat);
6717-
ClaimingPayment {
6718-
amount_msat: payment.htlcs.iter().map(|source| source.value).sum(),
6719-
payment_purpose: payment.purpose,
6720-
receiver_node_id,
6721-
htlcs,
6722-
sender_intended_value,
6723-
onion_fields: payment.onion_fields,
6724-
payment_id: Some(payment_id),
6725-
}
6726-
}).clone();
6727-
6728-
if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = claiming_payment.onion_fields {
6729-
if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
6730-
log_info!(self.logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}",
6731-
&payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
6732-
claimable_payments.pending_claiming_payments.remove(&payment_hash);
6733-
mem::drop(claimable_payments);
6734-
for htlc in payment.htlcs {
6735-
let reason = self.get_htlc_fail_reason_from_failure_code(FailureCode::InvalidOnionPayload(None), &htlc);
6736-
let source = HTLCSource::PreviousHopData(htlc.prev_hop);
6737-
let receiver = HTLCDestination::FailedPayment { payment_hash };
6738-
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
6739-
}
6740-
return;
6769+
match res {
6770+
Ok((htlcs, payment_info)) => (htlcs, payment_info),
6771+
Err(htlcs) => {
6772+
for htlc in htlcs {
6773+
let reason = self.get_htlc_fail_reason_from_failure_code(FailureCode::InvalidOnionPayload(None), &htlc);
6774+
let source = HTLCSource::PreviousHopData(htlc.prev_hop);
6775+
let receiver = HTLCDestination::FailedPayment { payment_hash };
6776+
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
67416777
}
6778+
return;
67426779
}
6743-
6744-
payment.htlcs
6745-
} else { return; }
6780+
}
67466781
};
67476782
debug_assert!(!sources.is_empty());
67486783

0 commit comments

Comments
 (0)