@@ -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 ;
@@ -50,10 +51,11 @@ use crate::payment::asynchronous::static_invoice_store::StaticInvoiceStore;
5051use crate :: payment:: store:: {
5152 PaymentDetails , PaymentDetailsUpdate , PaymentDirection , PaymentKind , PaymentStatus ,
5253} ;
53- use crate :: payment:: PaymentMetadata ;
54+ use crate :: payment:: { PaymentMetadata , PendingPaymentDetails } ;
5455use crate :: runtime:: Runtime ;
5556use crate :: types:: {
56- CustomTlvRecord , DynStore , KeysManager , OnionMessenger , PaymentStore , Sweeper , Wallet ,
57+ CustomTlvRecord , DynStore , KeysManager , OnionMessenger , PaymentStore , PendingPaymentStore ,
58+ Sweeper , Wallet ,
5759} ;
5860use crate :: {
5961 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 runtime : Arc < Runtime > ,
@@ -549,10 +552,10 @@ where
549552 channel_manager : Arc < ChannelManager > , connection_manager : Arc < ConnectionManager < L > > ,
550553 output_sweeper : Arc < Sweeper > , network_graph : Arc < Graph > ,
551554 liquidity_source : Arc < LiquiditySource < Arc < Logger > > > , payment_store : Arc < PaymentStore > ,
552- peer_store : Arc < PeerStore < L > > , keys_manager : Arc < KeysManager > ,
553- static_invoice_store : Option < StaticInvoiceStore > , onion_messenger : Arc < OnionMessenger > ,
554- om_mailbox : Option < Arc < OnionMessageMailbox > > , runtime : Arc < Runtime > , logger : L ,
555- config : Arc < Config > ,
555+ pending_payment_store : Arc < PendingPaymentStore > , peer_store : Arc < PeerStore < L > > ,
556+ keys_manager : Arc < KeysManager > , static_invoice_store : Option < StaticInvoiceStore > ,
557+ onion_messenger : Arc < OnionMessenger > , om_mailbox : Option < Arc < OnionMessageMailbox > > ,
558+ runtime : Arc < Runtime > , logger : L , config : Arc < Config > ,
556559 ) -> Self {
557560 Self {
558561 event_queue,
@@ -564,6 +567,7 @@ where
564567 network_graph,
565568 liquidity_source,
566569 payment_store,
570+ pending_payment_store,
567571 peer_store,
568572 keys_manager,
569573 logger,
@@ -605,6 +609,47 @@ where
605609 } )
606610 }
607611
612+ fn current_time_secs ( ) -> u64 {
613+ SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap_or ( Duration :: from_secs ( 0 ) ) . as_secs ( )
614+ }
615+
616+ async fn prune_expired_pending_payments ( & self ) -> Result < ( ) , ReplayEvent > {
617+ let now = Self :: current_time_secs ( ) ;
618+ let expired_payment_ids = self
619+ . pending_payment_store
620+ . list_filter ( |payment| payment. has_expired ( now) )
621+ . into_iter ( )
622+ . map ( |payment| payment. details . id )
623+ . collect :: < Vec < _ > > ( ) ;
624+
625+ for payment_id in expired_payment_ids {
626+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
627+ log_error ! (
628+ self . logger,
629+ "Failed to remove expired pending payment with ID {}: {}" ,
630+ payment_id,
631+ e
632+ ) ;
633+ return Err ( ReplayEvent ( ) ) ;
634+ }
635+ }
636+
637+ Ok ( ( ) )
638+ }
639+
640+ async fn find_pending_inbound_payment (
641+ & self , payment_hash : & PaymentHash ,
642+ ) -> Result < Option < PendingPaymentDetails > , ReplayEvent > {
643+ self . prune_expired_pending_payments ( ) . await ?;
644+ Ok ( self . pending_payment_store . list_by_payment_hash ( payment_hash) . into_iter ( ) . find (
645+ |payment| {
646+ payment. details . direction == PaymentDirection :: Inbound
647+ && payment. details . status == PaymentStatus :: Pending
648+ && matches ! ( & payment. details. kind, PaymentKind :: Bolt11 { hash, .. } if hash == payment_hash)
649+ } ,
650+ ) )
651+ }
652+
608653 pub async fn handle_event ( & self , event : LdkEvent ) -> Result < ( ) , ReplayEvent > {
609654 match event {
610655 LdkEvent :: FundingGenerationReady {
@@ -718,6 +763,11 @@ where
718763 } => {
719764 let payment_id = PaymentId ( payment_hash. 0 ) ;
720765 let payment_info = self . payment_store . get ( & payment_id) ;
766+ let pending_payment = if payment_info. is_none ( ) {
767+ self . find_pending_inbound_payment ( & payment_hash) . await ?
768+ } else {
769+ None
770+ } ;
721771 if let Some ( info) = payment_info. as_ref ( ) {
722772 if info. direction == PaymentDirection :: Outbound {
723773 log_info ! (
@@ -803,6 +853,17 @@ where
803853 counterparty_skimmed_fee_msat,
804854 ) ;
805855 self . fail_claimable_payment ( payment_id, & payment_hash) . await ?;
856+ if pending_payment. is_some ( ) {
857+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
858+ log_error ! (
859+ self . logger,
860+ "Failed to remove pending payment with ID {}: {}" ,
861+ payment_id,
862+ e
863+ ) ;
864+ return Err ( ReplayEvent ( ) ) ;
865+ }
866+ }
806867 return Ok ( ( ) ) ;
807868 } ;
808869
@@ -815,6 +876,17 @@ where
815876 max_total_opening_fee_msat,
816877 ) ;
817878 self . fail_claimable_payment ( payment_id, & payment_hash) . await ?;
879+ if pending_payment. is_some ( ) {
880+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
881+ log_error ! (
882+ self . logger,
883+ "Failed to remove pending payment with ID {}: {}" ,
884+ payment_id,
885+ e
886+ ) ;
887+ return Err ( ReplayEvent ( ) ) ;
888+ }
889+ }
818890 return Ok ( ( ) ) ;
819891 }
820892
@@ -838,6 +910,57 @@ where
838910 }
839911 }
840912
913+ let payment_info = if let Some ( pending_payment) = pending_payment. as_ref ( ) {
914+ let mut payment = pending_payment. details . clone ( ) ;
915+ if let PaymentKind :: Bolt11 {
916+ counterparty_skimmed_fee_msat : stored_fee, ..
917+ } = & mut payment. kind
918+ {
919+ if counterparty_skimmed_fee_msat > 0 {
920+ * stored_fee = Some ( counterparty_skimmed_fee_msat) ;
921+ }
922+ }
923+
924+ match self . payment_store . insert ( payment. clone ( ) ) . await {
925+ Ok ( false ) => ( ) ,
926+ Ok ( true ) => {
927+ log_error ! (
928+ self . logger,
929+ "Bolt11InvoicePayment with ID {} was previously known" ,
930+ payment_id,
931+ ) ;
932+ debug_assert ! ( false ) ;
933+ } ,
934+ Err ( e) => {
935+ log_error ! (
936+ self . logger,
937+ "Failed to insert payment with ID {}: {}" ,
938+ payment_id,
939+ e
940+ ) ;
941+ return Err ( ReplayEvent ( ) ) ;
942+ } ,
943+ }
944+
945+ let mut pending_payment = pending_payment. clone ( ) ;
946+ pending_payment. expires_at = None ;
947+ if let Err ( e) =
948+ self . pending_payment_store . insert_or_update ( pending_payment) . await
949+ {
950+ log_error ! (
951+ self . logger,
952+ "Failed to update pending payment with ID {}: {}" ,
953+ payment_id,
954+ e
955+ ) ;
956+ return Err ( ReplayEvent ( ) ) ;
957+ }
958+
959+ Some ( payment)
960+ } else {
961+ payment_info
962+ } ;
963+
841964 if let Some ( info) = payment_info {
842965 // If this is known by the store but ChannelManager doesn't know the preimage,
843966 // the payment has been registered via `_for_hash` variants and needs to be manually claimed via
@@ -1088,6 +1211,16 @@ where
10881211 } ,
10891212 }
10901213
1214+ if let Err ( e) = self . pending_payment_store . remove ( & payment_id) . await {
1215+ log_error ! (
1216+ self . logger,
1217+ "Failed to remove pending payment with ID {}: {}" ,
1218+ payment_id,
1219+ e
1220+ ) ;
1221+ return Err ( ReplayEvent ( ) ) ;
1222+ }
1223+
10911224 let event = Event :: PaymentReceived {
10921225 payment_id,
10931226 payment_hash,
0 commit comments