@@ -1127,8 +1127,9 @@ where
11271127 core:: mem:: take ( & mut self . pending_dns_onion_messages . lock ( ) . unwrap ( ) )
11281128 }
11291129
1130- /// Sends out [`OfferPathsRequest`] onion messages if we are an often-offline recipient and are
1131- /// configured to interactively build offers and static invoices with a static invoice server.
1130+ /// Sends out [`OfferPathsRequest`] and [`ServeStaticInvoice`] onion messages if we are an
1131+ /// often-offline recipient and are configured to interactively build offers and static invoices
1132+ /// with a static invoice server.
11321133 ///
11331134 /// # Usage
11341135 ///
@@ -1140,9 +1141,14 @@ where
11401141 ///
11411142 /// Errors if we failed to create blinded reply paths when sending an [`OfferPathsRequest`] message.
11421143 #[ cfg( async_payments) ]
1143- pub ( crate ) fn check_refresh_async_receive_offers (
1144- & self , peers : Vec < MessageForwardNode > , timer_tick_occurred : bool ,
1145- ) -> Result < ( ) , ( ) > {
1144+ pub ( crate ) fn check_refresh_async_receive_offers < ES : Deref , R : Deref > (
1145+ & self , peers : Vec < MessageForwardNode > , usable_channels : Vec < ChannelDetails > , entropy : ES ,
1146+ router : R , timer_tick_occurred : bool ,
1147+ ) -> Result < ( ) , ( ) >
1148+ where
1149+ ES :: Target : EntropySource ,
1150+ R :: Target : Router ,
1151+ {
11461152 // Terminate early if this node does not intend to receive async payments.
11471153 if self . paths_to_static_invoice_server . lock ( ) . unwrap ( ) . is_empty ( ) {
11481154 return Ok ( ( ) ) ;
@@ -1164,7 +1170,7 @@ where
11641170 path_absolute_expiry : duration_since_epoch
11651171 . saturating_add ( TEMP_REPLY_PATH_RELATIVE_EXPIRY ) ,
11661172 } ) ;
1167- let reply_paths = match self . create_blinded_paths ( peers, context) {
1173+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , context) {
11681174 Ok ( paths) => paths,
11691175 Err ( ( ) ) => {
11701176 return Err ( ( ) ) ;
@@ -1188,9 +1194,85 @@ where
11881194 ) ;
11891195 }
11901196
1197+ if timer_tick_occurred {
1198+ self . check_refresh_static_invoices ( peers, usable_channels, entropy, router) ;
1199+ }
1200+
11911201 Ok ( ( ) )
11921202 }
11931203
1204+ /// Enqueue onion messages that will used to request invoice refresh from the static invoice
1205+ /// server, based on the offers provided by the cache.
1206+ #[ cfg( async_payments) ]
1207+ fn check_refresh_static_invoices < ES : Deref , R : Deref > (
1208+ & self , peers : Vec < MessageForwardNode > , usable_channels : Vec < ChannelDetails > , entropy : ES ,
1209+ router : R ,
1210+ ) where
1211+ ES :: Target : EntropySource ,
1212+ R :: Target : Router ,
1213+ {
1214+ let duration_since_epoch = self . duration_since_epoch ( ) ;
1215+
1216+ let mut serve_static_invoice_messages = Vec :: new ( ) ;
1217+ {
1218+ let cache = self . async_receive_offer_cache . lock ( ) . unwrap ( ) ;
1219+ for offer_and_metadata in cache. offers_needing_invoice_refresh ( ) {
1220+ let ( offer, offer_nonce, offer_slot, update_static_invoice_path) =
1221+ offer_and_metadata;
1222+
1223+ let ( invoice, forward_invreq_path) = match self . create_static_invoice_for_server (
1224+ offer,
1225+ offer_nonce,
1226+ peers. clone ( ) ,
1227+ usable_channels. clone ( ) ,
1228+ & * entropy,
1229+ & * router,
1230+ ) {
1231+ Ok ( ( invoice, path) ) => ( invoice, path) ,
1232+ Err ( ( ) ) => continue ,
1233+ } ;
1234+
1235+ let reply_path_context = {
1236+ let path_absolute_expiry =
1237+ duration_since_epoch. saturating_add ( TEMP_REPLY_PATH_RELATIVE_EXPIRY ) ;
1238+ MessageContext :: AsyncPayments ( AsyncPaymentsContext :: StaticInvoicePersisted {
1239+ path_absolute_expiry,
1240+ offer_slot,
1241+ } )
1242+ } ;
1243+
1244+ let serve_invoice_message = ServeStaticInvoice {
1245+ invoice,
1246+ forward_invoice_request_path : forward_invreq_path,
1247+ invoice_slot : offer_slot,
1248+ } ;
1249+ serve_static_invoice_messages. push ( (
1250+ serve_invoice_message,
1251+ update_static_invoice_path. clone ( ) ,
1252+ reply_path_context,
1253+ ) ) ;
1254+ }
1255+ }
1256+
1257+ // Enqueue the new serve_static_invoice messages in a separate loop to avoid holding the offer
1258+ // cache lock and the pending_async_payments_messages lock at the same time.
1259+ for ( serve_invoice_msg, serve_invoice_path, reply_path_ctx) in serve_static_invoice_messages
1260+ {
1261+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , reply_path_ctx) {
1262+ Ok ( paths) => paths,
1263+ Err ( ( ) ) => continue ,
1264+ } ;
1265+
1266+ let message = AsyncPaymentsMessage :: ServeStaticInvoice ( serve_invoice_msg) ;
1267+ enqueue_onion_message_with_reply_paths (
1268+ message,
1269+ & [ serve_invoice_path. into_blinded_path ( ) ] ,
1270+ reply_paths,
1271+ & mut self . pending_async_payments_messages . lock ( ) . unwrap ( ) ,
1272+ ) ;
1273+ }
1274+ }
1275+
11941276 /// Handles an incoming [`OfferPaths`] message from the static invoice server, sending out
11951277 /// [`ServeStaticInvoice`] onion messages in response if we want to use the paths we've received
11961278 /// to build and cache an async receive offer.
0 commit comments