@@ -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,9 @@ impl OMNameResolver {
483507
484508#[ cfg( test) ]
485509mod tests {
486- use super :: HumanReadableName ;
510+ use super :: * ;
511+
512+ use crate :: sign:: KeysManager ;
487513
488514 #[ test]
489515 fn test_hrn_display_format ( ) {
@@ -500,4 +526,42 @@ mod tests {
500526 "HumanReadableName display format mismatch"
501527 ) ;
502528 }
529+
530+ #[ test]
531+ fn test_expiry ( ) {
532+ let keys = KeysManager :: new ( & [ 33 ; 32 ] , 0 , 0 ) ;
533+ let resolver = OMNameResolver :: new ( 42 , 42 ) ;
534+ let name = HumanReadableName :: new ( "user" , "example.com" ) . unwrap ( ) ;
535+
536+ // Queue up a resolution
537+ resolver. resolve_name ( PaymentId ( [ 0 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
538+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
539+ // and check that it expires after two blocks
540+ resolver. new_best_block ( 44 , 42 ) ;
541+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 0 ) ;
542+
543+ // Queue up another resolution
544+ resolver. resolve_name ( PaymentId ( [ 1 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
545+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
546+ // it won't expire after one block
547+ resolver. new_best_block ( 45 , 42 ) ;
548+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
549+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 1 ) ;
550+ // and queue up a second and third resolution of the same name
551+ resolver. resolve_name ( PaymentId ( [ 2 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
552+ resolver. resolve_name ( PaymentId ( [ 3 ; 32 ] ) , name. clone ( ) , & keys) . unwrap ( ) ;
553+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
554+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 3 ) ;
555+ // after another block the first will expire, but the second and third won't
556+ resolver. new_best_block ( 46 , 42 ) ;
557+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
558+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 2 ) ;
559+ // Check manual expiry
560+ resolver. expire_pending_resolution ( & name, PaymentId ( [ 3 ; 32 ] ) ) ;
561+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 1 ) ;
562+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . iter( ) . next( ) . unwrap( ) . 1 . len( ) , 1 ) ;
563+ // after one more block all the requests will have expired
564+ resolver. new_best_block ( 47 , 42 ) ;
565+ assert_eq ! ( resolver. pending_resolves. lock( ) . unwrap( ) . len( ) , 0 ) ;
566+ }
503567}
0 commit comments