@@ -1134,8 +1134,9 @@ where
1134
1134
core:: mem:: take ( & mut self . pending_dns_onion_messages . lock ( ) . unwrap ( ) )
1135
1135
}
1136
1136
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.
1139
1140
///
1140
1141
/// # Usage
1141
1142
///
@@ -1145,9 +1146,14 @@ where
1145
1146
///
1146
1147
/// Errors if we failed to create blinded reply paths when sending an [`OfferPathsRequest`] message.
1147
1148
#[ 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
+ {
1151
1157
// Terminate early if this node does not intend to receive async payments.
1152
1158
if self . paths_to_static_invoice_server . lock ( ) . unwrap ( ) . is_empty ( ) {
1153
1159
return Ok ( ( ) ) ;
@@ -1169,7 +1175,7 @@ where
1169
1175
path_absolute_expiry : duration_since_epoch
1170
1176
. saturating_add ( TEMP_REPLY_PATH_RELATIVE_EXPIRY ) ,
1171
1177
} ) ;
1172
- let reply_paths = match self . create_blinded_paths ( peers, context) {
1178
+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , context) {
1173
1179
Ok ( paths) => paths,
1174
1180
Err ( ( ) ) => {
1175
1181
return Err ( ( ) ) ;
@@ -1190,9 +1196,88 @@ where
1190
1196
) ;
1191
1197
}
1192
1198
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
+
1193
1209
Ok ( ( ) )
1194
1210
}
1195
1211
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
+
1196
1281
/// Handles an incoming [`OfferPaths`] message from the static invoice server, sending out
1197
1282
/// [`ServeStaticInvoice`] onion messages in response if we've built a new async receive offer and
1198
1283
/// need the corresponding [`StaticInvoice`] to be persisted by the static invoice server.
0 commit comments