@@ -1080,13 +1080,14 @@ where
1080
1080
core:: mem:: take ( & mut self . pending_dns_onion_messages . lock ( ) . unwrap ( ) )
1081
1081
}
1082
1082
1083
- /// Sends out [`OfferPathsRequest`] onion messages if we are an often-offline recipient and are
1084
- /// configured to interactively build offers and static invoices with a static invoice server.
1083
+ /// Sends out [`OfferPathsRequest`] and [`ServeStaticInvoice`] onion messages if we are an
1084
+ /// often-offline recipient and are configured to interactively build offers and static invoices
1085
+ /// with a static invoice server.
1085
1086
///
1086
1087
/// Errors if we failed to create blinded reply paths when sending an [`OfferPathsRequest`] message.
1087
1088
#[ cfg( async_payments) ]
1088
1089
pub ( crate ) fn check_refresh_async_receive_offers (
1089
- & self , peers : Vec < MessageForwardNode > ,
1090
+ & self , peers : Vec < MessageForwardNode > , usable_channels : Vec < ChannelDetails > ,
1090
1091
) -> Result < ( ) , ( ) > {
1091
1092
// Terminate early if this node does not intend to receive async payments.
1092
1093
if self . paths_to_static_invoice_server . is_empty ( ) {
@@ -1113,7 +1114,7 @@ where
1113
1114
path_absolute_expiry : duration_since_epoch
1114
1115
. saturating_add ( REPLY_PATH_RELATIVE_EXPIRY ) ,
1115
1116
} ) ;
1116
- let reply_paths = match self . create_blinded_paths ( peers, context) {
1117
+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , context) {
1117
1118
Ok ( paths) => paths,
1118
1119
Err ( ( ) ) => {
1119
1120
return Err ( ( ) ) ;
@@ -1133,6 +1134,60 @@ where
1133
1134
) ;
1134
1135
}
1135
1136
1137
+ // If a static invoice server has persisted an offer for us but the corresponding invoice is
1138
+ // expiring soon, we need to refresh that invoice. Here we create the onion messages that will
1139
+ // be used to request invoice refresh, based on the offers provided by the cache.
1140
+ let mut serve_static_invoice_messages = Vec :: new ( ) ;
1141
+ {
1142
+ let cache = self . async_receive_offer_cache . lock ( ) . unwrap ( ) ;
1143
+ for offer_and_metadata in cache. offers_needing_invoice_refresh ( duration_since_epoch) {
1144
+ let ( offer, offer_nonce, offer_created_at, update_static_invoice_path) =
1145
+ offer_and_metadata;
1146
+ let offer_id = offer. id ( ) ;
1147
+
1148
+ let ( serve_invoice_msg, reply_path_ctx) = match self
1149
+ . create_serve_static_invoice_message (
1150
+ offer. clone ( ) ,
1151
+ offer_nonce,
1152
+ offer_created_at,
1153
+ peers. clone ( ) ,
1154
+ usable_channels. clone ( ) ,
1155
+ update_static_invoice_path. clone ( ) ,
1156
+ ) {
1157
+ Ok ( ( msg, ctx) ) => ( msg, ctx) ,
1158
+ Err ( ( ) ) => continue ,
1159
+ } ;
1160
+ serve_static_invoice_messages. push ( ( serve_invoice_msg, reply_path_ctx, offer_id) ) ;
1161
+ }
1162
+ }
1163
+
1164
+ // Enqueue the new serve_static_invoice messages in a separate loop to avoid holding the offer
1165
+ // cache lock and the pending_async_payments_messages lock at the same time.
1166
+ for ( serve_invoice_msg, reply_path_ctx, offer_id) in serve_static_invoice_messages {
1167
+ let context = MessageContext :: AsyncPayments ( reply_path_ctx) ;
1168
+ let reply_paths = match self . create_blinded_paths ( peers. clone ( ) , context) {
1169
+ Ok ( paths) => paths,
1170
+ Err ( ( ) ) => continue ,
1171
+ } ;
1172
+
1173
+ {
1174
+ // We can't fail past this point, so indicate to the cache that we've requested an invoice
1175
+ // update.
1176
+ let mut cache = self . async_receive_offer_cache . lock ( ) . unwrap ( ) ;
1177
+ if cache. increment_invoice_update_attempts ( offer_id) . is_err ( ) {
1178
+ continue ;
1179
+ }
1180
+ }
1181
+
1182
+ let message = AsyncPaymentsMessage :: ServeStaticInvoice ( serve_invoice_msg) ;
1183
+ enqueue_onion_message_with_reply_paths (
1184
+ message,
1185
+ & self . paths_to_static_invoice_server ,
1186
+ reply_paths,
1187
+ & mut self . pending_async_payments_messages . lock ( ) . unwrap ( ) ,
1188
+ ) ;
1189
+ }
1190
+
1136
1191
Ok ( ( ) )
1137
1192
}
1138
1193
0 commit comments