@@ -298,26 +298,23 @@ impl PrivateTowerServices for Arc<InternalAPI> {
298298 )
299299 } ) ?;
300300
301- let appointments : Vec < Appointment > = self
301+ let mut matching_appointments : Vec < common_msgs :: AppointmentData > = self
302302 . watcher
303303 . get_watcher_appointments_with_locator ( locator, user_id)
304304 . into_values ( )
305- . map ( |appointment| appointment. inner )
306- . collect ( ) ;
307-
308- let mut matching_appointments: Vec < common_msgs:: AppointmentData > = appointments
309- . into_iter ( )
310305 . map ( |appointment| common_msgs:: AppointmentData {
311306 appointment_data : Some (
312- common_msgs:: appointment_data:: AppointmentData :: Appointment ( appointment. into ( ) ) ,
307+ common_msgs:: appointment_data:: AppointmentData :: Appointment (
308+ appointment. inner . into ( ) ,
309+ ) ,
313310 ) ,
314311 } )
315312 . collect ( ) ;
316313
317- for ( _ , tracker) in self
314+ for tracker in self
318315 . watcher
319316 . get_responder_trackers_with_locator ( locator, user_id)
320- . into_iter ( )
317+ . into_values ( )
321318 {
322319 matching_appointments. push ( common_msgs:: AppointmentData {
323320 appointment_data : Some ( common_msgs:: appointment_data:: AppointmentData :: Tracker (
@@ -445,6 +442,8 @@ mod tests_private_api {
445442 use bitcoin:: hashes:: Hash ;
446443 use bitcoin:: Txid ;
447444
445+ use rand:: { self , thread_rng, Rng } ;
446+
448447 use crate :: responder:: { ConfirmationStatus , TransactionTracker } ;
449448 use crate :: test_utils:: {
450449 create_api, generate_dummy_appointment, generate_dummy_appointment_with_user,
@@ -453,7 +452,7 @@ mod tests_private_api {
453452 use crate :: watcher:: Breach ;
454453
455454 use teos_common:: cryptography:: { self , get_random_keypair} ;
456- use teos_common:: test_utils:: get_random_user_id;
455+ use teos_common:: test_utils:: { get_random_locator , get_random_user_id} ;
457456
458457 #[ tokio:: test]
459458 async fn test_get_all_appointments ( ) {
@@ -531,18 +530,33 @@ mod tests_private_api {
531530 . into_inner ( ) ;
532531
533532 assert ! ( matches!( response, msgs:: GetAppointmentsResponse { .. } ) ) ;
533+
534+ let user_id = get_random_user_id ( ) . to_vec ( ) ;
535+ let locator = get_random_locator ( ) . to_vec ( ) ;
536+ let response = internal_api
537+ . get_appointments ( Request :: new ( msgs:: GetAppointmentsRequest {
538+ locator,
539+ user_id : Some ( user_id) ,
540+ } ) )
541+ . await
542+ . unwrap ( )
543+ . into_inner ( ) ;
544+
545+ assert ! ( matches!( response, msgs:: GetAppointmentsResponse { .. } ) ) ;
534546 }
535547
536548 #[ tokio:: test]
537- async fn test_get_appointments_watcher ( ) {
549+ async fn test_get_appointments_watcher_without_userid ( ) {
538550 let ( internal_api, _s) = create_api ( ) . await ;
539551
540552 for i in 0 ..3 {
541553 // Create a dispute tx to be used for creating different dummy appointments with the same locator.
542554 let dispute_txid = get_random_tx ( ) . txid ( ) ;
555+ let locator = Locator :: new ( dispute_txid) ;
543556
544557 // The number of different appointments to create for this dispute tx.
545- let appointments_to_create = 4 * i + 7 ;
558+ let random_number = 4 * i + 7 ;
559+ let appointments_to_create = random_number;
546560
547561 // Add that many appointments to the watcher.
548562 for _ in 0 ..appointments_to_create {
@@ -556,8 +570,6 @@ mod tests_private_api {
556570 . unwrap ( ) ;
557571 }
558572
559- let locator = Locator :: new ( dispute_txid) ;
560-
561573 // Query for the current locator and assert it retrieves correct appointments.
562574 let response = internal_api
563575 . get_appointments ( Request :: new ( msgs:: GetAppointmentsRequest {
@@ -584,6 +596,102 @@ mod tests_private_api {
584596 }
585597 }
586598
599+ #[ tokio:: test]
600+ async fn test_get_appointments_watcher_with_userid ( ) {
601+ let ( internal_api, _s) = create_api ( ) . await ;
602+
603+ for i in 0 ..3 {
604+
605+ // Create a dispute tx to be used for creating different dummy appointments with the same locator.
606+ let dispute_txid = get_random_tx ( ) . txid ( ) ;
607+ let locator = Locator :: new ( dispute_txid) ;
608+
609+ // The number of different appointments to create for this dispute tx.
610+ let random_number = 4 * i + 7 ;
611+ let appointments_to_create = random_number;
612+
613+ let mut random_users_list = Vec :: new ( ) ;
614+
615+ // Add that many appointments to the watcher.
616+ for _ in 0 ..appointments_to_create {
617+ let ( user_sk, user_pk) = get_random_keypair ( ) ;
618+ let user_id = UserId ( user_pk) ;
619+ internal_api. watcher . register ( user_id) . unwrap ( ) ;
620+ random_users_list. push ( user_id) ;
621+ let appointment = generate_dummy_appointment ( Some ( & dispute_txid) ) . inner ;
622+ let signature = cryptography:: sign ( & appointment. to_vec ( ) , & user_sk) . unwrap ( ) ;
623+ internal_api
624+ . watcher
625+ . add_appointment ( appointment, signature)
626+ . unwrap ( ) ;
627+ }
628+
629+ for user_id in random_users_list. into_iter ( ) {
630+ let response = internal_api
631+ . get_appointments ( Request :: new ( msgs:: GetAppointmentsRequest {
632+ locator : locator. to_vec ( ) ,
633+ user_id : Some ( user_id. to_vec ( ) ) ,
634+ } ) )
635+ . await
636+ . unwrap ( )
637+ . into_inner ( ) ;
638+
639+ // Verify that only a single appointment is returned
640+ assert_eq ! ( response. appointments. len( ) , 1 ) ;
641+
642+ // Verify that the appointment have the current locator
643+ assert ! ( matches!(
644+ response. appointments[ 0 ] . appointment_data,
645+ Some ( common_msgs:: appointment_data:: AppointmentData :: Appointment (
646+ common_msgs:: Appointment {
647+ locator: ref app_loc,
648+ ..
649+ }
650+ ) ) if Locator :: from_slice( app_loc) . unwrap( ) == locator
651+ ) ) ;
652+ }
653+
654+ // Ensure that duplicate appointments are not stored for a user
655+
656+ // Create a specific user
657+ let ( random_user_sk, random_user_pk) = get_random_keypair ( ) ;
658+ let random_user_id = UserId ( random_user_pk) ;
659+ internal_api. watcher . register ( random_user_id) . unwrap ( ) ;
660+
661+ for _ in 0 ..appointments_to_create {
662+ let appointment = generate_dummy_appointment ( Some ( & dispute_txid) ) . inner ;
663+ let signature = cryptography:: sign ( & appointment. to_vec ( ) , & random_user_sk) . unwrap ( ) ;
664+ internal_api
665+ . watcher
666+ . add_appointment ( appointment, signature)
667+ . unwrap ( ) ;
668+ }
669+
670+ let response = internal_api
671+ . get_appointments ( Request :: new ( msgs:: GetAppointmentsRequest {
672+ locator : locator. to_vec ( ) ,
673+ user_id : Some ( random_user_id. to_vec ( ) ) ,
674+ } ) )
675+ . await
676+ . unwrap ( )
677+ . into_inner ( ) ;
678+
679+ // Verify that only a single appointment is returned
680+ assert_eq ! ( response. appointments. len( ) , 1 ) ;
681+
682+ // Verify that the appointment have the current locator
683+ assert ! ( matches!(
684+ response. appointments[ 0 ] . appointment_data,
685+ Some ( common_msgs:: appointment_data:: AppointmentData :: Appointment (
686+ common_msgs:: Appointment {
687+ locator: ref app_loc,
688+ ..
689+ }
690+ ) ) if Locator :: from_slice( app_loc) . unwrap( ) == locator
691+ ) ) ;
692+ }
693+ }
694+
587695 #[ tokio:: test]
588696 async fn test_get_appointments_responder ( ) {
589697 let ( internal_api, _s) = create_api ( ) . await ;
@@ -596,11 +704,19 @@ mod tests_private_api {
596704 // The number of different trackers to create for this dispute tx.
597705 let trackers_to_create = 4 * i + 7 ;
598706
707+ let random_tracker_num = thread_rng ( ) . gen_range ( 0 ..trackers_to_create) ;
708+ let random_user_id = get_random_user_id ( ) ;
709+
599710 // Add that many trackers to the responder.
600- for _ in 0 ..trackers_to_create {
711+ for i in 0 ..trackers_to_create {
712+ let user_id = if i == random_tracker_num {
713+ random_user_id
714+ } else {
715+ get_random_user_id ( )
716+ } ;
601717 let tracker = TransactionTracker :: new (
602718 breach. clone ( ) ,
603- get_random_user_id ( ) ,
719+ user_id ,
604720 ConfirmationStatus :: ConfirmedIn ( 100 ) ,
605721 ) ;
606722 internal_api
@@ -610,7 +726,7 @@ mod tests_private_api {
610726
611727 let locator = Locator :: new ( dispute_tx. txid ( ) ) ;
612728
613- // Query for the current locator and assert it retrieves correct trackers .
729+ // Query for the current locator without the optional user_id .
614730 let response = internal_api
615731 . get_appointments ( Request :: new ( msgs:: GetAppointmentsRequest {
616732 locator : locator. to_vec ( ) ,
@@ -620,7 +736,7 @@ mod tests_private_api {
620736 . unwrap ( )
621737 . into_inner ( ) ;
622738
623- // The response should contain `trackers_to_create` trackers, all with dispute txid that matches with the locator of the current iteration.
739+ // Verify that the response should contain `trackers_to_create` trackers, all with dispute txid that matches with the locator of the current iteration.
624740 assert_eq ! ( response. appointments. len( ) , trackers_to_create) ;
625741 for app_data in response. appointments {
626742 assert ! ( matches!(
@@ -633,6 +749,28 @@ mod tests_private_api {
633749 ) ) if Locator :: new( Txid :: from_slice( dispute_txid) . unwrap( ) ) == locator
634750 ) ) ;
635751 }
752+
753+ // Query for the current locator with the optional user_id present.
754+ let response = internal_api
755+ . get_appointments ( Request :: new ( msgs:: GetAppointmentsRequest {
756+ locator : locator. to_vec ( ) ,
757+ user_id : Some ( random_user_id. to_vec ( ) ) ,
758+ } ) )
759+ . await
760+ . unwrap ( )
761+ . into_inner ( ) ;
762+
763+ // Verify that only a single appointment is returned and the correct locator is found
764+ assert_eq ! ( response. appointments. len( ) , 1 ) ;
765+ assert ! ( matches!(
766+ response. appointments[ 0 ] . appointment_data,
767+ Some ( common_msgs:: appointment_data:: AppointmentData :: Tracker (
768+ common_msgs:: Tracker {
769+ ref dispute_txid,
770+ ..
771+ }
772+ ) ) if Locator :: new( Txid :: from_slice( dispute_txid) . unwrap( ) ) == locator
773+ ) ) ;
636774 }
637775 }
638776
0 commit comments