diff --git a/DashSync.podspec b/DashSync.podspec index 24d4e3756..4e7b1273a 100644 --- a/DashSync.podspec +++ b/DashSync.podspec @@ -34,7 +34,7 @@ Pod::Spec.new do |s| s.ios.framework = 'UIKit' s.macos.framework = 'Cocoa' s.compiler_flags = '-Wno-comma' - s.dependency 'DashSharedCore', '0.4.14' + s.dependency 'DashSharedCore', '0.4.15' s.dependency 'CocoaLumberjack', '3.7.2' s.ios.dependency 'DWAlertController', '0.2.1' s.dependency 'DSDynamicOptions', '0.1.2' diff --git a/DashSync/shared/Categories/NSData/NSData+Dash.h b/DashSync/shared/Categories/NSData/NSData+Dash.h index 5edf772ae..bb9e37585 100644 --- a/DashSync/shared/Categories/NSData/NSData+Dash.h +++ b/DashSync/shared/Categories/NSData/NSData+Dash.h @@ -193,6 +193,7 @@ size_t chacha20Poly1305AEADDecrypt(void *_Nullable out, size_t outLen, const voi - (uint32_t)UInt32AtOffset:(NSUInteger)offset; - (uint32_t)UInt32BigToHostAtOffset:(NSUInteger)offset; - (uint64_t)UInt64AtOffset:(NSUInteger)offset; +- (int64_t)Int64AtOffset:(NSUInteger)offset; - (UInt128)UInt128AtOffset:(NSUInteger)offset; - (UInt160)UInt160AtOffset:(NSUInteger)offset; - (UInt256)UInt256AtOffset:(NSUInteger)offset; diff --git a/DashSync/shared/Categories/NSData/NSData+Dash.m b/DashSync/shared/Categories/NSData/NSData+Dash.m index 2093d4eeb..8efea528a 100644 --- a/DashSync/shared/Categories/NSData/NSData+Dash.m +++ b/DashSync/shared/Categories/NSData/NSData+Dash.m @@ -1211,6 +1211,11 @@ - (uint64_t)UInt64AtOffset:(NSUInteger)offset { return CFSwapInt64LittleToHost(*(const uint64_t *)((const uint8_t *)self.bytes + offset)); } +- (int64_t)Int64AtOffset:(NSUInteger)offset { + if (self.length < offset + sizeof(int64_t)) return 0; + return CFSwapInt64LittleToHost(*(const int64_t *)((const uint8_t *)self.bytes + offset)); +} + - (UInt128)UInt128AtOffset:(NSUInteger)offset { if (self.length < offset + sizeof(UInt128)) return UINT128_ZERO; return *(UInt128 *)(self.bytes + offset); diff --git a/DashSync/shared/Models/Chain/DSChain.m b/DashSync/shared/Models/Chain/DSChain.m index cd560f147..85b2f2155 100644 --- a/DashSync/shared/Models/Chain/DSChain.m +++ b/DashSync/shared/Models/Chain/DSChain.m @@ -1239,6 +1239,7 @@ - (DSBloomFilter *)bloomFilterWithFalsePositiveRate:(double)falsePositiveRate wi [allAddresses addObjectsFromArray:[wallet providerOwnerAddresses]]; [allAddresses addObjectsFromArray:[wallet providerVotingAddresses]]; [allAddresses addObjectsFromArray:[wallet providerOperatorAddresses]]; + [allAddresses addObjectsFromArray:[wallet platformNodeAddresses]]; } for (DSFundsDerivationPath *derivationPath in self.standaloneDerivationPaths) { diff --git a/DashSync/shared/Models/Managers/Chain Managers/DSTransactionManager.m b/DashSync/shared/Models/Managers/Chain Managers/DSTransactionManager.m index 866e476e8..dd5271b23 100644 --- a/DashSync/shared/Models/Managers/Chain Managers/DSTransactionManager.m +++ b/DashSync/shared/Models/Managers/Chain Managers/DSTransactionManager.m @@ -1016,6 +1016,7 @@ - (void)updateTransactionsBloomFilter { [allAddressesArray addObjectsFromArray:[wallet providerOwnerAddresses]]; [allAddressesArray addObjectsFromArray:[wallet providerVotingAddresses]]; [allAddressesArray addObjectsFromArray:[wallet providerOperatorAddresses]]; + [allAddressesArray addObjectsFromArray:[wallet platformNodeAddresses]]; } for (DSFundsDerivationPath *derivationPath in self.chain.standaloneDerivationPaths) { @@ -1216,11 +1217,7 @@ - (void)peer:(DSPeer *)peer relayedTransaction:(DSTransaction *)transaction inBl #endif } - if (block) { - transaction.timestamp = block.timestamp; - } else { - transaction.timestamp = [NSDate timeIntervalSince1970]; - } + transaction.timestamp = block ? block.timestamp : [NSDate timeIntervalSince1970]; NSArray *accounts = [self.chain accountsThatCanContainTransaction:transaction]; NSMutableArray *accountsAcceptingTransaction = [NSMutableArray array]; NSMutableArray *accountsWithValidTransaction = [NSMutableArray array]; diff --git a/DashSync/shared/Models/Masternode/DSMasternodeListStore.m b/DashSync/shared/Models/Masternode/DSMasternodeListStore.m index bd56eca67..148bfa85a 100644 --- a/DashSync/shared/Models/Masternode/DSMasternodeListStore.m +++ b/DashSync/shared/Models/Masternode/DSMasternodeListStore.m @@ -424,7 +424,6 @@ - (void)notifyMasternodeListUpdate { - (void)saveMasternodeList:(DSMasternodeList *)masternodeList addedMasternodes:(NSDictionary *)addedMasternodes modifiedMasternodes:(NSDictionary *)modifiedMasternodes completion:(void (^)(NSError *error))completion { UInt256 blockHash = masternodeList.blockHash; NSData *blockHashData = uint256_data(blockHash); - DSLog(@"•••• store (%d) masternode list at: %u: %@", [self hasMasternodeListAt:blockHashData], [self heightForBlockHash:blockHash], uint256_hex(blockHash)); if ([self hasMasternodeListAt:blockHashData]) { // in rare race conditions this might already exist // but also as we can get it from different sources @@ -524,7 +523,7 @@ + (void)saveMasternodeList:(DSMasternodeList *)masternodeList createUnknownBlocks:(BOOL)createUnknownBlocks inContext:(NSManagedObjectContext *)context completion:(void (^)(NSError *error))completion { - DSLog(@"Queued saving MNL at height %u", masternodeList.height); + DSLog(@"Queued saving MNL at height %u: %@", masternodeList.height, uint256_hex(masternodeList.blockHash)); [context performBlockAndWait:^{ //masternodes @autoreleasepool { @@ -607,7 +606,7 @@ + (void)saveMasternodeList:(DSMasternodeList *)masternodeList } } chainEntity.baseBlockHash = mnlBlockHashData; - DSLog(@"Finished merging MNL at height %u", mnlHeight); + DSLog(@"Finished merging MNL at height %u: %@", mnlHeight, mnlBlockHashData.hexString); } else if (!error) { DSMasternodeListEntity *masternodeListEntity = [DSMasternodeListEntity managedObjectInBlockedContext:context]; diff --git a/DashSync/shared/Models/Network/DSPeer.m b/DashSync/shared/Models/Network/DSPeer.m index ebd8ed663..0a6e1d86f 100644 --- a/DashSync/shared/Models/Network/DSPeer.m +++ b/DashSync/shared/Models/Network/DSPeer.m @@ -755,13 +755,14 @@ - (void)acceptMessage:(NSData *)message type:(NSString *)type { DSLog(@"%@:%u accept message %@", self.host, self.port, type); } #endif - if (self.currentBlock && (!([MSG_TX isEqual:type] || [MSG_IX isEqual:type] || [MSG_ISLOCK isEqual:type]))) { // if we receive a non-tx message, merkleblock is done + if (self.currentBlock && (!([MSG_TX isEqual:type] || [MSG_IX isEqual:type] || [MSG_ISLOCK isEqual:type]))) { + // if we receive a non-tx message, merkleblock is done UInt256 hash = self.currentBlock.blockHash; - + NSUInteger txExpected = self.currentBlockTxHashes.count; self.currentBlock = nil; self.currentBlockTxHashes = nil; - [self error:@"incomplete merkleblock %@, expected %u more tx, got %@", - uint256_obj(hash), (int)self.currentBlockTxHashes.count, type]; + [self error:@"incomplete merkleblock %@, expected %lu more tx, got %@", + uint256_obj(hash), txExpected, type]; } else if ([MSG_VERSION isEqual:type]) [self acceptVersionMessage:message]; else if ([MSG_VERACK isEqual:type]) @@ -1264,9 +1265,9 @@ - (void)acceptTxMessage:(NSData *)message { #endif #else #if DEBUG - DSLogPrivate(@"%@:%u got tx %@", self.host, self.port, uint256_obj(tx.txHash)); + DSLogPrivate(@"%@:%u got tx (%lu): %@", self.host, self.port, tx.type, uint256_obj(tx.txHash)); #else - DSLog(@"%@:%u got tx %@", self.host, self.port, @""); + DSLog(@"%@:%u got tx (%lu): %@", self.host, self.port, tx.type, @""); #endif #endif } @@ -1639,8 +1640,8 @@ - (void)acceptMerkleblockMessage:(NSData *)message { [self error:@"got merkleblock message before loading a filter"]; return; } - //else DSLog(@"%@:%u got merkleblock %@", self.host, self.port, block.blockHash); - + //else DSLog(@"%@:%u got merkleblock %@", self.host, self.port, uint256_hex(block.blockHash)); + NSMutableOrderedSet *txHashes = [NSMutableOrderedSet orderedSetWithArray:block.transactionHashes]; @synchronized (self.knownTxHashes) { [txHashes minusOrderedSet:self.knownTxHashes]; diff --git a/DashSync/shared/Models/Transactions/Base/DSTransaction.m b/DashSync/shared/Models/Transactions/Base/DSTransaction.m index 5ecc3c53d..485880905 100644 --- a/DashSync/shared/Models/Transactions/Base/DSTransaction.m +++ b/DashSync/shared/Models/Transactions/Base/DSTransaction.m @@ -307,7 +307,7 @@ - (NSArray *)outputAddresses { - (NSString *)description { NSString *txid = [NSString hexWithData:[NSData dataWithBytes:self.txHash.u8 length:sizeof(UInt256)].reverse]; - return [NSString stringWithFormat:@"%@(id=%@-block=%@) + (%@)", [self class], txid, (self.blockHeight == TX_UNCONFIRMED) ? @"Not mined" : @(self.blockHeight), [super description]]; + return [NSString stringWithFormat:@"%@(id=%@-block=%@)", [super description], txid, (self.blockHeight == TX_UNCONFIRMED) ? @"Not mined" : @(self.blockHeight)]; } - (NSString *)longDescription { diff --git a/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.h b/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.h index d5e5b7bd0..8b504d7f4 100644 --- a/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.h +++ b/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.h @@ -13,7 +13,7 @@ @property (nonatomic, assign) uint32_t height; @property (nonatomic, assign) UInt256 merkleRootMNList; @property (nonatomic, assign) UInt256 merkleRootLLMQList; -@property (nonatomic, assign) uint32_t bestCLHeightDiff; +@property (nonatomic, assign) NSUInteger bestCLHeightDiff; @property (nonatomic, assign) UInt768 bestCLSignature; @property (nonatomic, assign) int64_t creditPoolBalance; diff --git a/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.m b/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.m index 339cdfb8e..16d0d71c1 100644 --- a/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.m +++ b/DashSync/shared/Models/Transactions/Coinbase/DSCoinbaseTransaction.m @@ -39,15 +39,14 @@ - (instancetype)initWithMessage:(NSData *)message onChain:(DSChain *)chain { off += 32; if (version >= COINBASE_TX_CORE_20) { - if (length - off < 4) return nil; - self.bestCLHeightDiff = [message UInt32AtOffset:off]; - off += 4; + NSNumber *len; + self.bestCLHeightDiff = [message varIntAtOffset:off length:&len]; + off += len.unsignedIntegerValue; if (length - off < 96) return nil; self.bestCLSignature = [message UInt768AtOffset:off]; off += 96; if (length - off < 8) return nil; - NSNumber *len; - self.creditPoolBalance = [message varIntAtOffset:off length:&len]; + self.creditPoolBalance = [message Int64AtOffset:off]; off += len.unsignedIntegerValue; } } @@ -93,7 +92,7 @@ - (NSData *)payloadData { if (self.coinbaseTransactionVersion >= COINBASE_TX_CORE_19) { [data appendUInt256:self.merkleRootLLMQList]; if (self.coinbaseTransactionVersion >= COINBASE_TX_CORE_20) { - [data appendUInt32:self.bestCLHeightDiff]; + [data appendVarInt:self.bestCLHeightDiff]; // TODO: check whether it matters to check for optionals [data appendUInt768:self.bestCLSignature]; [data appendInt64:self.creditPoolBalance]; diff --git a/Example/Podfile.lock b/Example/Podfile.lock index c46846c3c..2429e3887 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -586,11 +586,11 @@ PODS: - "!ProtoCompiler-gRPCPlugin (~> 1.0)" - DAPI-GRPC/Messages - gRPC-ProtoRPC - - DashSharedCore (0.4.14) + - DashSharedCore (0.4.15) - DashSync (0.1.0): - CocoaLumberjack (= 3.7.2) - DAPI-GRPC (= 0.22.0-dev.8) - - DashSharedCore (= 0.4.14) + - DashSharedCore (= 0.4.15) - DSDynamicOptions (= 0.1.2) - DWAlertController (= 0.2.1) - TinyCborObjc (= 0.4.6) @@ -712,8 +712,8 @@ SPEC CHECKSUMS: CocoaImageHashing: 8656031d0899abe6c1c415827de43e9798189c53 CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da DAPI-GRPC: 138d62523bbfe7e88a39896f1053c0bc12390d9f - DashSharedCore: dc766715605effeed166d39701825bd1f4c3c500 - DashSync: 3c7c4c0385b8c18dd764c0ef63fc02eef1c38f4f + DashSharedCore: 837242d84149ee9d1cce1037cc583751553421fa + DashSync: 9c5355f4cd18808ef1eeb0d61cce174f52a1f27f DSDynamicOptions: 347cc5d2c4e080eb3de6a86719ad3d861b82adfc DWAlertController: 5f4cd8adf90336331c054857f709f5f8d4b16a5b gRPC: 64f36d689b2ecd99c4351f74e6f91347cdc65d9f diff --git a/Example/Tests/DSTestnetE2ETests.m b/Example/Tests/DSTestnetE2ETests.m index 7bef9f332..6dee83dc7 100644 --- a/Example/Tests/DSTestnetE2ETests.m +++ b/Example/Tests/DSTestnetE2ETests.m @@ -266,71 +266,63 @@ - (void)testFRegisterIdentities { XCTestExpectation *identityRegistrationFinishedExpectation1a = [[XCTestExpectation alloc] init]; [blockchainIdentity1a generateBlockchainIdentityExtendedPublicKeysWithPrompt:@"" completion:^(BOOL registered) { - [blockchainIdentity1a createFundingPrivateKeyWithPrompt:@"" - completion:^(BOOL success, BOOL cancelled) { - if (success && !cancelled) { - [blockchainIdentity1a registerOnNetwork:steps - withFundingAccount:self.fundingAccount1 - forTopupAmount:10000 - stepCompletion:^(DSBlockchainIdentityRegistrationStep stepCompleted) { - - } - completion:^(DSBlockchainIdentityRegistrationStep stepsCompleted, NSError *_Nonnull error) { - XCTAssertNil(error, @"There should not be an error"); - XCTAssert(stepsCompleted = steps, @"We should have completed the same amount of steps that were requested"); - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [identityRegistrationFinishedExpectation1a fulfill]; - }); - }]; - } - }]; - }]; + [blockchainIdentity1a createFundingPrivateKeyWithPrompt:@"" completion:^(BOOL success, BOOL cancelled) { + if (success && !cancelled) { + [blockchainIdentity1a registerOnNetwork:steps + withFundingAccount:self.fundingAccount1 + forTopupAmount:10000 + pinPrompt:@"PIN?" + stepCompletion:^(DSBlockchainIdentityRegistrationStep stepCompleted) {} + completion:^(DSBlockchainIdentityRegistrationStep stepsCompleted, NSError *_Nonnull error) { + XCTAssertNil(error, @"There should not be an error"); + XCTAssert(stepsCompleted = steps, @"We should have completed the same amount of steps that were requested"); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [identityRegistrationFinishedExpectation1a fulfill]; + }); + }]; + } + }]; + }]; [self waitForExpectations:@[identityRegistrationFinishedExpectation1a] timeout:600]; XCTestExpectation *identityRegistrationFinishedExpectation1b = [[XCTestExpectation alloc] init]; - [blockchainIdentity1b generateBlockchainIdentityExtendedPublicKeysWithPrompt:@"" - completion:^(BOOL registered) { - [blockchainIdentity1b createFundingPrivateKeyWithPrompt:@"" - completion:^(BOOL success, BOOL cancelled) { - if (success && !cancelled) { - [blockchainIdentity1b registerOnNetwork:steps - withFundingAccount:self.fundingAccount1 - forTopupAmount:10000 - stepCompletion:^(DSBlockchainIdentityRegistrationStep stepCompleted) { - - } - completion:^(DSBlockchainIdentityRegistrationStep stepsCompleted, NSError *_Nonnull error) { - XCTAssertNil(error, @"There should not be an error"); - XCTAssert(stepsCompleted = steps, @"We should have completed the same amount of steps that were requested"); - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [identityRegistrationFinishedExpectation1b fulfill]; - }); - }]; - } - }]; - }]; + [blockchainIdentity1b generateBlockchainIdentityExtendedPublicKeysWithPrompt:@"" completion:^(BOOL registered) { + [blockchainIdentity1b createFundingPrivateKeyWithPrompt:@"" completion:^(BOOL success, BOOL cancelled) { + if (success && !cancelled) { + [blockchainIdentity1b registerOnNetwork:steps + withFundingAccount:self.fundingAccount1 + forTopupAmount:10000 + pinPrompt:@"PIN?" + stepCompletion:^(DSBlockchainIdentityRegistrationStep stepCompleted) {} + completion:^(DSBlockchainIdentityRegistrationStep stepsCompleted, NSError *_Nonnull error) { + XCTAssertNil(error, @"There should not be an error"); + XCTAssert(stepsCompleted = steps, @"We should have completed the same amount of steps that were requested"); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [identityRegistrationFinishedExpectation1b fulfill]; + }); + }]; + } + }]; + }]; [self waitForExpectations:@[identityRegistrationFinishedExpectation1b] timeout:600]; XCTestExpectation *identityRegistrationFinishedExpectation2a = [[XCTestExpectation alloc] init]; - [blockchainIdentity2a generateBlockchainIdentityExtendedPublicKeysWithPrompt:@"" - completion:^(BOOL registered) { - [blockchainIdentity2a createFundingPrivateKeyWithPrompt:@"" - completion:^(BOOL success, BOOL cancelled) { - if (success && !cancelled) { - [blockchainIdentity2a registerOnNetwork:steps - withFundingAccount:self.fundingAccount1 - forTopupAmount:10000 - stepCompletion:^(DSBlockchainIdentityRegistrationStep stepCompleted) { - - } - completion:^(DSBlockchainIdentityRegistrationStep stepsCompleted, NSError *_Nonnull error) { - XCTAssertNil(error, @"There should not be an error"); - XCTAssert(stepsCompleted = steps, @"We should have completed the same amount of steps that were requested"); - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [identityRegistrationFinishedExpectation2a fulfill]; - }); - }]; - } - }]; - }]; + [blockchainIdentity2a generateBlockchainIdentityExtendedPublicKeysWithPrompt:@"" completion:^(BOOL registered) { + [blockchainIdentity2a createFundingPrivateKeyWithPrompt:@"" completion:^(BOOL success, BOOL cancelled) { + if (success && !cancelled) { + [blockchainIdentity2a registerOnNetwork:steps + withFundingAccount:self.fundingAccount1 + forTopupAmount:10000 + pinPrompt:@"PIN?" + stepCompletion:^(DSBlockchainIdentityRegistrationStep stepCompleted) {} + completion:^(DSBlockchainIdentityRegistrationStep stepsCompleted, NSError *_Nonnull error) { + XCTAssertNil(error, @"There should not be an error"); + XCTAssert(stepsCompleted = steps, @"We should have completed the same amount of steps that were requested"); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [identityRegistrationFinishedExpectation2a fulfill]; + }); + }]; + } + }]; + }]; [self waitForExpectations:@[identityRegistrationFinishedExpectation2a] timeout:600]; } diff --git a/Example/Tests/DSTestnetSyncTests.m b/Example/Tests/DSTestnetSyncTests.m index 36a151e8a..31a437cee 100644 --- a/Example/Tests/DSTestnetSyncTests.m +++ b/Example/Tests/DSTestnetSyncTests.m @@ -102,7 +102,7 @@ - (void)testTestnetFullSync { // give time for saving of other tests to complete XCTestExpectation *headerFinishedExpectation = [[XCTestExpectation alloc] init]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [self.chain useCheckpointBeforeOrOnHeightForSyncingChainBlocks:2000]; + [self.chain useCheckpointBeforeOrOnHeightForSyncingChainBlocks:530000]; [self.chain useCheckpointBeforeOrOnHeightForTerminalBlocksSync:UINT32_MAX]; [[DashSync sharedSyncController] wipePeerDataForChain:self.chain inContext:[NSManagedObjectContext chainContext]]; [[DashSync sharedSyncController] wipeBlockchainDataForChain:self.chain inContext:[NSManagedObjectContext chainContext]];