diff --git a/DashSync/shared/Models/Identity/DSIdentity+Username.m b/DashSync/shared/Models/Identity/DSIdentity+Username.m index f1f6e3e9..41c39b41 100644 --- a/DashSync/shared/Models/Identity/DSIdentity+Username.m +++ b/DashSync/shared/Models/Identity/DSIdentity+Username.m @@ -482,26 +482,29 @@ - (void)registerUsernamesAtStage:(DUsernameStatus *)status completion:(void (^_Nullable)(BOOL success, NSArray *errors))completion onCompletionQueue:(dispatch_queue_t)completionQueue { NSMutableString *debugInfo = [NSMutableString stringWithFormat:@"%@ Register Usernames At Stage [%hhu]", self.logPrefix, DUsernameStatusIndex(status)]; - - Result_ok_bool_err_dash_spv_platform_error_Error *result = dash_spv_platform_PlatformSDK_register_usernames_at_stage(self.chain.sharedRuntime, self.chain.sharedPlatformObj, self.model, status, ((__bridge void *)(context))); + DSLog(@"%@", debugInfo); + Result_ok_bool_err_dash_spv_platform_error_Error *result = dash_spv_platform_PlatformSDK_register_usernames_at_stage(self.chain.sharedRuntime, self.chain.sharedPlatformObj, self.model, status, ((__bridge void *)(self))); if (result->error) { + NSError *err = [NSError ffi_from_platform_error:result->error]; + DSLog(@"%@: Error: %@", debugInfo, err); switch (result->error->tag) { case dash_spv_platform_error_Error_UsernameRegistrationError: { DUsernameStatus *next_status = dash_spv_platform_document_usernames_UsernameStatus_next_status(status); BOOL proceedToNext = result->error->username_registration_error->tag != dash_spv_platform_identity_username_registration_error_UsernameRegistrationError_NotSupported && next_status != nil; Result_ok_bool_err_dash_spv_platform_error_Error_destroy(result); + DSLog(@"%@: UsernameRegistrationError: next? %u", debugInfo, DUsernameStatusIndex(status), proceedToNext); if (proceedToNext) { [self registerUsernamesAtStage:next_status inContext:context completion:completion onCompletionQueue:completionQueue]; } else { - if (completion) dispatch_async(completionQueue, ^{ completion(NO, nil); }); + if (completion) dispatch_async(completionQueue, ^{ completion(NO, @[err]); }); } break; } default: { Result_ok_bool_err_dash_spv_platform_error_Error_destroy(result); - if (completion) dispatch_async(completionQueue, ^{ completion(NO, nil); }); + if (completion) dispatch_async(completionQueue, ^{ completion(NO, @[err]); }); break; } } @@ -509,6 +512,7 @@ - (void)registerUsernamesAtStage:(DUsernameStatus *)status } DUsernameStatus *next_status = dash_spv_platform_document_usernames_UsernameStatus_next_status(status); BOOL ok = result->ok[0]; + DSLog(@"%@: Ok(%u) next? %@", debugInfo, ok, next_status ? [NSString stringWithFormat:@"%u", DUsernameStatusIndex(next_status)] : @"None"); Result_ok_bool_err_dash_spv_platform_error_Error_destroy(result); if (next_status) { [self registerUsernamesAtStage:next_status inContext:context completion:completion onCompletionQueue:completionQueue]; diff --git a/DashSync/shared/Models/Identity/DSIdentity.h b/DashSync/shared/Models/Identity/DSIdentity.h index 17c4664a..45d95838 100644 --- a/DashSync/shared/Models/Identity/DSIdentity.h +++ b/DashSync/shared/Models/Identity/DSIdentity.h @@ -141,6 +141,8 @@ NSString * DSIdentityQueryStepsDescription(DSIdentityQueryStep step); @property (nonatomic, readonly) NSString *localizedRegistrationStatusString; /*! @brief This is a convenience method that checks to see if registrationStatus is confirmed */ @property (nonatomic, readonly, getter=isRegistered) BOOL registered; +/*! @brief This is a convenience method that checks to see if registrationStatus is unknown */ +@property (nonatomic, readonly, getter=isUnknown) BOOL unknown; /*! @brief DashpaySyncronizationBlock represents the last L1 block height for which Dashpay would be synchronized, if this isn't at the end of the chain then we need to query L2 to make sure we don't need to update our bloom filter */ @property (nonatomic, readonly) uint32_t dashpaySyncronizationBlockHeight; /*! @brief DashpaySyncronizationBlock represents the last L1 block hash for which Dashpay would be synchronized */ diff --git a/DashSync/shared/Models/Identity/DSIdentity.m b/DashSync/shared/Models/Identity/DSIdentity.m index 169dbbb5..02959108 100644 --- a/DashSync/shared/Models/Identity/DSIdentity.m +++ b/DashSync/shared/Models/Identity/DSIdentity.m @@ -276,7 +276,7 @@ void save_username_caller(const void *context, DSaveUsernameContext* save_userna return; } NSManagedObjectContext *platformContext = identity.platformContext; - __block NSDictionary *maybeUserInfo = NULL; + [platformContext performBlockAndWait:^{ switch (save_username_context->tag) { case dash_spv_platform_identity_storage_username_SaveUsernameContext_NewUsername: { @@ -1612,6 +1612,10 @@ - (BOOL)isRegistered { return dash_spv_platform_identity_model_IdentityModel_is_registered(self.model); } +- (BOOL)isUnknown { + return DIdentityRegistrationStatusIndex(self.model) == dash_spv_platform_identity_registration_status_IdentityRegistrationStatus_Unknown; +} + - (NSString *)localizedRegistrationStatusString { char *status_string = dash_spv_platform_identity_registration_status_IdentityRegistrationStatus_string(self.registrationStatus); NSString *status = NSStringFromPtr(status_string); @@ -2688,7 +2692,7 @@ - (BOOL)isDefault { - (NSString *)debugDescription { - return [[super debugDescription] stringByAppendingString:[NSString stringWithFormat:@" {%@-%@}", self.currentDashpayUsername, self.uniqueIdString]]; + return [[super debugDescription] stringByAppendingString:[NSString stringWithFormat:@" {%@-%@-%u}", self.currentDashpayUsername, self.uniqueIdString, DIdentityRegistrationStatusIndex(self.model)]]; } - (NSString *)logPrefix { diff --git a/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.h b/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.h index 45be2c1e..c903ec59 100644 --- a/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.h +++ b/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.h @@ -62,15 +62,15 @@ typedef void (^DashpayUserInfoCompletionBlock)(BOOL success, DSTransientDashpayU inDomain:(NSString *)domain withCompletion:(IdentityCompletionBlock)completion; -//- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix -// queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo -// withCompletion:(IdentitiesCompletionBlock)completion; -// -//- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix -// startAfter:(NSData* _Nullable)startAfter -// limit:(uint32_t)limit -// queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo -// withCompletion:(IdentitiesCompletionBlock)completion; +- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix + queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo + withCompletion:(IdentitiesCompletionBlock)completion; + +- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix + startAfter:(NSData* _Nullable)startAfter + limit:(uint32_t)limit + queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo + withCompletion:(IdentitiesCompletionBlock)completion; - (void)searchIdentitiesByNamePrefix:(NSString *)namePrefix startAfter:(NSData* _Nullable)startAfter diff --git a/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.m b/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.m index 5602038e..4cdecb69 100644 --- a/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.m +++ b/DashSync/shared/Models/Managers/Chain Managers/DSIdentitiesManager.m @@ -300,38 +300,48 @@ - (void)searchIdentityByName:(NSString *)name withCompletion:(IdentityCompletionBlock)completion { NSMutableString *debugString = [NSMutableString stringWithFormat:@"%@ Search Identity by name: %@, domain: %@", self.logPrefix, name, domain]; DSLog(@"%@", debugString); - DMaybeDocumentsMap *result = dash_spv_platform_document_manager_DocumentsManager_dpns_documents_for_username(self.chain.sharedRuntime, self.chain.sharedDocumentsObj, DChar(name)); - if (result->error) { - NSError *error = [NSError ffi_from_platform_error:result->error]; - DMaybeDocumentsMapDtor(result); - DSLog(@"%@: ERROR: %@", debugString, error); - if (completion) dispatch_async(dispatch_get_main_queue(), ^{ completion(NO, nil, error); }); - return; - } - - // TODO: in wallet we have unusuable but cancelable request, so... - __block NSMutableArray *rIdentities = [NSMutableArray array]; - DDocumentsMap *documents = result->ok; - for (int i = 0; i < documents->count; i++) { - DDocument *document = documents->values[i]; - DSLog(@"%@: document[%i]: ", debugString, i); - dash_spv_platform_document_print_document(document); - - if (!document) continue; - NSString *normalizedLabel = DGetTextDocProperty(document, @"normalizedLabel"); - NSString *domain = DGetTextDocProperty(document, @"normalizedParentDomainName"); - DIdentifier *owner_id = document->v0->owner_id; + __weak typeof(self) weakSelf = self; + dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0); + //NSLog(@"Queue address: %p", queue); + dispatch_async(queue, ^{ + + __strong typeof(weakSelf) strongSelf = weakSelf; + if (!strongSelf) { + return; + } + DMaybeDocumentsMap *result = dash_spv_platform_document_manager_DocumentsManager_dpns_documents_for_username(strongSelf.chain.sharedRuntime, strongSelf.chain.sharedDocumentsObj, DChar(name)); + if (result->error) { + NSError *error = [NSError ffi_from_platform_error:result->error]; + DMaybeDocumentsMapDtor(result); + DSLog(@"%@: ERROR: %@", debugString, error); + if (completion) dispatch_async(dispatch_get_main_queue(), ^{ completion(NO, nil, error); }); + return; + } - DSIdentity *identity = [[DSIdentity alloc] initWithUniqueId:u256_cast(owner_id->_0->_0) isTransient:TRUE onChain:self.chain]; - [identity addConfirmedUsername:normalizedLabel inDomain:domain]; - [rIdentities addObject:identity]; + // TODO: in wallet we have unusuable but cancelable request, so... + __block NSMutableArray *rIdentities = [NSMutableArray array]; + DDocumentsMap *documents = result->ok; + for (int i = 0; i < documents->count; i++) { + DDocument *document = documents->values[i]; + DSLog(@"%@: document[%i]: ", debugString, i); + dash_spv_platform_document_print_document(document); + + if (!document) continue; + NSString *normalizedLabel = DGetTextDocProperty(document, @"normalizedLabel"); + NSString *domain = DGetTextDocProperty(document, @"normalizedParentDomainName"); + DIdentifier *owner_id = document->v0->owner_id; + + DSIdentity *identity = [[DSIdentity alloc] initWithUniqueId:u256_cast(owner_id->_0->_0) isTransient:TRUE onChain:strongSelf.chain]; + [identity addConfirmedUsername:normalizedLabel inDomain:domain]; + [rIdentities addObject:identity]; - } - DSLog(@"%@: OK: %@", debugString, [rIdentities firstObject]); - if (completion) - dispatch_async(dispatch_get_main_queue(), ^{ - completion(YES, [rIdentities firstObject], nil); - }); + } + DSLog(@"%@: OK: %@", debugString, [rIdentities firstObject]); + if (completion) + dispatch_async(dispatch_get_main_queue(), ^{ + completion(YES, [rIdentities firstObject], nil); + }); + }); } //- (void)fetchProfileForIdentity:(DSIdentity *)identity @@ -407,32 +417,33 @@ - (void)searchIdentityByName:(NSString *)name // if (completion) dispatch_async(completionQueue, ^{ completion(YES, dashpayUserDictionary, nil); }); //} -//- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix -// queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo -// withCompletion:(IdentitiesCompletionBlock)completion { -// [self searchIdentitiesByDashpayUsernamePrefix:namePrefix -// startAfter:nil -// limit:100 -// queryDashpayProfileInfo:queryDashpayProfileInfo -// withCompletion:completion]; -//} -// -//- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix -// startAfter:(NSData* _Nullable)startAfter -// limit:(uint32_t)limit -// queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo -// withCompletion:(IdentitiesCompletionBlock)completion { -// [self searchIdentitiesByNamePrefix:namePrefix -// startAfter:startAfter -// limit:limit -// withCompletion:^(BOOL success, NSArray *_Nullable identities, NSArray *_Nonnull errors) { -// if (errors.count) { -// if (completion) dispatch_async(dispatch_get_main_queue(), ^{ completion(success, identities, errors); }); -// } else if (queryDashpayProfileInfo && identities.count) { -// __block NSMutableDictionary *identityDictionary = [NSMutableDictionary dictionary]; -// for (DSIdentity *identity in identities) { -// [identityDictionary setObject:identity forKey:identity.uniqueIDData]; -// } +- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix + queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo + withCompletion:(IdentitiesCompletionBlock)completion { + [self searchIdentitiesByDashpayUsernamePrefix:namePrefix + startAfter:nil + limit:100 + queryDashpayProfileInfo:queryDashpayProfileInfo + withCompletion:completion]; +} + +- (void)searchIdentitiesByDashpayUsernamePrefix:(NSString *)namePrefix + startAfter:(NSData* _Nullable)startAfter + limit:(uint32_t)limit + queryDashpayProfileInfo:(BOOL)queryDashpayProfileInfo + withCompletion:(IdentitiesCompletionBlock)completion { + [self searchIdentitiesByNamePrefix:namePrefix + startAfter:startAfter + limit:limit + withCompletion:^(BOOL success, NSArray *_Nullable identities, NSArray *_Nonnull errors) { + if (errors.count) { + if (completion) dispatch_async(dispatch_get_main_queue(), ^{ completion(success, identities, errors); }); + } else if (queryDashpayProfileInfo && identities.count) { + __block NSMutableDictionary *identityDictionary = [NSMutableDictionary dictionary]; + for (DSIdentity *identity in identities) { + [identityDictionary setObject:identity forKey:identity.uniqueIDData]; + } + completion(success, identityDictionary.allValues, errors); // [self fetchProfilesForIdentities:identityDictionary.allKeys // withCompletion:^(BOOL success, NSDictionary *_Nullable dashpayUserInfosByIdentityUniqueId, NSError *_Nullable error) { // for (NSData *identityUniqueIdData in dashpayUserInfosByIdentityUniqueId) { @@ -442,11 +453,11 @@ - (void)searchIdentityByName:(NSString *)name // if (completion) dispatch_async(dispatch_get_main_queue(), ^{ completion(success, identities, errors); }); // } // onCompletionQueue:self.identityQueue]; -// } else if (completion) { -// dispatch_async(dispatch_get_main_queue(), ^{ completion(success, identities, errors); }); -// } -// }]; -//} + } else if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ completion(success, identities, errors); }); + } + }]; +} - (void)searchIdentitiesByNamePrefix:(NSString *)namePrefix startAfter:(NSData* _Nullable)startAfter diff --git a/DashSync/shared/Models/Persistence/DSDataController.m b/DashSync/shared/Models/Persistence/DSDataController.m index 4433cd12..00e81f01 100644 --- a/DashSync/shared/Models/Persistence/DSDataController.m +++ b/DashSync/shared/Models/Persistence/DSDataController.m @@ -160,6 +160,7 @@ - (NSManagedObjectContext *)platformContext { dispatch_once(&oncePlatformToken, ^{ _platformContext = [self.persistentContainer newBackgroundContext]; [_platformContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; + [_platformContext setAutomaticallyMergesChangesFromParent:YES]; }); return _platformContext; }