From 35ddf87a1b2bf10f6d2cda23ebda03b4c574534b Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 3 Dec 2024 13:01:44 +0100 Subject: [PATCH 1/2] [#1512] Ensure that the SDK does not assume a default account anywhere - The SDK no longer assumes a default account. All business logic with instances of Zip32AccountIndex() has been refactored. --- CHANGELOG.md | 1 + .../GetBalanceViewController.swift | 4 +- .../Get UTXOs/GetUTXOsViewController.swift | 2 +- .../Send/SendViewController.swift | 10 +-- .../Block/Actions/SaplingParamsAction.swift | 4 +- .../SaplingParametersHandler.swift | 34 +++++++-- .../ClosureSynchronizer.swift | 2 +- .../Metrics/SDKMetrics.swift | 17 +++-- .../ZcashLightClientKit/Synchronizer.swift | 15 ++-- .../Synchronizer/ClosureSDKSynchronizer.swift | 4 +- .../Synchronizer/CombineSDKSynchronizer.swift | 4 +- .../Synchronizer/SDKSynchronizer.swift | 15 ++-- Tests/DarksideTests/AdvancedReOrgTests.swift | 73 +++++++++++-------- Tests/DarksideTests/BalanceTests.swift | 51 +++++++------ Tests/DarksideTests/RewindRescanTests.swift | 29 +++++--- Tests/DarksideTests/ShieldFundsTests.swift | 24 +++--- Tests/DarksideTests/SynchronizerTests.swift | 13 ++-- .../ClosureSynchronizerOfflineTests.swift | 27 +++++-- .../CombineSynchronizerOfflineTests.swift | 40 +++++----- .../AutoMockable.generated.swift | 48 ++++++------ 20 files changed, 237 insertions(+), 180 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6ab6af3f..0d67a95e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this library adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Changed - `zcashlc_propose_transfer`, `zcashlc_propose_transfer_from_uri` and `zcashlc_propose_shielding` no longer accpt a `use_zip317_fees` parameter; ZIP 317 standard fees are now always used and are not configurable. +- The SDK no longer assumes a default account. All business logic with instances of Zip32AccountIndex() has been refactored. ## Checkpoints diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Get Balance/GetBalanceViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Get Balance/GetBalanceViewController.swift index 9aa2ea0d4..a36327e31 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Get Balance/GetBalanceViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Get Balance/GetBalanceViewController.swift @@ -27,7 +27,9 @@ class GetBalanceViewController: UIViewController { self.title = "Account 0 Balance" Task { @MainActor [weak self] in - self?.accountBalance = try? await synchronizer.getAccountBalance(accountIndex: accountIndex) + guard let accountIndex = self?.accountIndex else { return } + + self?.accountBalance = try? await synchronizer.getAccountsBalances()[accountIndex] self?.updateLabels() } diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift index 663df44d9..779e33d41 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Get UTXOs/GetUTXOsViewController.swift @@ -33,7 +33,7 @@ class GetUTXOsViewController: UIViewController { self.transparentAddressLabel.text = tAddress // swiftlint:disable:next force_try - let balance = try! await AppDelegate.shared.sharedSynchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero + let balance = try! await AppDelegate.shared.sharedSynchronizer.getAccountsBalances()[accountIndex]?.unshielded ?? .zero self.totalBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.amount)) self.verifiedBalanceLabel.text = NumberFormatter.zcashNumberFormatter.string(from: NSNumber(value: balance.amount)) diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift index ac3cb3d56..633aa9234 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift @@ -105,10 +105,10 @@ class SendViewController: UIViewController { func updateBalance() async { balanceLabel.text = format( - balance: (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.total() ?? .zero + balance: (try? await synchronizer.getAccountsBalances()[accountIndex])?.saplingBalance.total() ?? .zero ) verifiedBalanceLabel.text = format( - balance: (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero + balance: (try? await synchronizer.getAccountsBalances()[accountIndex])?.saplingBalance.spendableValue ?? .zero ) } @@ -123,7 +123,7 @@ class SendViewController: UIViewController { func maxFundsOn() { Task { @MainActor in let fee = Zatoshi(10000) - let max: Zatoshi = ((try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero) - fee + let max: Zatoshi = ((try? await synchronizer.getAccountsBalances()[accountIndex])?.saplingBalance.spendableValue ?? .zero) - fee amountTextField.text = format(balance: max) amountTextField.isEnabled = false } @@ -145,12 +145,12 @@ class SendViewController: UIViewController { } func isBalanceValid() async -> Bool { - let balance = (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero + let balance = (try? await synchronizer.getAccountsBalances()[accountIndex])?.saplingBalance.spendableValue ?? .zero return balance > .zero } func isAmountValid() async -> Bool { - let balance = (try? await synchronizer.getAccountBalance(accountIndex: accountIndex))?.saplingBalance.spendableValue ?? .zero + let balance = (try? await synchronizer.getAccountsBalances()[accountIndex])?.saplingBalance.spendableValue ?? .zero guard let value = amountTextField.text, let amount = NumberFormatter.zcashNumberFormatter.number(from: value).flatMap({ Zatoshi($0.int64Value) }), diff --git a/Sources/ZcashLightClientKit/Block/Actions/SaplingParamsAction.swift b/Sources/ZcashLightClientKit/Block/Actions/SaplingParamsAction.swift index 190d1ff43..f734e645f 100644 --- a/Sources/ZcashLightClientKit/Block/Actions/SaplingParamsAction.swift +++ b/Sources/ZcashLightClientKit/Block/Actions/SaplingParamsAction.swift @@ -22,9 +22,7 @@ extension SaplingParamsAction: Action { func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext { logger.debug("Fetching sapling parameters") - // TODO: [#1512] This is hardcoded Zip32AccountIndex for index 0, must be updated - // https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1512 - try await saplingParametersHandler.handleIfNeeded(accountIndex: Zip32AccountIndex(0)) + try await saplingParametersHandler.handleIfNeeded() await context.update(state: .updateSubtreeRoots) diff --git a/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift b/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift index 5eb7ff5de..2200bb2eb 100644 --- a/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift +++ b/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift @@ -14,7 +14,7 @@ struct SaplingParametersHandlerConfig { } protocol SaplingParametersHandler { - func handleIfNeeded(accountIndex: Zip32AccountIndex) async throws + func handleIfNeeded() async throws } struct SaplingParametersHandlerImpl { @@ -24,17 +24,37 @@ struct SaplingParametersHandlerImpl { } extension SaplingParametersHandlerImpl: SaplingParametersHandler { - func handleIfNeeded(accountIndex: Zip32AccountIndex) async throws { + func handleIfNeeded() async throws { try Task.checkCancellation() do { - let totalSaplingBalance = - try await rustBackend.getWalletSummary()?.accountBalances[accountIndex]?.saplingBalance.total().amount - ?? 0 - let totalTransparentBalance = try await rustBackend.getTransparentBalance(accountIndex: accountIndex) + let accounts = try await rustBackend.listAccounts() + var totalSaplingBalanceTrigger = false + var totalTransparentBalanceTrigger = false + + for account in accounts { + let zip32AccountIndex = Zip32AccountIndex(account.index) + + let totalSaplingBalance = + try await rustBackend.getWalletSummary()?.accountBalances[zip32AccountIndex]?.saplingBalance.total().amount + ?? 0 + + if totalSaplingBalance > 0 { + totalSaplingBalanceTrigger = true + break + } + + let totalTransparentBalance = try await rustBackend.getTransparentBalance(accountIndex: zip32AccountIndex) + + if totalTransparentBalance > 0 { + totalTransparentBalanceTrigger = true + break + } + } + // Download Sapling parameters only if sapling funds are detected. - guard totalSaplingBalance > 0 || totalTransparentBalance > 0 else { return } + guard totalSaplingBalanceTrigger || totalTransparentBalanceTrigger else { return } } catch { // if sapling balance can't be detected of we fail to obtain the balance // for some reason we shall not proceed to download the parameters and diff --git a/Sources/ZcashLightClientKit/ClosureSynchronizer.swift b/Sources/ZcashLightClientKit/ClosureSynchronizer.swift index 24d17379e..41296a775 100644 --- a/Sources/ZcashLightClientKit/ClosureSynchronizer.swift +++ b/Sources/ZcashLightClientKit/ClosureSynchronizer.swift @@ -127,7 +127,7 @@ public protocol ClosureSynchronizer { func refreshUTXOs(address: TransparentAddress, from height: BlockHeight, completion: @escaping (Result) -> Void) - func getAccountBalance(accountIndex: Zip32AccountIndex, completion: @escaping (Result) -> Void) + func getAccountsBalances(completion: @escaping (Result<[Zip32AccountIndex: AccountBalance], Error>) -> Void) func refreshExchangeRateUSD() diff --git a/Sources/ZcashLightClientKit/Metrics/SDKMetrics.swift b/Sources/ZcashLightClientKit/Metrics/SDKMetrics.swift index 36c495a67..11dc4603f 100644 --- a/Sources/ZcashLightClientKit/Metrics/SDKMetrics.swift +++ b/Sources/ZcashLightClientKit/Metrics/SDKMetrics.swift @@ -105,18 +105,25 @@ final class SDKMetricsImpl: SDKMetrics { func logCBPOverviewReport(_ logger: Logger, walletSummary: WalletSummary?) async { actionStop() - // TODO: [#1512] This is hardcoded Zip32AccountIndex for index 0, must be updated - // https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1512 - let accountBalance = walletSummary?.accountBalances[Zip32AccountIndex(0)] logger.sync( """ SYNC (\(syncs)) REPORT finished in: \(Date().timeIntervalSince1970 - cbpStartTime) - verified balance: \(accountBalance?.saplingBalance.spendableValue.amount ?? 0) - total balance: \(accountBalance?.saplingBalance.total().amount ?? 0) """ ) + if let accountBalances = walletSummary?.accountBalances { + for accountBalance in accountBalances { + logger.sync( + """ + account index: \(accountBalance.key) + verified balance: \(accountBalance.value.saplingBalance.spendableValue.amount) + total balance: \(accountBalance.value.saplingBalance.total().amount) + """ + ) + } + } + try? await Task.sleep(nanoseconds: 100_000) for action in cbpOverview { diff --git a/Sources/ZcashLightClientKit/Synchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer.swift index 87c0aaa4b..072cf9a75 100644 --- a/Sources/ZcashLightClientKit/Synchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer.swift @@ -36,7 +36,7 @@ public struct SynchronizerState: Equatable { /// SyncSessionIDs are provided to users public var syncSessionID: UUID /// account balance known to this synchronizer given the data that has processed locally - public var accountBalance: AccountBalance? + public var accountsBalances: [Zip32AccountIndex: AccountBalance] /// status of the whole sync process var internalSyncStatus: InternalSyncStatus public var syncStatus: SyncStatus @@ -47,7 +47,7 @@ public struct SynchronizerState: Equatable { public static var zero: SynchronizerState { SynchronizerState( syncSessionID: .nullID, - accountBalance: .zero, + accountsBalances: [:], internalSyncStatus: .unprepared, latestBlockHeight: .zero ) @@ -55,12 +55,12 @@ public struct SynchronizerState: Equatable { init( syncSessionID: UUID, - accountBalance: AccountBalance?, + accountsBalances: [Zip32AccountIndex: AccountBalance], internalSyncStatus: InternalSyncStatus, latestBlockHeight: BlockHeight ) { self.syncSessionID = syncSessionID - self.accountBalance = accountBalance + self.accountsBalances = accountsBalances self.internalSyncStatus = internalSyncStatus self.latestBlockHeight = latestBlockHeight self.syncStatus = internalSyncStatus.mapToSyncStatus() @@ -307,10 +307,9 @@ public protocol Synchronizer: AnyObject { /// `SynchronizerErrors.notPrepared`. func refreshUTXOs(address: TransparentAddress, from height: BlockHeight) async throws -> RefreshedUTXOs - /// Account balances from the given account index - /// - Parameter accountIndex: the ZIP 32 index of the account - /// - Returns: `AccountBalance`, struct that holds Sapling and unshielded balances, or `nil` when no account is associated with the given ZIP 32 index - func getAccountBalance(accountIndex: Zip32AccountIndex) async throws -> AccountBalance? + /// Accounts balances + /// - Returns: `[Zip32AccountIndex: AccountBalance]`, struct that holds Sapling and unshielded balances per account + func getAccountsBalances() async throws -> [Zip32AccountIndex: AccountBalance] /// Fetches the latest ZEC-USD exchange rate and updates `exchangeRateUSDSubject`. func refreshExchangeRateUSD() diff --git a/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift index 4f57dae3b..05d51d4a4 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift @@ -188,9 +188,9 @@ extension ClosureSDKSynchronizer: ClosureSynchronizer { } } - public func getAccountBalance(accountIndex: Zip32AccountIndex, completion: @escaping (Result) -> Void) { + public func getAccountsBalances(completion: @escaping (Result<[Zip32AccountIndex: AccountBalance], Error>) -> Void) { AsyncToClosureGateway.executeThrowingAction(completion) { - try await self.synchronizer.getAccountBalance(accountIndex: accountIndex) + try await self.synchronizer.getAccountsBalances() } } diff --git a/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift index f4e8b9423..28ce700fd 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift @@ -190,9 +190,9 @@ extension CombineSDKSynchronizer: CombineSynchronizer { } } - public func getAccountBalance(accountIndex: Zip32AccountIndex) -> SinglePublisher { + public func getAccountsBalances() -> SinglePublisher<[Zip32AccountIndex: AccountBalance], Error> { AsyncToCombineGateway.executeThrowingAction() { - try await self.synchronizer.getAccountBalance(accountIndex: accountIndex) + try await self.synchronizer.getAccountsBalances() } } diff --git a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift index 213834452..2d00ca4b2 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift @@ -28,9 +28,6 @@ public class SDKSynchronizer: Synchronizer { let metrics: SDKMetrics public let logger: Logger var tor: TorClient? - // TODO: [#1512] Only one instance of hardcoded account index has been removed in deeper levels and moved here, needs to be resolved in #1512 - // https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1512 - private var accountIndex = Zip32AccountIndex(0) // Don't read this variable directly. Use `status` instead. And don't update this variable directly use `updateStatus()` methods instead. private var underlyingStatus: GenericActor @@ -397,7 +394,7 @@ public class SDKSynchronizer: Synchronizer { try throwIfUnprepared() // let's see if there are funds to shield - guard let tBalance = try await self.getAccountBalance(accountIndex: spendingKey.accountIndex)?.unshielded else { + guard let tBalance = try await self.getAccountsBalances()[spendingKey.accountIndex]?.unshielded else { throw ZcashError.synchronizerSpendingKeyDoesNotBelongToTheWallet } @@ -511,8 +508,8 @@ public class SDKSynchronizer: Synchronizer { return try await blockProcessor.refreshUTXOs(tAddress: address, startHeight: height) } - public func getAccountBalance(accountIndex: Zip32AccountIndex) async throws -> AccountBalance? { - try await initializer.rustBackend.getWalletSummary()?.accountBalances[accountIndex] + public func getAccountsBalances() async throws -> [Zip32AccountIndex: AccountBalance] { + try await initializer.rustBackend.getWalletSummary()?.accountBalances ?? [:] } /// Fetches the latest ZEC-USD exchange rate. @@ -923,10 +920,10 @@ public class SDKSynchronizer: Synchronizer { // MARK: notify state - private func snapshotState(status: InternalSyncStatus, accountIndex: Zip32AccountIndex) async -> SynchronizerState { + private func snapshotState(status: InternalSyncStatus) async -> SynchronizerState { await SynchronizerState( syncSessionID: syncSession.value, - accountBalance: try? await getAccountBalance(accountIndex: accountIndex), + accountsBalances: (try? await getAccountsBalances()) ?? [:], internalSyncStatus: status, latestBlockHeight: latestBlocksDataProvider.latestBlockHeight ) @@ -951,7 +948,7 @@ public class SDKSynchronizer: Synchronizer { if SessionTicker.live.isNewSyncSession(oldStatus, newStatus) { await self.syncSession.newSession(with: self.syncSessionIDGenerator) } - newState = await snapshotState(status: newStatus, accountIndex: accountIndex) + newState = await snapshotState(status: newStatus) } latestState = newState diff --git a/Tests/DarksideTests/AdvancedReOrgTests.swift b/Tests/DarksideTests/AdvancedReOrgTests.swift index f973fcc1c..16db33059 100644 --- a/Tests/DarksideTests/AdvancedReOrgTests.swift +++ b/Tests/DarksideTests/AdvancedReOrgTests.swift @@ -86,6 +86,7 @@ class AdvancedReOrgTests: ZcashTestCase { var initialTotalBalance = Zatoshi(-1) var initialVerifiedBalance = Zatoshi(-1) self.expectedReorgHeight = receivedTxHeight + 1 + let accountIndex = Zip32AccountIndex(0) /* precondition:know balances before tx at received_Tx_height arrives @@ -100,8 +101,8 @@ class AdvancedReOrgTests: ZcashTestCase { try await coordinator.sync( completion: { synchro in synchronizer = synchro - initialVerifiedBalance = try await synchro.getAccountBalance()?.saplingBalance.spendableValue ?? .zero - initialTotalBalance = try await synchro.getAccountBalance()?.saplingBalance.total() ?? .zero + initialVerifiedBalance = try await synchro.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero + initialTotalBalance = try await synchro.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero preTxExpectation.fulfill() shouldContinue = true }, @@ -135,8 +136,8 @@ class AdvancedReOrgTests: ZcashTestCase { try await coordinator.sync( completion: { synchro in synchronizer = synchro - receivedTxVerifiedBalance = try await synchro.getAccountBalance()?.saplingBalance.spendableValue ?? .zero - receivedTxTotalBalance = try await synchro.getAccountBalance()?.saplingBalance.total() ?? .zero + receivedTxVerifiedBalance = try await synchro.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero + receivedTxTotalBalance = try await synchro.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero receivedTxExpectation.fulfill() }, error: self.handleError ) @@ -202,8 +203,8 @@ class AdvancedReOrgTests: ZcashTestCase { do { try await coordinator.sync( completion: { synchronizer in - afterReorgTxTotalBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - afterReorgTxVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + afterReorgTxTotalBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + afterReorgTxVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero reorgSyncexpectation.fulfill() }, error: self.handleError @@ -238,8 +239,8 @@ class AdvancedReOrgTests: ZcashTestCase { do { try await coordinator.sync( completion: { synchronizer in - finalReorgTxTotalBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - finalReorgTxVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + finalReorgTxTotalBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + finalReorgTxVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero finalsyncExpectation.fulfill() }, error: self.handleError @@ -289,6 +290,7 @@ class AdvancedReOrgTests: ZcashTestCase { try FakeChainBuilder.buildChain(darksideWallet: self.coordinator.service, branchID: branchID, chainName: chainName) let receivedTxHeight: BlockHeight = 663188 var initialTotalBalance = Zatoshi(-1) + let accountIndex = Zip32AccountIndex(0) /* 2. applyStaged(received_Tx_height) @@ -304,7 +306,7 @@ class AdvancedReOrgTests: ZcashTestCase { do { try await coordinator.sync( completion: { synchronizer in - initialTotalBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + initialTotalBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero preTxExpectation.fulfill() }, error: self.handleError @@ -450,17 +452,18 @@ class AdvancedReOrgTests: ZcashTestCase { await fulfillment(of: [lastSyncExpectation], timeout: 5) let expectedVerifiedBalance = initialTotalBalance + pendingTx.value - let currentVerifiedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + let currentVerifiedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero // TODO: [#1247] needs to review this to properly solve, https://github.com/zcash/ZcashLightClientKit/issues/1247 // let expectedPendingTransactionsCount = await coordinator.synchronizer.pendingTransactions.count // XCTAssertEqual(expectedPendingTransactionsCount, 0) XCTAssertEqual(expectedVerifiedBalance, currentVerifiedBalance) - let resultingBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let resultingBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual(resultingBalance, currentVerifiedBalance) } func testIncomingTransactionIndexChange() async throws { + let accountIndex = Zip32AccountIndex(0) await hookToReOrgNotification() self.expectedReorgHeight = 663196 self.expectedRewindHeight = 663175 @@ -480,8 +483,8 @@ class AdvancedReOrgTests: ZcashTestCase { var preReorgVerifiedBalance = Zatoshi.zero try await coordinator.sync( completion: { synchronizer in - preReorgTotalBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - preReorgVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + preReorgTotalBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + preReorgVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero firstSyncExpectation.fulfill() }, error: self.handleError @@ -503,8 +506,8 @@ class AdvancedReOrgTests: ZcashTestCase { var postReorgVerifiedBalance = Zatoshi.zero try await coordinator.sync( completion: { synchronizer in - postReorgTotalBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - postReorgVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + postReorgTotalBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + postReorgVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero afterReorgSync.fulfill() }, error: self.handleError @@ -517,6 +520,7 @@ class AdvancedReOrgTests: ZcashTestCase { } func testReOrgExpiresInboundTransaction() async throws { + let accountIndex = Zip32AccountIndex(0) try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) let receivedTxHeight = BlockHeight(663188) try coordinator.applyStaged(blockheight: receivedTxHeight - 1) @@ -527,8 +531,8 @@ class AdvancedReOrgTests: ZcashTestCase { try await coordinator.sync( completion: { synchronizer in - initialBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - initialVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + initialBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + initialVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero expectation.fulfill() }, error: self.handleError @@ -546,8 +550,8 @@ class AdvancedReOrgTests: ZcashTestCase { try await coordinator.sync( completion: { synchronizer in - afterTxBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - afterTxVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + afterTxBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + afterTxVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero let receivedTransactions = await synchronizer.receivedTransactions XCTAssertNotNil( receivedTransactions.first { $0.minedHeight == receivedTxHeight }, @@ -576,8 +580,8 @@ class AdvancedReOrgTests: ZcashTestCase { try await coordinator.sync( completion: { synchronizer in - afterReOrgBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - afterReOrgVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + afterReOrgBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + afterReOrgVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero let receivedTransactions = await synchronizer.receivedTransactions XCTAssertNil( receivedTransactions.first { $0.minedHeight == receivedTxHeight }, @@ -628,6 +632,7 @@ class AdvancedReOrgTests: ZcashTestCase { try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) let incomingTxHeight = BlockHeight(663188) + let accountIndex = Zip32AccountIndex(0) try coordinator.applyStaged(blockheight: incomingTxHeight + 1) @@ -653,7 +658,7 @@ class AdvancedReOrgTests: ZcashTestCase { /* 1a. save balances */ - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] initialBalance = accountBalance?.saplingBalance.total() ?? .zero initialVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero incomingTx = await coordinator.synchronizer.receivedTransactions.first(where: { $0.minedHeight == incomingTxHeight }) @@ -702,7 +707,7 @@ class AdvancedReOrgTests: ZcashTestCase { /* 7. check that balances still match */ - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedVerifiedBalance, initialVerifiedBalance) @@ -712,6 +717,7 @@ class AdvancedReOrgTests: ZcashTestCase { func testTxIndexReorg() async throws { try coordinator.resetBlocks(dataset: .predefined(dataset: .txIndexChangeBefore)) + let accountIndex = Zip32AccountIndex(0) let txReorgHeight = BlockHeight(663195) let finalHeight = BlockHeight(663200) try coordinator.applyStaged(blockheight: txReorgHeight) @@ -723,8 +729,8 @@ class AdvancedReOrgTests: ZcashTestCase { try await coordinator.sync( completion: { synchronizer in - initialBalance = try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero - initialVerifiedBalance = try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + initialBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero + initialVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero firstSyncExpectation.fulfill() }, error: self.handleError @@ -748,7 +754,7 @@ class AdvancedReOrgTests: ZcashTestCase { await fulfillment(of: [lastSyncExpectation], timeout: 5) - let accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, initialBalance) @@ -1062,6 +1068,7 @@ class AdvancedReOrgTests: ZcashTestCase { branchID: branchID, chainName: chainName ) + let accountIndex = Zip32AccountIndex(0) sleep(2) try coordinator.resetBlocks(dataset: .predefined(dataset: .txHeightReOrgBefore)) @@ -1081,7 +1088,7 @@ class AdvancedReOrgTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 5) - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let initialBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero let initialVerifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero guard let initialTxHeight = try await coordinator.synchronizer.allReceivedTransactions().first?.minedHeight else { @@ -1112,7 +1119,7 @@ class AdvancedReOrgTests: ZcashTestCase { return } - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(initialVerifiedBalance, expectedVerifiedBalance) @@ -1142,6 +1149,7 @@ class AdvancedReOrgTests: ZcashTestCase { try coordinator.resetBlocks(dataset: .predefined(dataset: .txReOrgRemovesInboundTxBefore)) + let accountIndex = Zip32AccountIndex(0) let reorgHeight: BlockHeight = 663195 self.expectedReorgHeight = reorgHeight self.expectedRewindHeight = reorgHeight - 10 @@ -1163,7 +1171,7 @@ class AdvancedReOrgTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 5) - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let initialTotalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero let initialVerifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero @@ -1202,7 +1210,7 @@ class AdvancedReOrgTests: ZcashTestCase { await fulfillment(of: [afterReorgSyncExpectation], timeout: 5) - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(initialVerifiedBalance, expectedVerifiedBalance) @@ -1231,6 +1239,7 @@ class AdvancedReOrgTests: ZcashTestCase { try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) let sentTxHeight: BlockHeight = 663195 try coordinator.applyStaged(blockheight: sentTxHeight - 1) + let accountIndex = Zip32AccountIndex(0) sleep(2) @@ -1253,7 +1262,7 @@ class AdvancedReOrgTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 10) sleep(1) - let initialTotalBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let initialTotalBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero let sendExpectation = XCTestExpectation(description: "send expectation") var pendingEntity: ZcashTransaction.Overview? @@ -1373,7 +1382,7 @@ class AdvancedReOrgTests: ZcashTestCase { await fulfillment(of: [lastSyncExpectation], timeout: 5) - let expectedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let expectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, initialTotalBalance) } diff --git a/Tests/DarksideTests/BalanceTests.swift b/Tests/DarksideTests/BalanceTests.swift index 15c41e7f7..ee92d787e 100644 --- a/Tests/DarksideTests/BalanceTests.swift +++ b/Tests/DarksideTests/BalanceTests.swift @@ -84,7 +84,8 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 12) // 2 check that there are no unconfirmed funds - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero XCTAssertTrue(verifiedBalance > network.constants.defaultFee()) @@ -199,7 +200,7 @@ class BalanceTests: ZcashTestCase { // // XCTAssertNil(confirmedPending, "pending, now confirmed transaction found") - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, .zero) @@ -238,7 +239,8 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 12) // 2 check that there are no unconfirmed funds - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero XCTAssertTrue(verifiedBalance > network.constants.defaultFee()) @@ -354,7 +356,7 @@ class BalanceTests: ZcashTestCase { // // XCTAssertNil(confirmedPending, "pending, now confirmed transaction found") - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, .zero) @@ -387,7 +389,8 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 12) // 2 check that there are no unconfirmed funds - let accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + let accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero XCTAssertTrue(verifiedBalance > network.constants.defaultFee()) @@ -453,7 +456,8 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 12) // 2 check that there are no unconfirmed funds - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero XCTAssertTrue(verifiedBalance > network.constants.defaultFee()) @@ -569,7 +573,7 @@ class BalanceTests: ZcashTestCase { // // XCTAssertNil(confirmedPending, "pending, now confirmed transaction found") - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, Zatoshi(100000)) @@ -615,7 +619,8 @@ class BalanceTests: ZcashTestCase { let spendingKey = coordinator.spendingKey - let presendVerifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + let accountIndex = Zip32AccountIndex(0) + let presendVerifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero /* there's more zatoshi to send than network fee @@ -633,7 +638,7 @@ class BalanceTests: ZcashTestCase { pendingTx = transaction self.sentTransactionExpectation.fulfill() - var expectedVerifiedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + var expectedVerifiedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero XCTAssertTrue(expectedVerifiedBalance > .zero) await fulfillment(of: [sentTransactionExpectation], timeout: 12) @@ -666,7 +671,7 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [mineExpectation], timeout: 5) - let accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero @@ -717,7 +722,7 @@ class BalanceTests: ZcashTestCase { spentValue: sentOutput.value, fee: fee, sentAmount: self.sendAmount, - currentVerifiedBalance: try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + currentVerifiedBalance: try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero ) } @@ -759,7 +764,8 @@ class BalanceTests: ZcashTestCase { let spendingKey = coordinator.spendingKey - let presendBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let accountIndex = Zip32AccountIndex(0) + let presendBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero // there's more zatoshi to send than network fee XCTAssertTrue(presendBalance >= network.constants.defaultFee() + sendAmount) @@ -781,7 +787,7 @@ class BalanceTests: ZcashTestCase { XCTFail("sendToAddress failed: \(error)") } - let accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] var expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero XCTAssertTrue(expectedVerifiedBalance > .zero) await fulfillment(of: [sentTransactionExpectation], timeout: 12) @@ -831,7 +837,7 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [mineExpectation], timeout: 5) - expectedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + expectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual( presendBalance - self.sendAmount - network.constants.defaultFee(), expectedBalance @@ -867,8 +873,9 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [syncedExpectation], timeout: 5) + let accountIndex = Zip32AccountIndex(0) let clearedTransactions = await coordinator.synchronizer.transactions - let expectedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let expectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual(clearedTransactions.count, 2) XCTAssertEqual(expectedBalance, Zatoshi(200000)) } @@ -920,7 +927,8 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [syncedExpectation], timeout: 6) - let accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + let accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let previousVerifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let previousTotalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero @@ -1029,11 +1037,11 @@ class BalanceTests: ZcashTestCase { spentValue: sentOutput.value, fee: fee, sentAmount: self.sendAmount, - currentVerifiedBalance: try await synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + currentVerifiedBalance: try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero ) self.totalBalanceValidation( - totalBalance: try await synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero, + totalBalance: try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero, previousTotalbalance: previousTotalBalance, sentAmount: self.sendAmount ) @@ -1092,7 +1100,8 @@ class BalanceTests: ZcashTestCase { let spendingKey = coordinator.spendingKey - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let previousVerifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let previousTotalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero let sendExpectation = XCTestExpectation(description: "send expectation") @@ -1108,7 +1117,7 @@ class BalanceTests: ZcashTestCase { sendExpectation.fulfill() } catch { // balance should be the same as before sending if transaction failed - let accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedVerifiedBalance, previousVerifiedBalance) @@ -1142,7 +1151,7 @@ class BalanceTests: ZcashTestCase { await fulfillment(of: [expirationSyncExpectation], timeout: 5) - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero /* diff --git a/Tests/DarksideTests/RewindRescanTests.swift b/Tests/DarksideTests/RewindRescanTests.swift index 71b9a3c9e..c05f54a96 100644 --- a/Tests/DarksideTests/RewindRescanTests.swift +++ b/Tests/DarksideTests/RewindRescanTests.swift @@ -69,8 +69,9 @@ class RewindRescanTests: ZcashTestCase { // 1 sync and get spendable funds try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) + let accountIndex = Zip32AccountIndex(0) try coordinator.applyStaged(blockheight: defaultLatestHeight + 50) - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let initialVerifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let initialTotalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero sleep(1) @@ -88,7 +89,7 @@ class RewindRescanTests: ZcashTestCase { } await fulfillment(of: [firstSyncExpectation], timeout: 12) - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero // 2 check that there are no unconfirmed funds @@ -125,7 +126,7 @@ class RewindRescanTests: ZcashTestCase { // XCTAssertEqual(lastScannedHeight, self.birthday) // check that the balance is cleared - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] var expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero var expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(initialVerifiedBalance, expectedVerifiedBalance) @@ -146,7 +147,7 @@ class RewindRescanTests: ZcashTestCase { await fulfillment(of: [secondScanExpectation], timeout: 12) // verify that the balance still adds up - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(verifiedBalance, expectedVerifiedBalance) @@ -162,10 +163,12 @@ class RewindRescanTests: ZcashTestCase { chainName: chainName, length: 10000 ) + + let accountIndex = Zip32AccountIndex(0) let newChaintTip = defaultLatestHeight + 10000 try coordinator.applyStaged(blockheight: newChaintTip) sleep(3) - let initialVerifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + let initialVerifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero let firstSyncExpectation = XCTestExpectation(description: "first sync expectation") do { @@ -180,7 +183,7 @@ class RewindRescanTests: ZcashTestCase { } await fulfillment(of: [firstSyncExpectation], timeout: 20) - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero // 2 check that there are no unconfirmed funds @@ -214,7 +217,7 @@ class RewindRescanTests: ZcashTestCase { await fulfillment(of: [rewindExpectation], timeout: 2) // check that the balance is cleared - var expectedVerifiedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero + var expectedVerifiedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero XCTAssertEqual(initialVerifiedBalance, expectedVerifiedBalance) let secondScanExpectation = XCTestExpectation(description: "rescan") @@ -233,7 +236,7 @@ class RewindRescanTests: ZcashTestCase { await fulfillment(of: [secondScanExpectation], timeout: 20) // verify that the balance still adds up - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(verifiedBalance, expectedVerifiedBalance) @@ -273,7 +276,8 @@ class RewindRescanTests: ZcashTestCase { ) await fulfillment(of: [firstSyncExpectation], timeout: 12) - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero // 2 check that there are no unconfirmed funds @@ -327,7 +331,7 @@ class RewindRescanTests: ZcashTestCase { await fulfillment(of: [secondScanExpectation], timeout: 12) // verify that the balance still adds up - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedBalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(verifiedBalance, expectedVerifiedBalance) @@ -364,7 +368,8 @@ class RewindRescanTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 12) // 2 check that there are no unconfirmed funds - var accountBalance = try await coordinator.synchronizer.getAccountBalance() + let accountIndex = Zip32AccountIndex(0) + var accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let verifiedBalance: Zatoshi = accountBalance?.saplingBalance.spendableValue ?? .zero let totalBalance: Zatoshi = accountBalance?.saplingBalance.total() ?? .zero XCTAssertTrue(verifiedBalance > network.constants.defaultFee()) @@ -520,7 +525,7 @@ class RewindRescanTests: ZcashTestCase { // // XCTAssertNil(confirmedPending, "pending, now confirmed transaction found") - accountBalance = try await coordinator.synchronizer.getAccountBalance() + accountBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex] let expectedVerifiedbalance = accountBalance?.saplingBalance.spendableValue ?? .zero let expectedBalance = accountBalance?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, .zero) diff --git a/Tests/DarksideTests/ShieldFundsTests.swift b/Tests/DarksideTests/ShieldFundsTests.swift index e147e8fef..6da9e7dd9 100644 --- a/Tests/DarksideTests/ShieldFundsTests.swift +++ b/Tests/DarksideTests/ShieldFundsTests.swift @@ -101,7 +101,7 @@ class ShieldFundsTests: ZcashTestCase { var initialTotalBalance = Zatoshi(-1) var initialVerifiedBalance = Zatoshi(-1) - var initialTransparentBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero + var initialTransparentBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.unshielded ?? .zero let utxo = try GetAddressUtxosReply(jsonString: """ @@ -123,8 +123,8 @@ class ShieldFundsTests: ZcashTestCase { do { try await coordinator.sync( completion: { synchronizer in - initialVerifiedBalance = try await synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.spendableValue ?? .zero - initialTotalBalance = try await synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero + initialVerifiedBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero + initialTotalBalance = try await synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero preTxExpectation.fulfill() shouldContinue = true }, @@ -144,7 +144,7 @@ class ShieldFundsTests: ZcashTestCase { // at this point the balance should be all zeroes for transparent and shielded funds XCTAssertEqual(initialTotalBalance, Zatoshi.zero) XCTAssertEqual(initialVerifiedBalance, Zatoshi.zero) - initialTransparentBalance = (try? await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex))?.unshielded ?? .zero + initialTransparentBalance = (try? await coordinator.synchronizer.getAccountsBalances()[accountIndex])?.unshielded ?? .zero XCTAssertEqual(initialTransparentBalance, .zero) @@ -177,7 +177,7 @@ class ShieldFundsTests: ZcashTestCase { // at this point the balance should be zero for shielded, then zero verified transparent funds // and 10000 zatoshi of total (not verified) transparent funds. - let tFundsDetectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero + let tFundsDetectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.unshielded ?? .zero XCTAssertEqual(tFundsDetectedBalance, Zatoshi(10000)) @@ -206,7 +206,7 @@ class ShieldFundsTests: ZcashTestCase { await fulfillment(of: [tFundsConfirmationSyncExpectation], timeout: 5) // the transparent funds should be 10000 zatoshis both total and verified - let confirmedTFundsBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero + let confirmedTFundsBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.unshielded ?? .zero XCTAssertEqual(confirmedTFundsBalance, Zatoshi(10000)) @@ -237,13 +237,13 @@ class ShieldFundsTests: ZcashTestCase { guard shouldContinue else { return } - let postShieldingBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero + let postShieldingBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.unshielded ?? .zero // when funds are shielded the UTXOs should be marked as spend and not shown on the balance. // now balance should be zero shielded, zero transaparent. // verify that the balance has been marked as spent regardless of confirmation // FIXME: [#720] this should be zero, https://github.com/zcash/ZcashLightClientKit/issues/720 XCTAssertEqual(postShieldingBalance, Zatoshi(10000)) - var expectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero + var expectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, .zero) // 10. clear the UTXO from darksidewalletd's cache @@ -290,11 +290,11 @@ class ShieldFundsTests: ZcashTestCase { // Now it should verify that the balance has been shielded. The resulting balance should be zero // transparent funds and `10000 - fee` total shielded funds, zero verified shielded funds. - let postShieldingShieldedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero + let postShieldingShieldedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.unshielded ?? .zero XCTAssertEqual(postShieldingShieldedBalance, .zero) - expectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero + expectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, Zatoshi(9000)) // 14. proceed confirm the shielded funds by staging ten more blocks @@ -330,9 +330,9 @@ class ShieldFundsTests: ZcashTestCase { XCTAssertNotNil(clearedTransaction) - expectedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.saplingBalance.total() ?? .zero + expectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual(expectedBalance, Zatoshi(9000)) - let postShieldingConfirmationShieldedBalance = try await coordinator.synchronizer.getAccountBalance(accountIndex: accountIndex)?.unshielded ?? .zero + let postShieldingConfirmationShieldedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.unshielded ?? .zero XCTAssertEqual(postShieldingConfirmationShieldedBalance, .zero) } diff --git a/Tests/DarksideTests/SynchronizerTests.swift b/Tests/DarksideTests/SynchronizerTests.swift index 73990e1aa..088d51a5d 100644 --- a/Tests/DarksideTests/SynchronizerTests.swift +++ b/Tests/DarksideTests/SynchronizerTests.swift @@ -258,8 +258,9 @@ final class SynchronizerTests: ZcashTestCase { try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName) try coordinator.applyStaged(blockheight: 663200) - let initialVerifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero - let initialTotalBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let accountIndex = Zip32AccountIndex(0) + let initialVerifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero + let initialTotalBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero sleep(1) let firstSyncExpectation = XCTestExpectation(description: "first sync expectation") @@ -276,8 +277,8 @@ final class SynchronizerTests: ZcashTestCase { await fulfillment(of: [firstSyncExpectation], timeout: 12) - let verifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero - let totalBalance: Zatoshi = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let verifiedBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero + let totalBalance: Zatoshi = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero // 2 check that there are no unconfirmed funds XCTAssertTrue(verifiedBalance > network.constants.defaultFee()) XCTAssertEqual(verifiedBalance, totalBalance) @@ -332,8 +333,8 @@ final class SynchronizerTests: ZcashTestCase { // XCTAssertEqual(lastScannedHeight, self.birthday) // check that the balance is cleared - let expectedVerifiedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.spendableValue ?? .zero - let expectedBalance = try await coordinator.synchronizer.getAccountBalance()?.saplingBalance.total() ?? .zero + let expectedVerifiedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.spendableValue ?? .zero + let expectedBalance = try await coordinator.synchronizer.getAccountsBalances()[accountIndex]?.saplingBalance.total() ?? .zero XCTAssertEqual(initialVerifiedBalance, expectedVerifiedBalance) XCTAssertEqual(initialTotalBalance, expectedBalance) } diff --git a/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift b/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift index 22a719211..7e44e6777 100644 --- a/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift +++ b/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift @@ -638,16 +638,18 @@ class ClosureSynchronizerOfflineTests: XCTestCase { } func testGetTransparentBalanceSucceed() { + let accountIndex = Zip32AccountIndex(3) + let expectedBalance = AccountBalance(saplingBalance: .zero, orchardBalance: .zero, unshielded: Zatoshi(200)) synchronizerMock.getAccountBalanceAccountIndexClosure = { receivedAccountIndex in - XCTAssertEqual(receivedAccountIndex, Zip32AccountIndex(3)) + XCTAssertEqual(receivedAccountIndex, accountIndex) return expectedBalance } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in + synchronizer.getAccountsBalances()[accountIndex] { result in switch result { case let .success(receivedBalance): XCTAssertEqual(receivedBalance, expectedBalance) @@ -661,13 +663,15 @@ class ClosureSynchronizerOfflineTests: XCTestCase { } func testGetTransparentBalanceThrowsError() { + let accountIndex = Zip32AccountIndex(3) + synchronizerMock.getAccountBalanceAccountIndexClosure = { _ in throw "Some error" } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in + synchronizer.getAccountsBalances()[accountIndex] { result in switch result { case .success: XCTFail("Error should be thrown.") @@ -680,6 +684,8 @@ class ClosureSynchronizerOfflineTests: XCTestCase { } func testGetShieldedBalanceSucceed() { + let accountIndex = Zip32AccountIndex(3) + let expectedBalance = AccountBalance( saplingBalance: PoolBalance( @@ -697,13 +703,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase { ) synchronizerMock.getAccountBalanceAccountIndexClosure = { receivedAccountIndex in - XCTAssertEqual(receivedAccountIndex, Zip32AccountIndex(3)) + XCTAssertEqual(receivedAccountIndex, accountIndex) return expectedBalance } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in + synchronizer.getAccountsBalances()[accountIndex] { result in switch result { case let .success(receivedBalance): XCTAssertEqual(receivedBalance, expectedBalance) @@ -723,7 +729,9 @@ class ClosureSynchronizerOfflineTests: XCTestCase { let expectation = XCTestExpectation() - synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in + let accountIndex = Zip32AccountIndex(3) + + synchronizer.getAccountsBalances()[accountIndex] { result in switch result { case .success: XCTFail("Error should be thrown.") @@ -759,7 +767,8 @@ class ClosureSynchronizerOfflineTests: XCTestCase { let expectation = XCTestExpectation() - synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in + let accountIndex = Zip32AccountIndex(3) + synchronizer.getAccountsBalances()[accountIndex] { result in switch result { case let .success(receivedBalance): XCTAssertEqual(receivedBalance, expectedBalance) @@ -779,7 +788,9 @@ class ClosureSynchronizerOfflineTests: XCTestCase { let expectation = XCTestExpectation() - synchronizer.getAccountBalance(accountIndex: Zip32AccountIndex(3)) { result in + let accountIndex = Zip32AccountIndex(3) + + synchronizer.getAccountsBalances()[accountIndex] { result in switch result { case .success: XCTFail("Error should be thrown.") diff --git a/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift b/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift index 8af72d03b..b5e324937 100644 --- a/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift +++ b/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift @@ -754,18 +754,18 @@ class CombineSynchronizerOfflineTests: XCTestCase { } func testGetTransparentBalanceSucceed() { - let testAccount = Account(3) + let accountIndex = Zip32AccountIndex(3) let expectedBalance = AccountBalance(saplingBalance: .zero, orchardBalance: .zero, unshielded: Zatoshi(100)) - synchronizerMock.getAccountBalanceAccountClosure = { receivedAccount in - XCTAssertEqual(receivedAccount, testAccount) + synchronizerMock.getAccountsBalancesClosure = { receivedAccount in + XCTAssertEqual(receivedAccount, accountIndex) return expectedBalance } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(account: testAccount) + synchronizer.getAccountsBalances()[accountIndex] .sink( receiveCompletion: { result in switch result { @@ -785,15 +785,15 @@ class CombineSynchronizerOfflineTests: XCTestCase { } func testGetTransparentBalanceThrowsError() { - let testAccount = Account(3) + let accountIndex = Zip32AccountIndex(3) - synchronizerMock.getAccountBalanceAccountClosure = { _ in + synchronizerMock.getAccountsBalancesClosure = { _ in throw "Some error" } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(account: testAccount) + synchronizer.getAccountsBalances()[accountIndex] .sink( receiveCompletion: { result in switch result { @@ -813,7 +813,7 @@ class CombineSynchronizerOfflineTests: XCTestCase { } func testGetShieldedBalanceSucceed() { - let testAccount = Account(3) + let accountIndex = Zip32AccountIndex(3) let expectedBalance = AccountBalance( saplingBalance: @@ -831,14 +831,14 @@ class CombineSynchronizerOfflineTests: XCTestCase { unshielded: .zero ) - synchronizerMock.getAccountBalanceAccountClosure = { receivedAccount in - XCTAssertEqual(receivedAccount, testAccount) + synchronizerMock.getAccountsBalancesClosure = { receivedAccount in + XCTAssertEqual(receivedAccount, accountIndex) return expectedBalance } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(account: testAccount) + synchronizer.getAccountsBalances()[accountIndex] .sink( receiveCompletion: { result in switch result { @@ -858,13 +858,14 @@ class CombineSynchronizerOfflineTests: XCTestCase { } func testGetShieldedBalanceThrowsError() { - synchronizerMock.getAccountBalanceAccountClosure = { _ in + synchronizerMock.getAccountsBalancesClosure = { _ in throw "Some error" } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(account: Account(3)) + let accountIndex = Zip32AccountIndex(3) + synchronizer.getAccountsBalances()[accountIndex] .sink( receiveCompletion: { result in switch result { @@ -884,7 +885,7 @@ class CombineSynchronizerOfflineTests: XCTestCase { } func testGetShieldedVerifiedBalanceSucceed() { - let testAcount = Account(3) + let accountIndex = Zip32AccountIndex(3) let expectedBalance = AccountBalance( saplingBalance: @@ -902,14 +903,14 @@ class CombineSynchronizerOfflineTests: XCTestCase { unshielded: .zero ) - synchronizerMock.getAccountBalanceAccountClosure = { receivedAccount in - XCTAssertEqual(receivedAccount, testAcount) + synchronizerMock.getAccountsBalancesClosure = { receivedAccount in + XCTAssertEqual(receivedAccount, accountIndex) return expectedBalance } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(account: testAcount) + synchronizer.getAccountsBalances()[accountIndex] .sink( receiveCompletion: { result in switch result { @@ -929,13 +930,14 @@ class CombineSynchronizerOfflineTests: XCTestCase { } func testGetShieldedVerifiedBalanceThrowsError() { - synchronizerMock.getAccountBalanceAccountClosure = { _ in + synchronizerMock.getAccountsBalancesClosure = { _ in throw "Some error" } let expectation = XCTestExpectation() - synchronizer.getAccountBalance(account: Account(3)) + let accountIndex = Zip32AccountIndex(3) + synchronizer.getAccountsBalances()[accountIndex] .sink( receiveCompletion: { result in switch result { diff --git a/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift b/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift index baebb4a38..cab2775d4 100644 --- a/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift +++ b/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift @@ -1289,21 +1289,19 @@ class SaplingParametersHandlerMock: SaplingParametersHandler { // MARK: - handleIfNeeded - var handleIfNeededAccountIndexThrowableError: Error? - var handleIfNeededAccountIndexCallsCount = 0 - var handleIfNeededAccountIndexCalled: Bool { - return handleIfNeededAccountIndexCallsCount > 0 + var handleIfNeededThrowableError: Error? + var handleIfNeededCallsCount = 0 + var handleIfNeededCalled: Bool { + return handleIfNeededCallsCount > 0 } - var handleIfNeededAccountIndexReceivedAccountIndex: Zip32AccountIndex? - var handleIfNeededAccountIndexClosure: ((Zip32AccountIndex) async throws -> Void)? + var handleIfNeededClosure: (() async throws -> Void)? - func handleIfNeeded(accountIndex: Zip32AccountIndex) async throws { - if let error = handleIfNeededAccountIndexThrowableError { + func handleIfNeeded() async throws { + if let error = handleIfNeededThrowableError { throw error } - handleIfNeededAccountIndexCallsCount += 1 - handleIfNeededAccountIndexReceivedAccountIndex = accountIndex - try await handleIfNeededAccountIndexClosure!(accountIndex) + handleIfNeededCallsCount += 1 + try await handleIfNeededClosure!() } } @@ -1800,27 +1798,25 @@ class SynchronizerMock: Synchronizer { } } - // MARK: - getAccountBalance + // MARK: - getAccountsBalances - var getAccountBalanceAccountIndexThrowableError: Error? - var getAccountBalanceAccountIndexCallsCount = 0 - var getAccountBalanceAccountIndexCalled: Bool { - return getAccountBalanceAccountIndexCallsCount > 0 + var getAccountsBalancesThrowableError: Error? + var getAccountsBalancesCallsCount = 0 + var getAccountsBalancesCalled: Bool { + return getAccountsBalancesCallsCount > 0 } - var getAccountBalanceAccountIndexReceivedAccountIndex: Zip32AccountIndex? - var getAccountBalanceAccountIndexReturnValue: AccountBalance? - var getAccountBalanceAccountIndexClosure: ((Zip32AccountIndex) async throws -> AccountBalance?)? + var getAccountsBalancesReturnValue: [Zip32AccountIndex: AccountBalance]! + var getAccountsBalancesClosure: (() async throws -> [Zip32AccountIndex: AccountBalance])? - func getAccountBalance(accountIndex: Zip32AccountIndex) async throws -> AccountBalance? { - if let error = getAccountBalanceAccountIndexThrowableError { + func getAccountsBalances() async throws -> [Zip32AccountIndex: AccountBalance] { + if let error = getAccountsBalancesThrowableError { throw error } - getAccountBalanceAccountIndexCallsCount += 1 - getAccountBalanceAccountIndexReceivedAccountIndex = accountIndex - if let closure = getAccountBalanceAccountIndexClosure { - return try await closure(accountIndex) + getAccountsBalancesCallsCount += 1 + if let closure = getAccountsBalancesClosure { + return try await closure() } else { - return getAccountBalanceAccountIndexReturnValue + return getAccountsBalancesReturnValue } } From db3a4b905f842f3818f2aa3551ef506130d7e491 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Tue, 3 Dec 2024 18:14:11 +0100 Subject: [PATCH 2/2] getWalletSummary out of the loop - Updated the code to not call getWalletSummary() with each loop iteration --- .../Block/SaplingParameters/SaplingParametersHandler.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift b/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift index 2200bb2eb..16d2c9a4b 100644 --- a/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift +++ b/Sources/ZcashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift @@ -32,13 +32,12 @@ extension SaplingParametersHandlerImpl: SaplingParametersHandler { var totalSaplingBalanceTrigger = false var totalTransparentBalanceTrigger = false - + let accountBalances = try await rustBackend.getWalletSummary()?.accountBalances + for account in accounts { let zip32AccountIndex = Zip32AccountIndex(account.index) - let totalSaplingBalance = - try await rustBackend.getWalletSummary()?.accountBalances[zip32AccountIndex]?.saplingBalance.total().amount - ?? 0 + let totalSaplingBalance = accountBalances?[zip32AccountIndex]?.saplingBalance.total().amount ?? 0 if totalSaplingBalance > 0 { totalSaplingBalanceTrigger = true