@@ -10,6 +10,7 @@ use core::task::{Poll, Waker};
1010use std:: collections:: VecDeque ;
1111use std:: ops:: Deref ;
1212use std:: sync:: { Arc , Mutex } ;
13+ use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
1314
1415use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
1516use bitcoin:: secp256k1:: PublicKey ;
@@ -51,11 +52,12 @@ use crate::payment::asynchronous::static_invoice_store::StaticInvoiceStore;
5152use crate :: payment:: store:: {
5253 PaymentDetails , PaymentDetailsUpdate , PaymentDirection , PaymentKind , PaymentStatus ,
5354} ;
54- use crate :: payment:: PaymentMetadata ;
55+ use crate :: payment:: { PaymentMetadata , PendingPaymentDetails } ;
5556use crate :: probing:: Prober ;
5657use crate :: runtime:: Runtime ;
5758use crate :: types:: {
58- CustomTlvRecord , DynStore , KeysManager , OnionMessenger , PaymentStore , Sweeper , Wallet ,
59+ CustomTlvRecord , DynStore , KeysManager , OnionMessenger , PaymentStore , PendingPaymentStore ,
60+ Sweeper , Wallet ,
5961} ;
6062use crate :: {
6163 hex_utils, BumpTransactionEventHandler , ChannelManager , Error , Graph , PeerInfo , PeerStore ,
@@ -529,6 +531,7 @@ where
529531 network_graph : Arc < Graph > ,
530532 liquidity_source : Arc < LiquiditySource < Arc < Logger > > > ,
531533 payment_store : Arc < PaymentStore > ,
534+ pending_payment_store : Arc < PendingPaymentStore > ,
532535 peer_store : Arc < PeerStore < L > > ,
533536 keys_manager : Arc < KeysManager > ,
534537 static_invoice_store : Option < StaticInvoiceStore > ,
@@ -550,10 +553,10 @@ where
550553 channel_manager : Arc < ChannelManager > , connection_manager : Arc < ConnectionManager < L > > ,
551554 output_sweeper : Arc < Sweeper > , network_graph : Arc < Graph > ,
552555 liquidity_source : Arc < LiquiditySource < Arc < Logger > > > , payment_store : Arc < PaymentStore > ,
553- peer_store : Arc < PeerStore < L > > , keys_manager : Arc < KeysManager > ,
554- static_invoice_store : Option < StaticInvoiceStore > , onion_messenger : Arc < OnionMessenger > ,
555- om_mailbox : Option < Arc < OnionMessageMailbox > > , prober : Option < Arc < Prober > > ,
556- runtime : Arc < Runtime > , logger : L , config : Arc < Config > ,
556+ pending_payment_store : Arc < PendingPaymentStore > , peer_store : Arc < PeerStore < L > > ,
557+ keys_manager : Arc < KeysManager > , static_invoice_store : Option < StaticInvoiceStore > ,
558+ onion_messenger : Arc < OnionMessenger > , om_mailbox : Option < Arc < OnionMessageMailbox > > ,
559+ prober : Option < Arc < Prober > > , runtime : Arc < Runtime > , logger : L , config : Arc < Config > ,
557560 ) -> Self {
558561 Self {
559562 event_queue,
@@ -565,6 +568,7 @@ where
565568 network_graph,
566569 liquidity_source,
567570 payment_store,
571+ pending_payment_store,
568572 peer_store,
569573 keys_manager,
570574 static_invoice_store,
@@ -607,6 +611,41 @@ where
607611 } )
608612 }
609613
614+ fn current_time_secs ( ) -> u64 {
615+ SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap_or ( Duration :: from_secs ( 0 ) ) . as_secs ( )
616+ }
617+
618+ async fn prune_expired_pending_payments ( & self ) -> Result < ( ) , ReplayEvent > {
619+ let now = Self :: current_time_secs ( ) ;
620+ let expired_payment_ids = self
621+ . pending_payment_store
622+ . list_filter ( |payment| payment. has_expired ( now) )
623+ . into_iter ( )
624+ . map ( |payment| payment. details . id )
625+ . collect :: < Vec < _ > > ( ) ;
626+
627+ for payment_id in expired_payment_ids {
628+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
629+ log_error ! (
630+ self . logger,
631+ "Failed to remove expired pending payment with ID {}: {}" ,
632+ payment_id,
633+ e
634+ ) ;
635+ return Err ( ReplayEvent ( ) ) ;
636+ }
637+ }
638+
639+ Ok ( ( ) )
640+ }
641+
642+ async fn find_pending_inbound_payment (
643+ & self , payment_hash : & PaymentHash ,
644+ ) -> Result < Option < PendingPaymentDetails > , ReplayEvent > {
645+ self . prune_expired_pending_payments ( ) . await ?;
646+ Ok ( self . pending_payment_store . get_pending_manual_bolt11_by_payment_hash ( payment_hash) )
647+ }
648+
610649 pub async fn handle_event ( & self , event : LdkEvent ) -> Result < ( ) , ReplayEvent > {
611650 match event {
612651 LdkEvent :: FundingGenerationReady {
@@ -720,6 +759,11 @@ where
720759 } => {
721760 let payment_id = PaymentId ( payment_hash. 0 ) ;
722761 let payment_info = self . payment_store . get ( & payment_id) ;
762+ let pending_payment = if payment_info. is_none ( ) {
763+ self . find_pending_inbound_payment ( & payment_hash) . await ?
764+ } else {
765+ None
766+ } ;
723767 if let Some ( info) = payment_info. as_ref ( ) {
724768 if info. direction == PaymentDirection :: Outbound {
725769 log_info ! (
@@ -805,6 +849,17 @@ where
805849 counterparty_skimmed_fee_msat,
806850 ) ;
807851 self . fail_claimable_payment ( payment_id, & payment_hash) . await ?;
852+ if pending_payment. is_some ( ) {
853+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
854+ log_error ! (
855+ self . logger,
856+ "Failed to remove pending payment with ID {}: {}" ,
857+ payment_id,
858+ e
859+ ) ;
860+ return Err ( ReplayEvent ( ) ) ;
861+ }
862+ }
808863 return Ok ( ( ) ) ;
809864 } ;
810865
@@ -817,6 +872,17 @@ where
817872 max_total_opening_fee_msat,
818873 ) ;
819874 self . fail_claimable_payment ( payment_id, & payment_hash) . await ?;
875+ if pending_payment. is_some ( ) {
876+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
877+ log_error ! (
878+ self . logger,
879+ "Failed to remove pending payment with ID {}: {}" ,
880+ payment_id,
881+ e
882+ ) ;
883+ return Err ( ReplayEvent ( ) ) ;
884+ }
885+ }
820886 return Ok ( ( ) ) ;
821887 }
822888
@@ -840,6 +906,57 @@ where
840906 }
841907 }
842908
909+ let payment_info = if let Some ( pending_payment) = pending_payment. as_ref ( ) {
910+ let mut payment = pending_payment. details . clone ( ) ;
911+ if let PaymentKind :: Bolt11 {
912+ counterparty_skimmed_fee_msat : stored_fee, ..
913+ } = & mut payment. kind
914+ {
915+ if counterparty_skimmed_fee_msat > 0 {
916+ * stored_fee = Some ( counterparty_skimmed_fee_msat) ;
917+ }
918+ }
919+
920+ match self . payment_store . insert ( payment. clone ( ) ) . await {
921+ Ok ( false ) => ( ) ,
922+ Ok ( true ) => {
923+ log_error ! (
924+ self . logger,
925+ "Bolt11InvoicePayment with ID {} was previously known" ,
926+ payment_id,
927+ ) ;
928+ debug_assert ! ( false ) ;
929+ } ,
930+ Err ( e) => {
931+ log_error ! (
932+ self . logger,
933+ "Failed to insert payment with ID {}: {}" ,
934+ payment_id,
935+ e
936+ ) ;
937+ return Err ( ReplayEvent ( ) ) ;
938+ } ,
939+ }
940+
941+ let mut pending_payment = pending_payment. clone ( ) ;
942+ pending_payment. expires_at = None ;
943+ if let Err ( e) =
944+ self . pending_payment_store . insert_or_update ( pending_payment) . await
945+ {
946+ log_error ! (
947+ self . logger,
948+ "Failed to update pending payment with ID {}: {}" ,
949+ payment_id,
950+ e
951+ ) ;
952+ return Err ( ReplayEvent ( ) ) ;
953+ }
954+
955+ Some ( payment)
956+ } else {
957+ payment_info
958+ } ;
959+
843960 if let Some ( info) = payment_info {
844961 // If this is known by the store but ChannelManager doesn't know the preimage,
845962 // the payment has been registered via `_for_hash` variants and needs to be manually claimed via
@@ -1090,6 +1207,16 @@ where
10901207 } ,
10911208 }
10921209
1210+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
1211+ log_error ! (
1212+ self . logger,
1213+ "Failed to remove pending payment with ID {}: {}" ,
1214+ payment_id,
1215+ e
1216+ ) ;
1217+ return Err ( ReplayEvent ( ) ) ;
1218+ }
1219+
10931220 let event = Event :: PaymentReceived {
10941221 payment_id,
10951222 payment_hash,
0 commit comments