@@ -891,6 +891,68 @@ struct ClaimablePayments {
891
891
pending_claiming_payments: HashMap<PaymentHash, ClaimingPayment>,
892
892
}
893
893
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
+
894
956
/// Events which we process internally but cannot be processed immediately at the generation site
895
957
/// usually because we're running pre-full-init. They are handled immediately once we detect we are
896
958
/// running normally, and specifically must be processed before any other non-background
@@ -6689,60 +6751,33 @@ where
6689
6751
6690
6752
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
6691
6753
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
+ }
6703
6764
}
6765
+ Ok(())
6704
6766
}
6767
+ );
6705
6768
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);
6741
6777
}
6778
+ return;
6742
6779
}
6743
-
6744
- payment.htlcs
6745
- } else { return; }
6780
+ }
6746
6781
};
6747
6782
debug_assert!(!sources.is_empty());
6748
6783
0 commit comments