@@ -344,6 +344,30 @@ impl OMNameResolver {
344
344
} ) ;
345
345
}
346
346
347
+ /// Removes any pending resolutions for the given `name` and `payment_id`.
348
+ ///
349
+ /// Any future calls to [`Self::handle_dnssec_proof_for_offer`] or
350
+ /// [`Self::handle_dnssec_proof_for_uri`] will no longer return a result for the given
351
+ /// resolution.
352
+ pub fn expire_pending_resolution ( & self , name : & HumanReadableName , payment_id : PaymentId ) {
353
+ let dns_name =
354
+ Name :: try_from ( format ! ( "{}.user._bitcoin-payment.{}." , name. user( ) , name. domain( ) ) ) ;
355
+ debug_assert ! (
356
+ dns_name. is_ok( ) ,
357
+ "The HumanReadableName constructor shouldn't allow names which are too long"
358
+ ) ;
359
+ if let Ok ( name) = dns_name {
360
+ let mut pending_resolves = self . pending_resolves . lock ( ) . unwrap ( ) ;
361
+ if let hash_map:: Entry :: Occupied ( mut entry) = pending_resolves. entry ( name) {
362
+ let resolutions = entry. get_mut ( ) ;
363
+ resolutions. retain ( |resolution| resolution. payment_id != payment_id) ;
364
+ if resolutions. is_empty ( ) {
365
+ entry. remove ( ) ;
366
+ }
367
+ }
368
+ }
369
+ }
370
+
347
371
/// Begins the process of resolving a BIP 353 Human Readable Name.
348
372
///
349
373
/// Returns a [`DNSSECQuery`] onion message and a [`DNSResolverContext`] which should be sent
@@ -483,7 +507,7 @@ impl OMNameResolver {
483
507
484
508
#[ cfg( test) ]
485
509
mod tests {
486
- use super :: HumanReadableName ;
510
+ use super :: * ;
487
511
488
512
#[ test]
489
513
fn test_hrn_display_format ( ) {
@@ -500,4 +524,43 @@ mod tests {
500
524
"HumanReadableName display format mismatch"
501
525
) ;
502
526
}
527
+
528
+ #[ test]
529
+ #[ cfg( feature = "dnssec" ) ]
530
+ fn test_expiry ( ) {
531
+ let keys = crate :: sign:: KeysManager :: new ( & [ 33 ; 32 ] , 0 , 0 ) ;
532
+ let resolver = OMNameResolver :: new ( 42 , 42 ) ;
533
+ let name = HumanReadableName :: new ( "user" , "example.com" ) . unwrap ( ) ;
534
+
535
+ // Queue up a resolution
536
+ resolver. resolve_name ( PaymentId ( [ 0 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
537
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
538
+ // and check that it expires after two blocks
539
+ resolver. new_best_block ( 44 , 42 ) ;
540
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 0 ) ;
541
+
542
+ // Queue up another resolution
543
+ resolver. resolve_name ( PaymentId ( [ 1 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
544
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
545
+ // it won't expire after one block
546
+ resolver. new_best_block ( 45 , 42 ) ;
547
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
548
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 1 ) ;
549
+ // and queue up a second and third resolution of the same name
550
+ resolver. resolve_name ( PaymentId ( [ 2 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
551
+ resolver. resolve_name ( PaymentId ( [ 3 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
552
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
553
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 3 ) ;
554
+ // after another block the first will expire, but the second and third won't
555
+ resolver. new_best_block ( 46 , 42 ) ;
556
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
557
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 2 ) ;
558
+ // Check manual expiry
559
+ resolver. expire_pending_resolution ( & name, PaymentId ( [ 3 ; 32 ] ) ) ;
560
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
561
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 1 ) ;
562
+ // after one more block all the requests will have expired
563
+ resolver. new_best_block ( 47 , 42 ) ;
564
+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 0 ) ;
565
+ }
503
566
}
0 commit comments