@@ -1134,8 +1134,9 @@ where
11341134 core:: mem:: take ( & mut self . pending_dns_onion_messages . lock ( ) . unwrap ( ) )
11351135 }
11361136
1137- /// Sends out [`OfferPathsRequest`] onion messages if we are an often-offline recipient and are
1138- /// configured to interactively build offers and static invoices with a static invoice server.
1137+ /// Sends out [`OfferPathsRequest`] and [`ServeStaticInvoice`] onion messages if we are an
1138+ /// often-offline recipient and are configured to interactively build offers and static invoices
1139+ /// with a static invoice server.
11391140 ///
11401141 /// # Usage
11411142 ///
@@ -1145,9 +1146,14 @@ where
11451146 ///
11461147 /// Errors if we failed to create blinded reply paths when sending an [`OfferPathsRequest`] message.
11471148 #[ cfg( async_payments) ]
1148- pub ( crate ) fn check_refresh_async_receive_offer_cache (
1149- & self , peers : Vec < MessageForwardNode > , timer_tick_occurred : bool ,
1150- ) -> Result < ( ) , ( ) > {
1149+ pub ( crate ) fn check_refresh_async_receive_offer_cache < ES : Deref , R : Deref > (
1150+ & self , peers : Vec < MessageForwardNode > , usable_channels : Vec < ChannelDetails > , entropy : ES ,
1151+ router : R , timer_tick_occurred : bool ,
1152+ ) -> Result < ( ) , ( ) >
1153+ where
1154+ ES :: Target : EntropySource ,
1155+ R :: Target : Router ,
1156+ {
11511157 // Terminate early if this node does not intend to receive async payments.
11521158 if self . paths_to_static_invoice_server . lock ( ) . unwrap ( ) . is_empty ( ) {
11531159 return Ok ( ( ) ) ;
@@ -1169,7 +1175,7 @@ where
11691175 path_absolute_expiry : duration_since_epoch
11701176 . saturating_add ( TEMP_REPLY_PATH_RELATIVE_EXPIRY ) ,
11711177 } ) ;
1172- let reply_paths = match self . create_blinded_paths ( peers, context) {
1178+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , context) {
11731179 Ok ( paths) => paths,
11741180 Err ( ( ) ) => {
11751181 return Err ( ( ) ) ;
@@ -1190,9 +1196,88 @@ where
11901196 ) ;
11911197 }
11921198
1199+ if timer_tick_occurred {
1200+ self . check_refresh_static_invoices (
1201+ peers,
1202+ usable_channels,
1203+ duration_since_epoch,
1204+ entropy,
1205+ router,
1206+ ) ;
1207+ }
1208+
11931209 Ok ( ( ) )
11941210 }
11951211
1212+ /// Enqueue onion messages that will used to request invoice refresh from the static invoice
1213+ /// server, based on the offers provided by the cache.
1214+ #[ cfg( async_payments) ]
1215+ fn check_refresh_static_invoices < ES : Deref , R : Deref > (
1216+ & self , peers : Vec < MessageForwardNode > , usable_channels : Vec < ChannelDetails > ,
1217+ duration_since_epoch : Duration , entropy : ES , router : R ,
1218+ ) where
1219+ ES :: Target : EntropySource ,
1220+ R :: Target : Router ,
1221+ {
1222+ let mut serve_static_invoice_msgs = Vec :: new ( ) ;
1223+ {
1224+ let cache = self . async_receive_offer_cache . lock ( ) . unwrap ( ) ;
1225+ for offer_and_metadata in cache. offers_needing_invoice_refresh ( ) {
1226+ let ( offer, offer_nonce, slot_number, update_static_invoice_path) =
1227+ offer_and_metadata;
1228+
1229+ let ( invoice, forward_invreq_path) = match self . create_static_invoice_for_server (
1230+ offer,
1231+ offer_nonce,
1232+ peers. clone ( ) ,
1233+ usable_channels. clone ( ) ,
1234+ & * entropy,
1235+ & * router,
1236+ ) {
1237+ Ok ( ( invoice, path) ) => ( invoice, path) ,
1238+ Err ( ( ) ) => continue ,
1239+ } ;
1240+
1241+ let reply_path_context = {
1242+ let path_absolute_expiry =
1243+ duration_since_epoch. saturating_add ( TEMP_REPLY_PATH_RELATIVE_EXPIRY ) ;
1244+ MessageContext :: AsyncPayments ( AsyncPaymentsContext :: StaticInvoicePersisted {
1245+ path_absolute_expiry,
1246+ offer_id : offer. id ( ) ,
1247+ } )
1248+ } ;
1249+
1250+ let serve_invoice_message = ServeStaticInvoice {
1251+ invoice,
1252+ forward_invoice_request_path : forward_invreq_path,
1253+ invoice_slot : slot_number,
1254+ } ;
1255+ serve_static_invoice_msgs. push ( (
1256+ serve_invoice_message,
1257+ update_static_invoice_path. clone ( ) ,
1258+ reply_path_context,
1259+ ) ) ;
1260+ }
1261+ }
1262+
1263+ // Enqueue the new serve_static_invoice messages in a separate loop to avoid holding the offer
1264+ // cache lock and the pending_async_payments_messages lock at the same time.
1265+ for ( serve_invoice_msg, serve_invoice_path, reply_path_ctx) in serve_static_invoice_msgs {
1266+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , reply_path_ctx) {
1267+ Ok ( paths) => paths,
1268+ Err ( ( ) ) => continue ,
1269+ } ;
1270+
1271+ let message = AsyncPaymentsMessage :: ServeStaticInvoice ( serve_invoice_msg) ;
1272+ enqueue_onion_message_with_reply_paths (
1273+ message,
1274+ & [ serve_invoice_path. into_blinded_path ( ) ] ,
1275+ reply_paths,
1276+ & mut self . pending_async_payments_messages . lock ( ) . unwrap ( ) ,
1277+ ) ;
1278+ }
1279+ }
1280+
11961281 /// Handles an incoming [`OfferPaths`] message from the static invoice server, sending out
11971282 /// [`ServeStaticInvoice`] onion messages in response if we've built a new async receive offer and
11981283 /// need the corresponding [`StaticInvoice`] to be persisted by the static invoice server.
0 commit comments