@@ -899,6 +899,68 @@ struct ClaimablePayments {
899
899
pending_claiming_payments: HashMap<PaymentHash, ClaimingPayment>,
900
900
}
901
901
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
+
902
964
/// Events which we process internally but cannot be processed immediately at the generation site
903
965
/// usually because we're running pre-full-init. They are handled immediately once we detect we are
904
966
/// running normally, and specifically must be processed before any other non-background
@@ -6698,60 +6760,33 @@ where
6698
6760
6699
6761
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
6700
6762
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
+ }
6712
6773
}
6774
+ Ok(())
6713
6775
}
6776
+ );
6714
6777
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);
6750
6786
}
6787
+ return;
6751
6788
}
6752
-
6753
- payment.htlcs
6754
- } else { return; }
6789
+ }
6755
6790
};
6756
6791
debug_assert!(!sources.is_empty());
6757
6792
0 commit comments