@@ -1115,8 +1115,9 @@ where
11151115 core:: mem:: take ( & mut self . pending_dns_onion_messages . lock ( ) . unwrap ( ) )
11161116 }
11171117
1118- /// Sends out [`OfferPathsRequest`] onion messages if we are an often-offline recipient and are
1119- /// configured to interactively build offers and static invoices with a static invoice server.
1118+ /// Sends out [`OfferPathsRequest`] and [`ServeStaticInvoice`] onion messages if we are an
1119+ /// often-offline recipient and are configured to interactively build offers and static invoices
1120+ /// with a static invoice server.
11201121 ///
11211122 /// # Usage
11221123 ///
@@ -1125,11 +1126,13 @@ where
11251126 ///
11261127 /// Errors if we failed to create blinded reply paths when sending an [`OfferPathsRequest`] message.
11271128 #[ cfg( async_payments) ]
1128- pub ( crate ) fn check_refresh_async_receive_offers < ES : Deref > (
1129- & self , peers : Vec < MessageForwardNode > , entropy : ES ,
1129+ pub ( crate ) fn check_refresh_async_receive_offers < ES : Deref , R : Deref > (
1130+ & self , peers : Vec < MessageForwardNode > , usable_channels : Vec < ChannelDetails > , entropy : ES ,
1131+ router : R ,
11301132 ) -> Result < ( ) , ( ) >
11311133 where
11321134 ES :: Target : EntropySource ,
1135+ R :: Target : Router ,
11331136 {
11341137 // Terminate early if this node does not intend to receive async payments.
11351138 if self . paths_to_static_invoice_server . is_empty ( ) {
@@ -1155,7 +1158,7 @@ where
11551158 path_absolute_expiry : duration_since_epoch
11561159 . saturating_add ( TEMP_REPLY_PATH_RELATIVE_EXPIRY ) ,
11571160 } ) ;
1158- let reply_paths = match self . create_blinded_paths ( peers, context) {
1161+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , context) {
11591162 Ok ( paths) => paths,
11601163 Err ( ( ) ) => {
11611164 return Err ( ( ) ) ;
@@ -1175,9 +1178,77 @@ where
11751178 ) ;
11761179 }
11771180
1181+ self . check_refresh_static_invoices ( peers, usable_channels, entropy, router) ;
1182+
11781183 Ok ( ( ) )
11791184 }
11801185
1186+ /// If a static invoice server has persisted an offer for us but the corresponding invoice is
1187+ /// expiring soon, we need to refresh that invoice. Here we enqueue the onion messages that will
1188+ /// be used to request invoice refresh, based on the offers provided by the cache.
1189+ fn check_refresh_static_invoices < ES : Deref , R : Deref > (
1190+ & self , peers : Vec < MessageForwardNode > , usable_channels : Vec < ChannelDetails > , entropy : ES ,
1191+ router : R ,
1192+ ) where
1193+ ES :: Target : EntropySource ,
1194+ R :: Target : Router ,
1195+ {
1196+ let duration_since_epoch = self . duration_since_epoch ( ) ;
1197+
1198+ let mut serve_static_invoice_messages = Vec :: new ( ) ;
1199+ {
1200+ let cache = self . async_receive_offer_cache . lock ( ) . unwrap ( ) ;
1201+ for offer_and_metadata in cache. offers_needing_invoice_refresh ( duration_since_epoch) {
1202+ let ( offer, offer_nonce, offer_created_at, update_static_invoice_path) =
1203+ offer_and_metadata;
1204+ let offer_id = offer. id ( ) ;
1205+
1206+ let ( serve_invoice_msg, reply_path_ctx) = match self
1207+ . create_serve_static_invoice_message (
1208+ offer. clone ( ) ,
1209+ offer_nonce,
1210+ offer_created_at,
1211+ peers. clone ( ) ,
1212+ usable_channels. clone ( ) ,
1213+ update_static_invoice_path. clone ( ) ,
1214+ & * entropy,
1215+ & * router,
1216+ ) {
1217+ Ok ( ( msg, ctx) ) => ( msg, ctx) ,
1218+ Err ( ( ) ) => continue ,
1219+ } ;
1220+ serve_static_invoice_messages. push ( ( serve_invoice_msg, reply_path_ctx, offer_id) ) ;
1221+ }
1222+ }
1223+
1224+ // Enqueue the new serve_static_invoice messages in a separate loop to avoid holding the offer
1225+ // cache lock and the pending_async_payments_messages lock at the same time.
1226+ for ( serve_invoice_msg, reply_path_ctx, offer_id) in serve_static_invoice_messages {
1227+ let context = MessageContext :: AsyncPayments ( reply_path_ctx) ;
1228+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , context) {
1229+ Ok ( paths) => paths,
1230+ Err ( ( ) ) => continue ,
1231+ } ;
1232+
1233+ {
1234+ // We can't fail past this point, so indicate to the cache that we've requested an invoice
1235+ // update.
1236+ let mut cache = self . async_receive_offer_cache . lock ( ) . unwrap ( ) ;
1237+ if cache. increment_invoice_update_attempts ( offer_id) . is_err ( ) {
1238+ continue ;
1239+ }
1240+ }
1241+
1242+ let message = AsyncPaymentsMessage :: ServeStaticInvoice ( serve_invoice_msg) ;
1243+ enqueue_onion_message_with_reply_paths (
1244+ message,
1245+ & self . paths_to_static_invoice_server ,
1246+ reply_paths,
1247+ & mut self . pending_async_payments_messages . lock ( ) . unwrap ( ) ,
1248+ ) ;
1249+ }
1250+ }
1251+
11811252 /// Handles an incoming [`OfferPaths`] message from the static invoice server, sending out
11821253 /// [`ServeStaticInvoice`] onion messages in response if we want to use the paths we've received
11831254 /// to build and cache an async receive offer.
0 commit comments