From 60ac6c26f8391fed4e59d07b6439642976e45d88 Mon Sep 17 00:00:00 2001 From: Andrei Ashikhmin Date: Fri, 31 Jan 2025 12:30:27 +0800 Subject: [PATCH] fix: memory & lock issues in sortTransactions --- DashSync/shared/Models/Wallet/DSAccount.h | 3 --- DashSync/shared/Models/Wallet/DSAccount.m | 29 ++++++----------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/DashSync/shared/Models/Wallet/DSAccount.h b/DashSync/shared/Models/Wallet/DSAccount.h index cb261c2f..dc0ace3c 100644 --- a/DashSync/shared/Models/Wallet/DSAccount.h +++ b/DashSync/shared/Models/Wallet/DSAccount.h @@ -289,9 +289,6 @@ FOUNDATION_EXPORT NSString *_Nonnull const DSAccountNewAccountShouldBeAddedFromT // returns the fee for the given transaction if all its inputs are from wallet transactions, UINT64_MAX otherwise - (uint64_t)feeForTransaction:(DSTransaction *)transaction; -// historical wallet balance after the given transaction, or current balance if transaction is not registered in wallet -- (uint64_t)balanceAfterTransaction:(DSTransaction *)transaction; - - (void)chainUpdatedBlockHeight:(int32_t)height; - (NSArray *)setBlockHeight:(int32_t)height andTimestamp:(NSTimeInterval)timestamp forTransactionHashes:(NSArray *)txHashes; diff --git a/DashSync/shared/Models/Wallet/DSAccount.m b/DashSync/shared/Models/Wallet/DSAccount.m index 6243034c..d994a055 100644 --- a/DashSync/shared/Models/Wallet/DSAccount.m +++ b/DashSync/shared/Models/Wallet/DSAccount.m @@ -671,7 +671,6 @@ - (void)updateBalance { NSMutableOrderedSet *utxos = [NSMutableOrderedSet orderedSet]; NSMutableSet *spentOutputs = [NSMutableSet set], *invalidTx = [NSMutableSet set], *pendingTransactionHashes = [NSMutableSet set]; NSMutableDictionary *pendingCoinbaseLockedTransactionHashes = [NSMutableDictionary dictionary]; - NSMutableArray *balanceHistory = [NSMutableArray array]; uint32_t now = [NSDate timeIntervalSince1970]; for (DSFundsDerivationPath *derivationPath in self.fundDerivationPaths) { @@ -701,7 +700,6 @@ - (void)updateBalance { if (tx.blockHeight == TX_UNCONFIRMED && ([spent intersectsSet:spentOutputs] || [inputs intersectsSet:invalidTx])) { [invalidTx addObject:uint256_obj(tx.txHash)]; - [balanceHistory insertObject:@(balance) atIndex:0]; continue; } } else { @@ -754,7 +752,6 @@ - (void)updateBalance { if (pending || [inputs intersectsSet:pendingTransactionHashes]) { [pendingTransactionHashes addObject:uint256_obj(tx.txHash)]; - [balanceHistory insertObject:@(balance) atIndex:0]; continue; } @@ -765,7 +762,6 @@ - (void)updateBalance { pendingCoinbaseLockedTransactionHashes[@(lockedBlockHeight)] = [NSMutableSet set]; } [((NSMutableSet *)pendingCoinbaseLockedTransactionHashes[@(lockedBlockHeight)]) addObject:uint256_obj(tx.txHash)]; - [balanceHistory insertObject:@(balance) atIndex:0]; continue; } @@ -811,7 +807,6 @@ - (void)updateBalance { if (prevBalance < balance) totalReceived += balance - prevBalance; if (balance < prevBalance) totalSent += prevBalance - balance; - [balanceHistory insertObject:@(balance) atIndex:0]; prevBalance = balance; #if LOG_BALANCE_UPDATE DSLog(@"===UTXOS==="); @@ -835,7 +830,6 @@ - (void)updateBalance { self.pendingCoinbaseLockedTransactionHashes = pendingCoinbaseLockedTransactionHashes; self.spentOutputs = spentOutputs; self.utxos = utxos; - self.balanceHistory = balanceHistory; _totalSent = totalSent; _totalReceived = totalReceived; @@ -849,16 +843,6 @@ - (void)updateBalance { } } -// historical wallet balance after the given transaction, or current balance if transaction is not registered in wallet -- (uint64_t)balanceAfterTransaction:(DSTransaction *)transaction { - NSParameterAssert(transaction); - - NSUInteger i = [self.transactions indexOfObject:transaction]; - - return (i < self.balanceHistory.count) ? [self.balanceHistory[i] unsignedLongLongValue] : self.balance; -} - - - (void)postBalanceDidChangeNotification { [[NSNotificationCenter defaultCenter] postNotificationName:DSWalletBalanceDidChangeNotification object:nil]; } @@ -895,21 +879,22 @@ __block __weak BOOL (^_isAscending)(id, id) = isAscending = ^BOOL(DSTransaction }] != NSNotFound) return NO; if ([self.invalidTransactionHashes containsObject:hash1] && ![self.invalidTransactionHashes containsObject:hash2]) return YES; if ([self.pendingTransactionHashes containsObject:hash1] && ![self.pendingTransactionHashes containsObject:hash2]) return YES; - for (DSTransactionInput *input in tx1.inputs) { - if (_isAscending(self.allTx[uint256_obj(input.inputHash)], tx2)) return YES; - } + return NO; }; + NSArray *externalAddresses = self.externalAddresses; + NSArray *internalAddresses = self.internalAddresses; + [self.transactions sortWithOptions:NSSortStable usingComparator:^NSComparisonResult(id tx1, id tx2) { if (isAscending(tx1, tx2)) return NSOrderedAscending; if (isAscending(tx2, tx1)) return NSOrderedDescending; - NSUInteger i = transactionAddressIndex(tx1, self.internalAddresses); - NSUInteger j = transactionAddressIndex(tx2, (i == NSNotFound) ? self.externalAddresses : self.internalAddresses); + NSUInteger i = transactionAddressIndex(tx1, internalAddresses); + NSUInteger j = transactionAddressIndex(tx2, (i == NSNotFound) ? externalAddresses : internalAddresses); - if (i == NSNotFound && j != NSNotFound) i = transactionAddressIndex(tx1, self.externalAddresses); + if (i == NSNotFound && j != NSNotFound) i = transactionAddressIndex(tx1, externalAddresses); if (i == NSNotFound || j == NSNotFound || i == j) return NSOrderedSame; return (i > j) ? NSOrderedAscending : NSOrderedDescending; }];