@@ -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
@@ -6700,60 +6762,33 @@ where
6700
6762
6701
6763
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
6702
6764
6703
- let claiming_payment;
6704
- let sources = {
6705
- let mut claimable_payments = self.claimable_payments.lock().unwrap();
6706
- if let Some(payment) = claimable_payments.claimable_payments.remove(&payment_hash) {
6707
- let mut receiver_node_id = self.our_network_pubkey;
6708
- for htlc in payment.htlcs.iter() {
6709
- if htlc.prev_hop.phantom_shared_secret.is_some() {
6710
- let phantom_pubkey = self.node_signer.get_node_id(Recipient::PhantomNode)
6711
- .expect("Failed to get node_id for phantom node recipient");
6712
- receiver_node_id = phantom_pubkey;
6713
- break;
6765
+ let (sources, claiming_payment) = {
6766
+ let res = self.claimable_payments.lock().unwrap().begin_claiming_payment(
6767
+ payment_hash, &self.node_signer, &self.logger, &self.inbound_payment_id_secret,
6768
+ |onion_fields| {
6769
+ if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = onion_fields {
6770
+ if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
6771
+ log_info!(self.logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}",
6772
+ &payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
6773
+ return Err(());
6774
+ }
6714
6775
}
6776
+ Ok(())
6715
6777
}
6778
+ );
6716
6779
6717
- let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6718
- claiming_payment = claimable_payments.pending_claiming_payments
6719
- .entry(payment_hash)
6720
- .and_modify(|_| {
6721
- debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
6722
- log_error!(self.logger, "Got a duplicate pending claimable event on payment hash {}! Please report this bug",
6723
- &payment_hash);
6724
- })
6725
- .or_insert_with(|| {
6726
- let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
6727
- let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat);
6728
- ClaimingPayment {
6729
- amount_msat: payment.htlcs.iter().map(|source| source.value).sum(),
6730
- payment_purpose: payment.purpose,
6731
- receiver_node_id,
6732
- htlcs,
6733
- sender_intended_value,
6734
- onion_fields: payment.onion_fields,
6735
- payment_id: Some(payment_id),
6736
- }
6737
- }).clone();
6738
-
6739
- if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = claiming_payment.onion_fields {
6740
- if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
6741
- log_info!(self.logger, "Rejecting payment with payment hash {} as we cannot accept payment with unknown even TLVs: {}",
6742
- &payment_hash, log_iter!(custom_tlvs.iter().map(|(typ, _)| typ).filter(|typ| *typ % 2 == 0)));
6743
- claimable_payments.pending_claiming_payments.remove(&payment_hash);
6744
- mem::drop(claimable_payments);
6745
- for htlc in payment.htlcs {
6746
- let reason = self.get_htlc_fail_reason_from_failure_code(FailureCode::InvalidOnionPayload(None), &htlc);
6747
- let source = HTLCSource::PreviousHopData(htlc.prev_hop);
6748
- let receiver = HTLCDestination::FailedPayment { payment_hash };
6749
- self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
6750
- }
6751
- return;
6780
+ match res {
6781
+ Ok((htlcs, payment_info)) => (htlcs, payment_info),
6782
+ Err(htlcs) => {
6783
+ for htlc in htlcs {
6784
+ let reason = self.get_htlc_fail_reason_from_failure_code(FailureCode::InvalidOnionPayload(None), &htlc);
6785
+ let source = HTLCSource::PreviousHopData(htlc.prev_hop);
6786
+ let receiver = HTLCDestination::FailedPayment { payment_hash };
6787
+ self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
6752
6788
}
6789
+ return;
6753
6790
}
6754
-
6755
- payment.htlcs
6756
- } else { return; }
6791
+ }
6757
6792
};
6758
6793
debug_assert!(!sources.is_empty());
6759
6794
0 commit comments