@@ -344,6 +344,30 @@ impl OMNameResolver {
344344 } ) ;
345345 }
346346
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+
347371 /// Begins the process of resolving a BIP 353 Human Readable Name.
348372 ///
349373 /// Returns a [`DNSSECQuery`] onion message and a [`DNSResolverContext`] which should be sent
@@ -483,7 +507,7 @@ impl OMNameResolver {
483507
484508#[ cfg( test) ]
485509mod tests {
486- use super :: HumanReadableName ;
510+ use super :: * ;
487511
488512 #[ test]
489513 fn test_hrn_display_format ( ) {
@@ -500,4 +524,43 @@ mod tests {
500524 "HumanReadableName display format mismatch"
501525 ) ;
502526 }
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+ }
503566}
0 commit comments