1515//! [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
1616//! [BOLT 12]: https://github.com/lightning/bolts/blob/master/12-offer-encoding.md
1717use std:: sync:: Arc ;
18+ use std:: time:: Duration ;
1819use std:: vec:: IntoIter ;
1920
2021use bip21:: de:: ParamKind ;
@@ -29,6 +30,7 @@ use lightning::onion_message::dns_resolution::HumanReadableName;
2930use lightning:: routing:: router:: RouteParametersConfig ;
3031use lightning_invoice:: { Bolt11Invoice , Bolt11InvoiceDescription , Description } ;
3132
33+ use crate :: config:: HRN_RESOLUTION_TIMEOUT_SECS ;
3234use crate :: error:: Error ;
3335use crate :: ffi:: maybe_wrap;
3436use crate :: logger:: { log_error, LdkLogger , Logger } ;
@@ -159,17 +161,24 @@ impl UnifiedPayment {
159161 & self , uri_str : & str , amount_msat : Option < u64 > ,
160162 route_parameters : Option < RouteParametersConfig > ,
161163 ) -> Result < UnifiedPaymentResult , Error > {
162- let instructions = PaymentInstructions :: parse (
164+ let parse_fut = PaymentInstructions :: parse (
163165 uri_str,
164166 self . config . network ,
165167 self . hrn_resolver . as_ref ( ) ,
166168 false ,
167- )
168- . await
169- . map_err ( |e| {
170- log_error ! ( self . logger, "Failed to parse payment instructions: {:?}" , e) ;
171- Error :: UriParameterParsingFailed
172- } ) ?;
169+ ) ;
170+
171+ let instructions =
172+ tokio:: time:: timeout ( Duration :: from_secs ( HRN_RESOLUTION_TIMEOUT_SECS ) , parse_fut)
173+ . await
174+ . map_err ( |e| {
175+ log_error ! ( self . logger, "Payment instructions resolution timed out: {:?}" , e) ;
176+ Error :: UriParameterParsingFailed
177+ } ) ?
178+ . map_err ( |e| {
179+ log_error ! ( self . logger, "Failed to parse payment instructions: {:?}" , e) ;
180+ Error :: UriParameterParsingFailed
181+ } ) ?;
173182
174183 let resolved = match instructions {
175184 PaymentInstructions :: ConfigurableAmount ( instr) => {
@@ -183,10 +192,22 @@ impl UnifiedPayment {
183192 Error :: InvalidAmount
184193 } ) ?;
185194
186- instr. set_amount ( amt, self . hrn_resolver . as_ref ( ) ) . await . map_err ( |e| {
187- log_error ! ( self . logger, "Failed to set amount: {:?}" , e) ;
188- Error :: InvalidAmount
189- } ) ?
195+ let fut = instr. set_amount ( amt, self . hrn_resolver . as_ref ( ) ) ;
196+
197+ tokio:: time:: timeout ( Duration :: from_secs ( HRN_RESOLUTION_TIMEOUT_SECS ) , fut)
198+ . await
199+ . map_err ( |e| {
200+ log_error ! (
201+ self . logger,
202+ "Payment instructions resolution timed out: {:?}" ,
203+ e
204+ ) ;
205+ Error :: UriParameterParsingFailed
206+ } ) ?
207+ . map_err ( |e| {
208+ log_error ! ( self . logger, "Failed to set amount: {:?}" , e) ;
209+ Error :: InvalidAmount
210+ } ) ?
190211 } ,
191212 PaymentInstructions :: FixedAmount ( instr) => {
192213 if let Some ( user_amount) = amount_msat {
0 commit comments