From e7621204e5cad5dcfd53719b5286b3c775c26bd3 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 6 Sep 2023 12:28:25 +0100 Subject: [PATCH] Update Rust dependencies with account birthdays and scan progress The previous FFI repo revisions no longer exist; commits between 87faf91096b7abc9d1eacb5eaf3e6d7fc2ddb9ef and here will not build. Update Rust dependencies with account birthdays and scan progress - fixes for SampleApp --- .../xcshareddata/swiftpm/Package.resolved | 2 +- .../Send/SendViewController.swift | 1 - .../SyncBlocksListViewController.swift | 5 - .../SyncBlocksViewController.swift | 1 - Package.resolved | 2 +- Package.swift | 2 +- .../Download/BlockDownloaderService.swift | 4 +- .../FSCompactBlockRepository.swift | 8 +- .../ClosureSynchronizer.swift | 1 - .../CombineSynchronizer.swift | 1 - .../Error/ZcashError.swift | 24 ++ .../Error/ZcashErrorCode.swift | 8 + Sources/ZcashLightClientKit/Initializer.swift | 24 +- .../Model/Checkpoint.swift | 12 + .../Model/ScanProgress.swift | 13 + .../Repository/CompactBlockRepository.swift | 2 +- .../Rust/ZcashRustBackend.swift | 139 ++++----- .../Rust/ZcashRustBackendWelding.swift | 56 ++-- .../ZcashLightClientKit/Synchronizer.swift | 4 +- .../Synchronizer/ClosureSDKSynchronizer.swift | 3 +- .../Synchronizer/CombineSDKSynchronizer.swift | 3 +- .../Synchronizer/SDKSynchronizer.swift | 3 +- .../DarksideTests/BlockDownloaderTests.swift | 2 +- .../TransactionEnhancementTests.swift | 15 +- Tests/NetworkTests/DownloadTests.swift | 2 +- .../ClosureSynchronizerOfflineTests.swift | 11 +- .../CombineSynchronizerOfflineTests.swift | 9 +- .../CompactBlockRepositoryTests.swift | 10 +- Tests/OfflineTests/FsBlockStorageTests.swift | 18 +- Tests/OfflineTests/NullBytesTests.swift | 67 ----- .../SynchronizerOfflineTests.swift | 8 +- Tests/OfflineTests/WalletTests.swift | 2 +- .../OfflineTests/ZcashRustBackendTests.swift | 8 +- .../PerformanceTests/SynchronizerTests.swift | 8 +- .../AutoMockable.generated.swift | 263 ++++++++++++------ Tests/TestUtils/Sourcery/generateMocks.sh | 2 +- Tests/TestUtils/Stubs.swift | 13 +- Tests/TestUtils/TestCoordinator.swift | 2 +- 38 files changed, 368 insertions(+), 390 deletions(-) create mode 100644 Sources/ZcashLightClientKit/Model/ScanProgress.swift diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index f8cef871..44b33997 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/ZcashLightClientSample/ZcashLightClientSample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -158,7 +158,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi", "state" : { - "revision" : "6a53c9e32520b46f8c70597e27b335105fabfc21" + "revision" : "1411d9a839a62523997dae113150b2beccd6b3fc" } } ], diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift index 112d6b3e..7eff58bb 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Send/SendViewController.swift @@ -45,7 +45,6 @@ class SendViewController: UIViewController { closureSynchronizer.prepare( with: DemoAppConfig.defaultSeed, - viewingKeys: [AppDelegate.shared.sharedViewingKey], walletBirthday: DemoAppConfig.defaultBirthdayHeight ) { result in loggerProxy.debug("Prepare result: \(result)") diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksListViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksListViewController.swift index a0d78ce2..c86e83a0 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksListViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksListViewController.swift @@ -67,13 +67,8 @@ class SyncBlocksListViewController: UIViewController { case .unprepared, .upToDate, .error(ZcashError.synchronizerDisconnected), .error: do { if syncStatus == .unprepared { - let derivationTool = DerivationTool(networkType: kZcashNetwork.networkType) - let spendingKey = try derivationTool.deriveUnifiedSpendingKey(seed: synchronizerData.seed, accountIndex: 0) - let viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey) - _ = try! await synchronizer.prepare( with: synchronizerData.seed, - viewingKeys: [viewingKey], walletBirthday: synchronizerData.birthday ) } diff --git a/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift b/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift index dd23da60..43d01b5f 100644 --- a/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift +++ b/Example/ZcashLightClientSample/ZcashLightClientSample/Sync Blocks/SyncBlocksViewController.swift @@ -153,7 +153,6 @@ class SyncBlocksViewController: UIViewController { do { _ = try await synchronizer.prepare( with: DemoAppConfig.defaultSeed, - viewingKeys: [AppDelegate.shared.sharedViewingKey], walletBirthday: DemoAppConfig.defaultBirthdayHeight ) } catch { diff --git a/Package.resolved b/Package.resolved index f964897f..6bcc9b97 100644 --- a/Package.resolved +++ b/Package.resolved @@ -113,7 +113,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi", "state" : { - "revision" : "6a53c9e32520b46f8c70597e27b335105fabfc21" + "revision" : "1411d9a839a62523997dae113150b2beccd6b3fc" } } ], diff --git a/Package.swift b/Package.swift index 57e97800..8adc3a10 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.14.0"), .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1"), - .package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "6a53c9e32520b46f8c70597e27b335105fabfc21") + .package(url: "https://github.com/zcash-hackworks/zcash-light-client-ffi", revision: "1411d9a839a62523997dae113150b2beccd6b3fc") ], targets: [ .target( diff --git a/Sources/ZcashLightClientKit/Block/Download/BlockDownloaderService.swift b/Sources/ZcashLightClientKit/Block/Download/BlockDownloaderService.swift index 256156e5..86775c38 100644 --- a/Sources/ZcashLightClientKit/Block/Download/BlockDownloaderService.swift +++ b/Sources/ZcashLightClientKit/Block/Download/BlockDownloaderService.swift @@ -107,8 +107,8 @@ extension BlockDownloaderServiceImpl: BlockDownloaderService { try await self.storage.rewind(to: height) } - func lastDownloadedBlockHeight() async -> BlockHeight { - await self.storage.latestHeight() + func lastDownloadedBlockHeight() async throws -> BlockHeight { + try await self.storage.latestHeight() } func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched { diff --git a/Sources/ZcashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift b/Sources/ZcashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift index 5de7488d..68c223bb 100644 --- a/Sources/ZcashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift +++ b/Sources/ZcashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift @@ -64,8 +64,8 @@ extension FSCompactBlockRepository: CompactBlockRepository { } } - func latestHeight() async -> BlockHeight { - await metadataStore.latestHeight() + func latestHeight() async throws -> BlockHeight { + try await metadataStore.latestHeight() } func write(blocks: [ZcashCompactBlock]) async throws { @@ -251,7 +251,7 @@ struct FSMetadataStore { let saveBlocksMeta: ([ZcashCompactBlock]) async throws -> Void let rewindToHeight: (BlockHeight) async throws -> Void let initFsBlockDbRoot: () async throws -> Void - let latestHeight: () async -> BlockHeight + let latestHeight: () async throws -> BlockHeight } extension FSMetadataStore { @@ -268,7 +268,7 @@ extension FSMetadataStore { } initFsBlockDbRoot: { try await rustBackend.initBlockMetadataDb() } latestHeight: { - await rustBackend.latestCachedBlockHeight() + try await rustBackend.latestCachedBlockHeight() } } } diff --git a/Sources/ZcashLightClientKit/ClosureSynchronizer.swift b/Sources/ZcashLightClientKit/ClosureSynchronizer.swift index 9a2f199e..0ef93852 100644 --- a/Sources/ZcashLightClientKit/ClosureSynchronizer.swift +++ b/Sources/ZcashLightClientKit/ClosureSynchronizer.swift @@ -24,7 +24,6 @@ public protocol ClosureSynchronizer { func prepare( with seed: [UInt8]?, - viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight, completion: @escaping (Result) -> Void ) diff --git a/Sources/ZcashLightClientKit/CombineSynchronizer.swift b/Sources/ZcashLightClientKit/CombineSynchronizer.swift index 35b86441..7db6f455 100644 --- a/Sources/ZcashLightClientKit/CombineSynchronizer.swift +++ b/Sources/ZcashLightClientKit/CombineSynchronizer.swift @@ -24,7 +24,6 @@ public protocol CombineSynchronizer { func prepare( with seed: [UInt8]?, - viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight ) -> SinglePublisher diff --git a/Sources/ZcashLightClientKit/Error/ZcashError.swift b/Sources/ZcashLightClientKit/Error/ZcashError.swift index eb853a9e..6d165be4 100644 --- a/Sources/ZcashLightClientKit/Error/ZcashError.swift +++ b/Sources/ZcashLightClientKit/Error/ZcashError.swift @@ -294,6 +294,22 @@ public enum ZcashError: Equatable, Error { /// Invalid transaction ID length when calling ZcashRustBackend.getMemo /// ZRUST0050 case rustGetMemoInvalidTxIdLength + /// Error from rust layer when calling ZcashRustBackend.getScanProgress + /// - `rustError` contains error generated by the rust layer. + /// ZRUST0051 + case rustGetScanProgress(_ rustError: String) + /// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight + /// - `rustError` contains error generated by the rust layer. + /// ZRUST0052 + case rustFullyScannedHeight(_ rustError: String) + /// Error from rust layer when calling ZcashRustBackend.maxScannedHeight + /// - `rustError` contains error generated by the rust layer. + /// ZRUST0053 + case rustMaxScannedHeight(_ rustError: String) + /// Error from rust layer when calling ZcashRustBackend.latestCachedBlockHeight + /// - `rustError` contains error generated by the rust layer. + /// ZRUST0054 + case rustLatestCachedBlockHeight(_ rustError: String) /// SQLite query failed when fetching all accounts from the database. /// - `sqliteError` is error produced by SQLite library. /// ZADAO0001 @@ -628,6 +644,10 @@ public enum ZcashError: Equatable, Error { case .rustUpdateChainTip: return "Error from rust layer when calling ZcashRustBackend.updateChainTip" case .rustSuggestScanRanges: return "Error from rust layer when calling ZcashRustBackend.suggestScanRanges" case .rustGetMemoInvalidTxIdLength: return "txId must be 32 bytes" + case .rustGetScanProgress: return "Error from rust layer when calling ZcashRustBackend.getScanProgress" + case .rustFullyScannedHeight: return "Error from rust layer when calling ZcashRustBackend.fullyScannedHeight" + case .rustMaxScannedHeight: return "Error from rust layer when calling ZcashRustBackend.maxScannedHeight" + case .rustLatestCachedBlockHeight: return "Error from rust layer when calling ZcashRustBackend.latestCachedBlockHeight" case .accountDAOGetAll: return "SQLite query failed when fetching all accounts from the database." case .accountDAOGetAllCantDecode: return "Fetched accounts from SQLite but can't decode them." case .accountDAOFindBy: return "SQLite query failed when seaching for accounts in the database." @@ -791,6 +811,10 @@ public enum ZcashError: Equatable, Error { case .rustUpdateChainTip: return .rustUpdateChainTip case .rustSuggestScanRanges: return .rustSuggestScanRanges case .rustGetMemoInvalidTxIdLength: return .rustGetMemoInvalidTxIdLength + case .rustGetScanProgress: return .rustGetScanProgress + case .rustFullyScannedHeight: return .rustFullyScannedHeight + case .rustMaxScannedHeight: return .rustMaxScannedHeight + case .rustLatestCachedBlockHeight: return .rustLatestCachedBlockHeight case .accountDAOGetAll: return .accountDAOGetAll case .accountDAOGetAllCantDecode: return .accountDAOGetAllCantDecode case .accountDAOFindBy: return .accountDAOFindBy diff --git a/Sources/ZcashLightClientKit/Error/ZcashErrorCode.swift b/Sources/ZcashLightClientKit/Error/ZcashErrorCode.swift index 60f12f20..da9c51af 100644 --- a/Sources/ZcashLightClientKit/Error/ZcashErrorCode.swift +++ b/Sources/ZcashLightClientKit/Error/ZcashErrorCode.swift @@ -163,6 +163,14 @@ public enum ZcashErrorCode: String { case rustSuggestScanRanges = "ZRUST0049" /// Invalid transaction ID length when calling ZcashRustBackend.getMemo case rustGetMemoInvalidTxIdLength = "ZRUST0050" + /// Error from rust layer when calling ZcashRustBackend.getScanProgress + case rustGetScanProgress = "ZRUST0051" + /// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight + case rustFullyScannedHeight = "ZRUST0052" + /// Error from rust layer when calling ZcashRustBackend.maxScannedHeight + case rustMaxScannedHeight = "ZRUST0053" + /// Error from rust layer when calling ZcashRustBackend.latestCachedBlockHeight + case rustLatestCachedBlockHeight = "ZRUST0054" /// SQLite query failed when fetching all accounts from the database. case accountDAOGetAll = "ZADAO0001" /// Fetched accounts from SQLite but can't decode them. diff --git a/Sources/ZcashLightClientKit/Initializer.swift b/Sources/ZcashLightClientKit/Initializer.swift index 60b3c1f7..6c1fa9b3 100644 --- a/Sources/ZcashLightClientKit/Initializer.swift +++ b/Sources/ZcashLightClientKit/Initializer.swift @@ -409,7 +409,7 @@ public class Initializer { /// - Parameter seed: ZIP-32 Seed bytes for the wallet that will be initialized /// - Throws: `InitializerError.dataDbInitFailed` if the creation of the dataDb fails /// `InitializerError.accountInitFailed` if the account table can't be initialized. - func initialize(with seed: [UInt8]?, viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight) async throws -> InitializationResult { + func initialize(with seed: [UInt8]?, walletBirthday: BlockHeight) async throws -> InitializationResult { try await storage.create() if case .seedRequired = try await rustBackend.initDataDb(seed: seed) { @@ -417,28 +417,10 @@ public class Initializer { } let checkpoint = Checkpoint.birthday(with: walletBirthday, network: network) - do { - try await rustBackend.initBlocksTable( - height: Int32(checkpoint.height), - hash: checkpoint.hash, - time: checkpoint.time, - saplingTree: checkpoint.saplingTree - ) - } catch ZcashError.rustInitBlocksTableDataDbNotEmpty { - // this is fine - } catch { - throw error - } self.walletBirthday = checkpoint.height - - do { - try await rustBackend.initAccountsTable(ufvks: viewingKeys) - } catch ZcashError.rustInitAccountsTableDataDbNotEmpty { - // this is fine - } catch { - throw error - } + + // TODO: Initialize accounts if desired. return .success } diff --git a/Sources/ZcashLightClientKit/Model/Checkpoint.swift b/Sources/ZcashLightClientKit/Model/Checkpoint.swift index 7368e0af..6e1a657f 100644 --- a/Sources/ZcashLightClientKit/Model/Checkpoint.swift +++ b/Sources/ZcashLightClientKit/Model/Checkpoint.swift @@ -71,6 +71,18 @@ extension Checkpoint: Decodable { } return height } + + public func treeState() -> TreeState { + var ret = TreeState() + ret.height = UInt64(height) + ret.hash = hash + ret.time = time + ret.saplingTree = saplingTree + if let tree = orchardTree { + ret.orchardTree = tree + } + return ret + } } public extension BlockHeight { diff --git a/Sources/ZcashLightClientKit/Model/ScanProgress.swift b/Sources/ZcashLightClientKit/Model/ScanProgress.swift new file mode 100644 index 00000000..75c7e9de --- /dev/null +++ b/Sources/ZcashLightClientKit/Model/ScanProgress.swift @@ -0,0 +1,13 @@ +// +// ScanProgress.swift +// +// +// Created by Jack Grigg on 06/09/2023. +// + +import Foundation + +struct ScanProgress { + let numerator: UInt64 + let denominator: UInt64 +} diff --git a/Sources/ZcashLightClientKit/Repository/CompactBlockRepository.swift b/Sources/ZcashLightClientKit/Repository/CompactBlockRepository.swift index 41e7c445..e6ff62e2 100644 --- a/Sources/ZcashLightClientKit/Repository/CompactBlockRepository.swift +++ b/Sources/ZcashLightClientKit/Repository/CompactBlockRepository.swift @@ -15,7 +15,7 @@ protocol CompactBlockRepository { /** Gets the height of the highest block that is currently stored. */ - func latestHeight() async -> BlockHeight + func latestHeight() async throws -> BlockHeight /** Write the given blocks to this store, which may be anything from an in-memory cache to a DB. diff --git a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift index 9551a4f7..17fd1022 100644 --- a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift +++ b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift @@ -47,12 +47,15 @@ actor ZcashRustBackend: ZcashRustBackendWelding { } } - func createAccount(seed: [UInt8]) async throws -> UnifiedSpendingKey { + func createAccount(seed: [UInt8], treeState: [UInt8], recoverUntil: UInt32?) async throws -> UnifiedSpendingKey { let ffiBinaryKeyPtr = zcashlc_create_account( dbData.0, dbData.1, seed, UInt(seed.count), + treeState, + UInt(treeState.count), + recoverUntil != nil ? Int64(recoverUntil!) : -1, networkType.networkId ) @@ -278,57 +281,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding { } } - func initAccountsTable(ufvks: [UnifiedFullViewingKey]) async throws { - var ffiUfvks: [FFIEncodedKey] = [] - for ufvk in ufvks { - guard !ufvk.encoding.containsCStringNullBytesBeforeStringEnding() else { - throw ZcashError.rustInitAccountsTableViewingKeyCotainsNullBytes - } - - guard self.keyDeriving.isValidUnifiedFullViewingKey(ufvk.encoding) else { - throw ZcashError.rustInitAccountsTableViewingKeyIsInvalid - } - - let ufvkCStr = [CChar](String(ufvk.encoding).utf8CString) - - let ufvkPtr = UnsafeMutablePointer.allocate(capacity: ufvkCStr.count) - ufvkPtr.initialize(from: ufvkCStr, count: ufvkCStr.count) - - ffiUfvks.append( - FFIEncodedKey(account_id: ufvk.account, encoding: ufvkPtr) - ) - } - - var contiguousUVKs = ContiguousArray(ffiUfvks) - - var result = false - - contiguousUVKs.withContiguousMutableStorageIfAvailable { ufvksPtr in - result = zcashlc_init_accounts_table_with_keys( - dbData.0, - dbData.1, - ufvksPtr.baseAddress, - UInt(ufvks.count), - networkType.networkId - ) - } - - defer { - for ufvk in ffiUfvks { - ufvk.encoding.deallocate() - } - } - - guard result else { - let message = lastErrorMessage(fallback: "`initAccountsTable` failed with unknown error") - if message.isDbNotEmptyErrorMessage() { - throw ZcashError.rustInitAccountsTableDataDbNotEmpty - } else { - throw ZcashError.rustInitAccountsTable(message) - } - } - } - func initBlockMetadataDb() async throws { let result = zcashlc_init_block_metadata_db(fsBlockDbRoot.0, fsBlockDbRoot.1) @@ -394,42 +346,16 @@ actor ZcashRustBackend: ZcashRustBackendWelding { } } - func initBlocksTable( - height: Int32, - hash: String, - time: UInt32, - saplingTree: String - ) async throws { - guard !hash.containsCStringNullBytesBeforeStringEnding() else { - throw ZcashError.rustInitBlocksTableHashContainsNullBytes + func latestCachedBlockHeight() async throws -> BlockHeight { + let height = zcashlc_latest_cached_block_height(fsBlockDbRoot.0, fsBlockDbRoot.1) + + if height >= 0 { + return BlockHeight(height) + } else if height == -1 { + return BlockHeight.empty() + } else { + throw ZcashError.rustLatestCachedBlockHeight(lastErrorMessage(fallback: "`latestCachedBlockHeight` failed with unknown error")) } - - guard !saplingTree.containsCStringNullBytesBeforeStringEnding() else { - throw ZcashError.rustInitBlocksTableSaplingTreeContainsNullBytes - } - - let result = zcashlc_init_blocks_table( - dbData.0, - dbData.1, - height, - [CChar](hash.utf8CString), - time, - [CChar](saplingTree.utf8CString), - networkType.networkId - ) - - guard result != 0 else { - let message = lastErrorMessage(fallback: "`initBlocksTable` failed with unknown error") - if message.isDbNotEmptyErrorMessage() { - throw ZcashError.rustInitBlocksTableDataDbNotEmpty - } else { - throw ZcashError.rustInitBlocksTable(message) - } - } - } - - func latestCachedBlockHeight() async -> BlockHeight { - return BlockHeight(zcashlc_latest_cached_block_height(fsBlockDbRoot.0, fsBlockDbRoot.1)) } func listTransparentReceivers(account: Int32) async throws -> [TransparentAddress] { @@ -565,6 +491,45 @@ actor ZcashRustBackend: ZcashRustBackendWelding { } } + func fullyScannedHeight() async throws -> BlockHeight? { + let height = zcashlc_fully_scanned_height(dbData.0, dbData.1, networkType.networkId) + + if height >= 0 { + return BlockHeight(height) + } else if height == -1 { + return nil + } else { + throw ZcashError.rustFullyScannedHeight(lastErrorMessage(fallback: "`fullyScannedHeight` failed with unknown error")) + } + } + + func maxScannedHeight() async throws -> BlockHeight? { + let height = zcashlc_max_scanned_height(dbData.0, dbData.1, networkType.networkId) + + if height >= 0 { + return BlockHeight(height) + } else if height == -1 { + return nil + } else { + throw ZcashError.rustMaxScannedHeight(lastErrorMessage(fallback: "`maxScannedHeight` failed with unknown error")) + } + } + + func getScanProgress() async throws -> ScanProgress? { + let result = zcashlc_get_scan_progress(dbData.0, dbData.1, networkType.networkId) + + if result.denominator == 0 { + switch result.numerator { + case 0: + return nil; + default: + throw ZcashError.rustGetScanProgress(lastErrorMessage(fallback: "`getScanProgress` failed with unknown error")) + } + } else { + return ScanProgress(numerator: result.numerator, denominator: result.denominator) + } + } + func suggestScanRanges() async throws -> [ScanRange] { let scanRangesPtr = zcashlc_suggest_scan_ranges(dbData.0, dbData.1, networkType.networkId) diff --git a/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift b/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift index f601dd15..c0c74062 100644 --- a/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift +++ b/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift @@ -35,9 +35,11 @@ protocol ZcashRustBackendWelding { /// have been received by the currently-available account (in order to enable /// automated account recovery). /// - parameter seed: byte array of the zip32 seed + /// - parameter treeState: byte array containing the TreeState Protobuf object for the height prior to the account birthday + /// - parameter recoverUntil: the fully-scanned height up to which the account will be treated as "being recovered" /// - Returns: The `UnifiedSpendingKey` structs for the number of accounts created /// - Throws: `rustCreateAccount`. - func createAccount(seed: [UInt8]) async throws -> UnifiedSpendingKey + func createAccount(seed: [UInt8], treeState: [UInt8], recoverUntil: UInt32?) async throws -> UnifiedSpendingKey /// Creates a transaction to the given address from the given account /// - Parameter usk: `UnifiedSpendingKey` for the account that controls the funds to be spent. @@ -101,14 +103,6 @@ protocol ZcashRustBackendWelding { /// - `rustGetTransparentBalance` if rust layer returns error. func getTransparentBalance(account: Int32) async throws -> Int64 - /// Initialize the accounts table from a set of unified full viewing keys. - /// - Note: this function should only be used when restoring an existing seed phrase. when creating a new wallet, use `createAccount()` instead. - /// - Parameter ufvks: an array of UnifiedFullViewingKeys - /// - Throws: - /// - `rustInitAccountsTableViewingKeyCotainsNullBytes` if any of the key in `ufvks` contains null bytes before end. - /// - `rustInitAccountsTableViewingKeyIsInvalid` if any of the key in `ufvks` isn't valid. - func initAccountsTable(ufvks: [UnifiedFullViewingKey]) async throws - /// Initializes the data db. This will performs any migrations needed on the sqlite file /// provided. Some migrations might need that callers provide the seed bytes. /// - Parameter seed: ZIP-32 compliant seed bytes for this wallet @@ -118,23 +112,6 @@ protocol ZcashRustBackendWelding { /// Throws `rustInitDataDb` if rust layer returns error. func initDataDb(seed: [UInt8]?) async throws -> DbInitResult - /// Initialize the blocks table from a given checkpoint (heigh, hash, time, saplingTree and networkType). - /// - parameter height: represents the block height of the given checkpoint - /// - parameter hash: hash of the merkle tree - /// - parameter time: in milliseconds from reference - /// - parameter saplingTree: hash of the sapling tree - /// - Throws: - /// - `rustInitBlocksTableHashContainsNullBytes` if `hash` contains null bytes before end. - /// - `rustInitBlocksTableSaplingTreeContainsNullBytes` if `saplingTree` contains null bytes before end. - /// - `rustInitBlocksTableDataDbNotEmpty` if data DB is not empty. - /// - `rustInitBlocksTable` if rust layer returns error. - func initBlocksTable( - height: Int32, - hash: String, - time: UInt32, - saplingTree: String - ) async throws - /// Returns a list of the transparent receivers for the diversified unified addresses that have /// been allocated for the provided account. /// - parameter account: index of the given account @@ -166,6 +143,31 @@ protocol ZcashRustBackendWelding { /// - Throws: `rustRewindCacheToHeight` if rust layer returns error. func rewindCacheToHeight(height: Int32) async throws + /// Updates the wallet's view of the blockchain. + /// + /// This method is used to provide the wallet with information about the state of the blockchain, + /// and detect any previously scanned data that needs to be re-validated before proceeding with + /// scanning. It should be called at wallet startup prior to calling `suggestScanRanges` + /// in order to provide the wallet with the information it needs to correctly prioritize scanning + /// operations. + func updateChainTip(height: Int32) async throws + + /// Returns the height to which the wallet has been fully scanned. + /// + /// This is the height for which the wallet has fully trial-decrypted this and all + /// preceding blocks beginning with the wallet's birthday height. + func fullyScannedHeight() async throws -> BlockHeight? + + /// Returns the maximum height that the wallet has scanned. + /// + /// If the wallet is fully synced, this will be equivalent to `fullyScannedHeight`; + /// otherwise the maximal scanned height is likely to be greater than the fully scanned + /// height due to the fact that out-of-order scanning can leave gaps. + func maxScannedHeight() async throws -> BlockHeight? + + /// Returns the scan progress derived from the current wallet state. + func getScanProgress() async throws -> ScanProgress? + /// Returns a list of suggested scan ranges based upon the current wallet state. /// /// This method should only be used in cases where the `CompactBlock` data that will be @@ -242,5 +244,5 @@ protocol ZcashRustBackendWelding { /// this directory is expected to contain a `/blocks` sub-directory with the blocks stored in the convened filename /// format `{height}-{hash}-block`. This directory has must be granted both write and read permissions. /// - Returns `BlockHeight` of the latest cached block or `.empty` if no blocks are stored. - func latestCachedBlockHeight() async -> BlockHeight + func latestCachedBlockHeight() async throws -> BlockHeight } diff --git a/Sources/ZcashLightClientKit/Synchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer.swift index c422fc51..65339e1b 100644 --- a/Sources/ZcashLightClientKit/Synchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer.swift @@ -131,8 +131,7 @@ public protocol Synchronizer: AnyObject { /// do not already exist). These files can be given a prefix for scenarios where multiple wallets /// /// - Parameters: - /// - seed: ZIP-32 Seed bytes for the wallet that will be initialized. - /// - viewingKeys: Viewing key derived from seed. + /// - seed: ZIP-32 Seed bytes for the wallet that will be initialized /// - walletBirthday: Birthday of wallet. /// - Throws: /// - `aliasAlreadyInUse` if the Alias used to create this instance is already used by other instance. @@ -142,7 +141,6 @@ public protocol Synchronizer: AnyObject { /// - Some other `ZcashError` thrown by lower layer of the SDK. func prepare( with seed: [UInt8]?, - viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight ) async throws -> Initializer.InitializationResult diff --git a/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift index 6921b3fd..2ac03308 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift @@ -33,12 +33,11 @@ extension ClosureSDKSynchronizer: ClosureSynchronizer { public func prepare( with seed: [UInt8]?, - viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight, completion: @escaping (Result) -> Void ) { AsyncToClosureGateway.executeThrowingAction(completion) { - return try await self.synchronizer.prepare(with: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday) + return try await self.synchronizer.prepare(with: seed, walletBirthday: walletBirthday) } } diff --git a/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift index a14e5ffc..e9bcf496 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift @@ -33,11 +33,10 @@ extension CombineSDKSynchronizer: CombineSynchronizer { public func prepare( with seed: [UInt8]?, - viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight ) -> SinglePublisher { AsyncToCombineGateway.executeThrowingAction() { - return try await self.synchronizer.prepare(with: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday) + return try await self.synchronizer.prepare(with: seed, walletBirthday: walletBirthday) } } diff --git a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift index 9db9a9bd..2464a047 100644 --- a/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift +++ b/Sources/ZcashLightClientKit/Synchronizer/SDKSynchronizer.swift @@ -127,7 +127,6 @@ public class SDKSynchronizer: Synchronizer { public func prepare( with seed: [UInt8]?, - viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight ) async throws -> Initializer.InitializationResult { guard await status == .unprepared else { return .success } @@ -138,7 +137,7 @@ public class SDKSynchronizer: Synchronizer { try await utxoRepository.initialise() - if case .seedRequired = try await self.initializer.initialize(with: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday) { + if case .seedRequired = try await self.initializer.initialize(with: seed, walletBirthday: walletBirthday) { return .seedRequired } diff --git a/Tests/DarksideTests/BlockDownloaderTests.swift b/Tests/DarksideTests/BlockDownloaderTests.swift index bf720fb7..dd96e847 100644 --- a/Tests/DarksideTests/BlockDownloaderTests.swift +++ b/Tests/DarksideTests/BlockDownloaderTests.swift @@ -76,7 +76,7 @@ class BlockDownloaderTests: XCTestCase { try await downloader.downloadBlockRange(range) // check what was 'stored' - let latestHeight = await self.storage.latestHeight() + let latestHeight = try await self.storage.latestHeight() XCTAssertEqual(latestHeight, upperRange) let resultHeight = try await self.downloader.lastDownloadedBlockHeight() diff --git a/Tests/DarksideTests/TransactionEnhancementTests.swift b/Tests/DarksideTests/TransactionEnhancementTests.swift index edf576b3..837f7aff 100644 --- a/Tests/DarksideTests/TransactionEnhancementTests.swift +++ b/Tests/DarksideTests/TransactionEnhancementTests.swift @@ -82,9 +82,13 @@ class TransactionEnhancementTests: ZcashTestCase { let viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey) do { - try await rustBackend.initAccountsTable(ufvks: [viewingKey]) + _ = try await rustBackend.createAccount( + seed: Environment.seedBytes, + treeState: birthday.treeState().serializedData(partial: false).bytes, + recoverUntil: nil + ) } catch { - XCTFail("Failed to init accounts table error: \(error)") + XCTFail("Failed to create account. Error: \(error)") return } @@ -93,13 +97,6 @@ class TransactionEnhancementTests: ZcashTestCase { return } - _ = try await rustBackend.initBlocksTable( - height: Int32(birthday.height), - hash: birthday.hash, - time: birthday.time, - saplingTree: birthday.saplingTree - ) - let service = DarksideWalletService() darksideWalletService = service diff --git a/Tests/NetworkTests/DownloadTests.swift b/Tests/NetworkTests/DownloadTests.swift index 5414ecc6..66b46859 100644 --- a/Tests/NetworkTests/DownloadTests.swift +++ b/Tests/NetworkTests/DownloadTests.swift @@ -67,7 +67,7 @@ class DownloadTests: ZcashTestCase { XCTFail("Download failed with error: \(error)") } - let latestHeight = await storage.latestHeight() + let latestHeight = try await storage.latestHeight() XCTAssertEqual(latestHeight, range.upperBound) await compactBlockProcessor.stop() diff --git a/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift b/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift index dde6dec0..ee4d1493 100644 --- a/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift +++ b/Tests/OfflineTests/ClosureSynchronizerOfflineTests.swift @@ -101,17 +101,15 @@ class ClosureSynchronizerOfflineTests: XCTestCase { } func testPrepareSucceed() throws { - let mockedViewingKey = data.viewingKey - synchronizerMock.prepareWithViewingKeysWalletBirthdayClosure = { receivedSeed, receivedViewingKeys, receivedWalletBirthday in + synchronizerMock.prepareWithWalletBirthdayClosure = { receivedSeed, receivedWalletBirthday in XCTAssertEqual(receivedSeed, self.data.seed) - XCTAssertEqual(receivedViewingKeys, [mockedViewingKey]) XCTAssertEqual(receivedWalletBirthday, self.data.birthday) return .success } let expectation = XCTestExpectation() - synchronizer.prepare(with: data.seed, viewingKeys: [mockedViewingKey], walletBirthday: data.birthday) { result in + synchronizer.prepare(with: data.seed, walletBirthday: data.birthday) { result in switch result { case let .success(status): XCTAssertEqual(status, .success) @@ -125,14 +123,13 @@ class ClosureSynchronizerOfflineTests: XCTestCase { } func testPrepareThrowsError() throws { - let mockedViewingKey = data.viewingKey - synchronizerMock.prepareWithViewingKeysWalletBirthdayClosure = { _, _, _ in + synchronizerMock.prepareWithWalletBirthdayClosure = { _, _ in throw "Some error" } let expectation = XCTestExpectation() - synchronizer.prepare(with: data.seed, viewingKeys: [mockedViewingKey], walletBirthday: data.birthday) { result in + synchronizer.prepare(with: data.seed, walletBirthday: data.birthday) { result in switch result { case .success: XCTFail("Error should be thrown.") diff --git a/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift b/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift index a2e6ed5c..64038894 100644 --- a/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift +++ b/Tests/OfflineTests/CombineSynchronizerOfflineTests.swift @@ -102,16 +102,15 @@ class CombineSynchronizerOfflineTests: XCTestCase { func testPrepareSucceed() throws { let mockedViewingKey = self.data.viewingKey - synchronizerMock.prepareWithViewingKeysWalletBirthdayClosure = { receivedSeed, receivedViewingKeys, receivedWalletBirthday in + synchronizerMock.prepareWithWalletBirthdayClosure = { receivedSeed, receivedWalletBirthday in XCTAssertEqual(receivedSeed, self.data.seed) - XCTAssertEqual(receivedViewingKeys, [mockedViewingKey]) XCTAssertEqual(receivedWalletBirthday, self.data.birthday) return .success } let expectation = XCTestExpectation() - synchronizer.prepare(with: data.seed, viewingKeys: [mockedViewingKey], walletBirthday: data.birthday) + synchronizer.prepare(with: data.seed, walletBirthday: data.birthday) .sink( receiveCompletion: { result in switch result { @@ -132,13 +131,13 @@ class CombineSynchronizerOfflineTests: XCTestCase { func testPrepareThrowsError() throws { let mockedViewingKey = self.data.viewingKey - synchronizerMock.prepareWithViewingKeysWalletBirthdayClosure = { _, _, _ in + synchronizerMock.prepareWithWalletBirthdayClosure = { _, _ in throw "Some error" } let expectation = XCTestExpectation() - synchronizer.prepare(with: data.seed, viewingKeys: [mockedViewingKey], walletBirthday: data.birthday) + synchronizer.prepare(with: data.seed, walletBirthday: data.birthday) .sink( receiveCompletion: { result in switch result { diff --git a/Tests/OfflineTests/CompactBlockRepositoryTests.swift b/Tests/OfflineTests/CompactBlockRepositoryTests.swift index 1341d770..5547023c 100644 --- a/Tests/OfflineTests/CompactBlockRepositoryTests.swift +++ b/Tests/OfflineTests/CompactBlockRepositoryTests.swift @@ -41,7 +41,7 @@ class CompactBlockRepositoryTests: ZcashTestCase { try await compactBlockRepository.create() - let latestHeight = await compactBlockRepository.latestHeight() + let latestHeight = try await compactBlockRepository.latestHeight() XCTAssertEqual(latestHeight, BlockHeight.empty()) } @@ -60,14 +60,14 @@ class CompactBlockRepositoryTests: ZcashTestCase { try await compactBlockRepository.create() - let initialHeight = await compactBlockRepository.latestHeight() + let initialHeight = try await compactBlockRepository.latestHeight() let startHeight = self.network.constants.saplingActivationHeight let blockCount = Int(1_000) let finalHeight = startHeight + blockCount try await TestDbBuilder.seed(db: compactBlockRepository, with: startHeight...finalHeight) - let latestHeight = await compactBlockRepository.latestHeight() + let latestHeight = try await compactBlockRepository.latestHeight() XCTAssertNotEqual(initialHeight, latestHeight) XCTAssertEqual(latestHeight, finalHeight) } @@ -94,7 +94,7 @@ class CompactBlockRepositoryTests: ZcashTestCase { } try await compactBlockRepository.write(blocks: [block]) - let result = await compactBlockRepository.latestHeight() + let result = try await compactBlockRepository.latestHeight() XCTAssertEqual(result, expectedHeight) } @@ -121,7 +121,7 @@ class CompactBlockRepositoryTests: ZcashTestCase { let rewindHeight = BlockHeight(finalHeight - 233) try await compactBlockRepository.rewind(to: rewindHeight) - let latestHeight = await compactBlockRepository.latestHeight() + let latestHeight = try await compactBlockRepository.latestHeight() XCTAssertEqual(latestHeight, rewindHeight) } } diff --git a/Tests/OfflineTests/FsBlockStorageTests.swift b/Tests/OfflineTests/FsBlockStorageTests.swift index 67299002..a5e8f3c4 100644 --- a/Tests/OfflineTests/FsBlockStorageTests.swift +++ b/Tests/OfflineTests/FsBlockStorageTests.swift @@ -34,7 +34,7 @@ final class FsBlockStorageTests: ZcashTestCase { try await emptyCache.create() - let latestHeight = await emptyCache.latestHeight() + let latestHeight = try await emptyCache.latestHeight() XCTAssertEqual(latestHeight, .empty()) } @@ -180,7 +180,7 @@ final class FsBlockStorageTests: ZcashTestCase { try await freshCache.write(blocks: fakeBlocks) - let latestHeight = await freshCache.latestHeight() + let latestHeight = try await freshCache.latestHeight() XCTAssertEqual(latestHeight, 2000) } @@ -292,12 +292,12 @@ final class FsBlockStorageTests: ZcashTestCase { } try await fsBlockCache.write(blocks: stubBlocks) - var latestHeight = await fsBlockCache.latestHeight() + var latestHeight = try await fsBlockCache.latestHeight() XCTAssertEqual(latestHeight, 1010) try await fsBlockCache.clear() - latestHeight = await fsBlockCache.latestHeight() + latestHeight = try await fsBlockCache.latestHeight() XCTAssertEqual(latestHeight, .empty()) } @@ -332,7 +332,7 @@ final class FsBlockStorageTests: ZcashTestCase { try await realCache.write(blocks: sandblastedBlocks) - let latestHeight = await realCache.latestHeight() + let latestHeight = try await realCache.latestHeight() XCTAssertEqual(latestHeight, 19) } @@ -390,20 +390,20 @@ final class FsBlockStorageTests: ZcashTestCase { XCTAssertLessThan(timePassed, 0.5) - let latestHeight = await realCache.latestHeight() + let latestHeight = try await realCache.latestHeight() XCTAssertEqual(latestHeight, 19) try await realCache.rewind(to: 14) - let rewoundHeight = await realCache.latestHeight() + let rewoundHeight = try await realCache.latestHeight() XCTAssertEqual(rewoundHeight, 14) let blockSlice = [ZcashCompactBlock](sandblastedBlocks[5...]) try await realCache.write(blocks: blockSlice) - let newLatestHeight = await realCache.latestHeight() + let newLatestHeight = try await realCache.latestHeight() XCTAssertEqual(newLatestHeight, 19) } @@ -480,7 +480,7 @@ final class FsBlockStorageTests: ZcashTestCase { try await freshCache.write(blocks: fakeBlocks) let endTime = Date() - let latestHeight = await freshCache.latestHeight() + let latestHeight = try await freshCache.latestHeight() XCTAssertEqual(latestHeight, 2000) diff --git a/Tests/OfflineTests/NullBytesTests.swift b/Tests/OfflineTests/NullBytesTests.swift index deaf8ccd..2a5c5fea 100644 --- a/Tests/OfflineTests/NullBytesTests.swift +++ b/Tests/OfflineTests/NullBytesTests.swift @@ -27,74 +27,7 @@ class NullBytesTests: XCTestCase { XCTAssertFalse(DerivationTool(networkType: networkType).isValidTransparentAddress(tAddrWithNullBytes)) } - - func testInitAccountTableNullBytes() async throws { - let wrongHash = "000000000\015c597fab53f\058b9e1ededbe8bd83ca0203788e2039eceeb0d65ca6" - let goodHash = "00000000015c597fab53f58b9e1ededbe8bd83ca0203788e2039eceeb0d65ca6" - let time: UInt32 = 1582235356 - let height: Int32 = 735000 - let wrongTree = """ - 0161f2ff97ff6ac6a90f9bce76c11710460f4944d8695aecc7dc99e34cad0131040011015325b185e23e82562db27817be996ffade9597181244f67efc40561aeb9dde1101dae\ - ffadc9e38f755bcb55a847a1278518a0ba4a2ef33b2fe01bbb3eb242ab0070000000000011c51f9077e3f7e28e8e337eaf4bb99b41acbc853a37dcc1e172467a1c919fe410001\ - 0bb1f55481b2268ef31997dc0fb6b48a530bc17870220f156d832326c433eb0a010b3768d3bf7868a67823e022f49be67982d0588e7041c498a756024\0750065a4a0001a9e1b\ - f4bccb48b14b544e770f21d48f2d3ad8d6ca54eccc92f60634e3078eb48013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49\ - fb934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260 - """ - - let goodTree = """ - 0161f2ff97ff6ac6a90f9bce76c11710460f4944d8695aecc7dc99e34cad0131040011015325b185e23e82562db27817be996ffade9597181244f67efc40561aeb9dde1101dae\ - ffadc9e38f755bcb55a847a1278518a0ba4a2ef33b2fe01bbb3eb242ab0070000000000011c51f9077e3f7e28e8e337eaf4bb99b41acbc853a37dcc1e172467a1c919fe410001\ - 0bb1f55481b2268ef31997dc0fb6b48a530bc17870220f156d832326c433eb0a010b3768d3bf7868a67823e022f49be67982d0588e7041c498a756024750065a4a0001a9e1bf4\ - bccb48b14b544e770f21d48f2d3ad8d6ca54eccc92f60634e3078eb48013a1f7fb005388ac6f04099b647ed85d8b025d8ae4b178c2376b473b121b8c052000001d2ea556f49fb\ - 934dc76f087935a5c07788000b4e3aae24883adfec51b5f4d260 - """ - - let rustBackend = ZcashRustBackend.makeForTests( - dbData: try! __dataDbURL(), - fsBlockDbRoot: Environment.uniqueTestTempDirectory, - networkType: networkType - ) - - do { - _ = try await rustBackend.initBlocksTable( - height: height, - hash: wrongHash, - time: time, - saplingTree: goodTree - ) - XCTFail("InitBlocksTable with Null bytes on hash string should have failed") - } catch { - guard let rustError = error as? ZcashError else { - XCTFail("Expected ZcashError") - return - } - - if rustError.code != .rustInitBlocksTableHashContainsNullBytes { - XCTFail("expected error code \(ZcashError.rustInitBlocksTableHashContainsNullBytes.code.rawValue) and got error \(rustError)") - } - } - - do { - try await rustBackend.initBlocksTable( - height: height, - hash: goodHash, - time: time, - saplingTree: wrongTree - ) - XCTFail("InitBlocksTable with Null bytes on saplingTree string should have failed") - } catch { - guard let rustError = error as? ZcashError else { - XCTFail("Expected ZcashError") - return - } - - if rustError.code != .rustInitBlocksTableSaplingTreeContainsNullBytes { - XCTFail("expected error code \(ZcashError.rustInitBlocksTableSaplingTreeContainsNullBytes.code.rawValue) and got error \(rustError)") - } - } - } - // TODO: [#716] fix, https://github.com/zcash/ZcashLightClientKit/issues/716 func testderiveExtendedFullViewingKeyWithNullBytes() throws { // let wrongSpendingKeys = SaplingExtendedSpendingKey(validatedEncoding: "secret-extended-key-main1qw28psv0qqqqpqr2ru0kss5equx6h0xjsuk5299xrsgdqnhe0cknkl8uqff34prwkyuegyhh5d4rdr8025nl7e0hm8r2txx3fuea5mq\0uy3wnsr9tlajsg4wwvw0xcfk8357k4h850rgj72kt4rx3fjdz99zs9f4neda35cq8tn3848yyvlg4w38gx75cyv9jdpve77x9eq6rtl6d9qyh8det4edevlnc70tg5kse670x50764gzhy60dta0yv3wsd4fsuaz686lgszc7nc9vv") // this spending key corresponds to the "demo app reference seed" diff --git a/Tests/OfflineTests/SynchronizerOfflineTests.swift b/Tests/OfflineTests/SynchronizerOfflineTests.swift index c7be3969..26142d89 100644 --- a/Tests/OfflineTests/SynchronizerOfflineTests.swift +++ b/Tests/OfflineTests/SynchronizerOfflineTests.swift @@ -304,13 +304,7 @@ class SynchronizerOfflineTests: ZcashTestCase { let synchronizer = SDKSynchronizer(initializer: initializer) do { - let derivationTool = DerivationTool(networkType: network.networkType) - let spendingKey = try derivationTool.deriveUnifiedSpendingKey( - seed: Environment.seedBytes, - accountIndex: 0 - ) - let viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey) - _ = try await synchronizer.prepare(with: Environment.seedBytes, viewingKeys: [viewingKey], walletBirthday: 123000) + _ = try await synchronizer.prepare(with: Environment.seedBytes, walletBirthday: 123000) XCTFail("Failure of prepare is expected.") } catch { if let error = error as? ZcashError, case let .initializerCantUpdateURLWithAlias(failedURL) = error { diff --git a/Tests/OfflineTests/WalletTests.swift b/Tests/OfflineTests/WalletTests.swift index 641918e6..e34e5f76 100644 --- a/Tests/OfflineTests/WalletTests.swift +++ b/Tests/OfflineTests/WalletTests.swift @@ -50,7 +50,7 @@ class WalletTests: ZcashTestCase { let synchronizer = SDKSynchronizer(initializer: wallet) do { - guard case .success = try await synchronizer.prepare(with: seedData.bytes, viewingKeys: [viewingKey], walletBirthday: 663194) else { + guard case .success = try await synchronizer.prepare(with: seedData.bytes, walletBirthday: 663194) else { XCTFail("Failed to initDataDb. Expected `.success` got: `.seedRequired`") return } diff --git a/Tests/OfflineTests/ZcashRustBackendTests.swift b/Tests/OfflineTests/ZcashRustBackendTests.swift index 1304459c..58022424 100644 --- a/Tests/OfflineTests/ZcashRustBackendTests.swift +++ b/Tests/OfflineTests/ZcashRustBackendTests.swift @@ -43,6 +43,8 @@ class ZcashRustBackendTests: XCTestCase { func testInitWithShortSeedAndFail() async throws { let seed = "testreferencealice" + var treeState = TreeState() + treeState.height = 663193 // TODO: rest let dbInit = try await rustBackend.initDataDb(seed: nil) @@ -52,7 +54,7 @@ class ZcashRustBackendTests: XCTestCase { } do { - _ = try await rustBackend.createAccount(seed: Array(seed.utf8)) + _ = try await rustBackend.createAccount(seed: Array(seed.utf8), treeState: treeState.serializedData(partial: false).bytes, recoverUntil: nil) XCTFail("createAccount should fail here.") } catch { } } @@ -100,7 +102,9 @@ class ZcashRustBackendTests: XCTestCase { let initResult = try await rustBackend.initDataDb(seed: seed) XCTAssertEqual(initResult, .success) - let usk = try await rustBackend.createAccount(seed: seed) + let treeState = Checkpoint.birthday(with: 1234567, network: ZcashMainnet()).treeState() + + let usk = try await rustBackend.createAccount(seed: seed, treeState: treeState.serializedData(partial: false).bytes, recoverUntil: nil) XCTAssertEqual(usk.account, 0) let expectedReceivers = try testVector.map { diff --git a/Tests/PerformanceTests/SynchronizerTests.swift b/Tests/PerformanceTests/SynchronizerTests.swift index 0ad8b516..2824883b 100644 --- a/Tests/PerformanceTests/SynchronizerTests.swift +++ b/Tests/PerformanceTests/SynchronizerTests.swift @@ -48,17 +48,11 @@ class SynchronizerTests: ZcashTestCase { } func testHundredBlocksSync() async throws { - let derivationTool = DerivationTool(networkType: .mainnet) guard let seedData = Data(base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg==") else { XCTFail("seedData expected to be successfuly instantiated.") return } let seedBytes = [UInt8](seedData) - let spendingKey = try derivationTool.deriveUnifiedSpendingKey( - seed: seedBytes, - accountIndex: 0 - ) - let ufvk = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey) let network = ZcashNetworkBuilder.network(for: .mainnet) let endpoint = LightWalletEndpoint(address: "lightwalletd.electriccoin.co", port: 9067, secure: true) @@ -87,7 +81,7 @@ class SynchronizerTests: ZcashTestCase { guard let synchronizer else { fatalError("Synchronizer not initialized.") } synchronizer.metrics.enableMetrics() - _ = try await synchronizer.prepare(with: seedBytes, viewingKeys: [ufvk], walletBirthday: birthday) + _ = try await synchronizer.prepare(with: seedBytes, walletBirthday: birthday) let syncSyncedExpectation = XCTestExpectation(description: "synchronizerSynced Expectation") sdkSynchronizerInternalSyncStatusHandler.subscribe(to: synchronizer.stateStream, expectations: [.synced: syncSyncedExpectation]) diff --git a/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift b/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift index 1db61f80..a60727c5 100644 --- a/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift +++ b/Tests/TestUtils/Sourcery/GeneratedMocks/AutoMockable.generated.swift @@ -1,4 +1,4 @@ -// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery +// Generated using Sourcery 2.0.3 — https://github.com/krzysztofzablocki/Sourcery // DO NOT EDIT import Combine @testable import ZcashLightClientKit @@ -405,17 +405,21 @@ class CompactBlockRepositoryMock: CompactBlockRepository { // MARK: - latestHeight + var latestHeightThrowableError: Error? var latestHeightCallsCount = 0 var latestHeightCalled: Bool { return latestHeightCallsCount > 0 } var latestHeightReturnValue: BlockHeight! - var latestHeightClosure: (() async -> BlockHeight)? + var latestHeightClosure: (() async throws -> BlockHeight)? - func latestHeight() async -> BlockHeight { + func latestHeight() async throws -> BlockHeight { + if let error = latestHeightThrowableError { + throw error + } latestHeightCallsCount += 1 if let closure = latestHeightClosure { - return await closure() + return try await closure() } else { return latestHeightReturnValue } @@ -1042,25 +1046,25 @@ class SynchronizerMock: Synchronizer { // MARK: - prepare - var prepareWithViewingKeysWalletBirthdayThrowableError: Error? - var prepareWithViewingKeysWalletBirthdayCallsCount = 0 - var prepareWithViewingKeysWalletBirthdayCalled: Bool { - return prepareWithViewingKeysWalletBirthdayCallsCount > 0 + var prepareWithWalletBirthdayThrowableError: Error? + var prepareWithWalletBirthdayCallsCount = 0 + var prepareWithWalletBirthdayCalled: Bool { + return prepareWithWalletBirthdayCallsCount > 0 } - var prepareWithViewingKeysWalletBirthdayReceivedArguments: (seed: [UInt8]?, viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight)? - var prepareWithViewingKeysWalletBirthdayReturnValue: Initializer.InitializationResult! - var prepareWithViewingKeysWalletBirthdayClosure: (([UInt8]?, [UnifiedFullViewingKey], BlockHeight) async throws -> Initializer.InitializationResult)? + var prepareWithWalletBirthdayReceivedArguments: (seed: [UInt8]?, walletBirthday: BlockHeight)? + var prepareWithWalletBirthdayReturnValue: Initializer.InitializationResult! + var prepareWithWalletBirthdayClosure: (([UInt8]?, BlockHeight) async throws -> Initializer.InitializationResult)? - func prepare(with seed: [UInt8]?, viewingKeys: [UnifiedFullViewingKey], walletBirthday: BlockHeight) async throws -> Initializer.InitializationResult { - if let error = prepareWithViewingKeysWalletBirthdayThrowableError { + func prepare(with seed: [UInt8]?, walletBirthday: BlockHeight) async throws -> Initializer.InitializationResult { + if let error = prepareWithWalletBirthdayThrowableError { throw error } - prepareWithViewingKeysWalletBirthdayCallsCount += 1 - prepareWithViewingKeysWalletBirthdayReceivedArguments = (seed: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday) - if let closure = prepareWithViewingKeysWalletBirthdayClosure { - return try await closure(seed, viewingKeys, walletBirthday) + prepareWithWalletBirthdayCallsCount += 1 + prepareWithWalletBirthdayReceivedArguments = (seed: seed, walletBirthday: walletBirthday) + if let closure = prepareWithWalletBirthdayClosure { + return try await closure(seed, walletBirthday) } else { - return prepareWithViewingKeysWalletBirthdayReturnValue + return prepareWithWalletBirthdayReturnValue } } @@ -2055,34 +2059,34 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding { // MARK: - createAccount - var createAccountSeedThrowableError: Error? - func setCreateAccountSeedThrowableError(_ param: Error?) async { - createAccountSeedThrowableError = param + var createAccountSeedTreeStateRecoverUntilThrowableError: Error? + func setCreateAccountSeedTreeStateRecoverUntilThrowableError(_ param: Error?) async { + createAccountSeedTreeStateRecoverUntilThrowableError = param } - var createAccountSeedCallsCount = 0 - var createAccountSeedCalled: Bool { - return createAccountSeedCallsCount > 0 + var createAccountSeedTreeStateRecoverUntilCallsCount = 0 + var createAccountSeedTreeStateRecoverUntilCalled: Bool { + return createAccountSeedTreeStateRecoverUntilCallsCount > 0 } - var createAccountSeedReceivedSeed: [UInt8]? - var createAccountSeedReturnValue: UnifiedSpendingKey! - func setCreateAccountSeedReturnValue(_ param: UnifiedSpendingKey) async { - createAccountSeedReturnValue = param + var createAccountSeedTreeStateRecoverUntilReceivedArguments: (seed: [UInt8], treeState: [UInt8], recoverUntil: UInt32?)? + var createAccountSeedTreeStateRecoverUntilReturnValue: UnifiedSpendingKey! + func setCreateAccountSeedTreeStateRecoverUntilReturnValue(_ param: UnifiedSpendingKey) async { + createAccountSeedTreeStateRecoverUntilReturnValue = param } - var createAccountSeedClosure: (([UInt8]) async throws -> UnifiedSpendingKey)? - func setCreateAccountSeedClosure(_ param: (([UInt8]) async throws -> UnifiedSpendingKey)?) async { - createAccountSeedClosure = param + var createAccountSeedTreeStateRecoverUntilClosure: (([UInt8], [UInt8], UInt32?) async throws -> UnifiedSpendingKey)? + func setCreateAccountSeedTreeStateRecoverUntilClosure(_ param: (([UInt8], [UInt8], UInt32?) async throws -> UnifiedSpendingKey)?) async { + createAccountSeedTreeStateRecoverUntilClosure = param } - func createAccount(seed: [UInt8]) async throws -> UnifiedSpendingKey { - if let error = createAccountSeedThrowableError { + func createAccount(seed: [UInt8], treeState: [UInt8], recoverUntil: UInt32?) async throws -> UnifiedSpendingKey { + if let error = createAccountSeedTreeStateRecoverUntilThrowableError { throw error } - createAccountSeedCallsCount += 1 - createAccountSeedReceivedSeed = seed - if let closure = createAccountSeedClosure { - return try await closure(seed) + createAccountSeedTreeStateRecoverUntilCallsCount += 1 + createAccountSeedTreeStateRecoverUntilReceivedArguments = (seed: seed, treeState: treeState, recoverUntil: recoverUntil) + if let closure = createAccountSeedTreeStateRecoverUntilClosure { + return try await closure(seed, treeState, recoverUntil) } else { - return createAccountSeedReturnValue + return createAccountSeedTreeStateRecoverUntilReturnValue } } @@ -2342,31 +2346,6 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding { } } - // MARK: - initAccountsTable - - var initAccountsTableUfvksThrowableError: Error? - func setInitAccountsTableUfvksThrowableError(_ param: Error?) async { - initAccountsTableUfvksThrowableError = param - } - var initAccountsTableUfvksCallsCount = 0 - var initAccountsTableUfvksCalled: Bool { - return initAccountsTableUfvksCallsCount > 0 - } - var initAccountsTableUfvksReceivedUfvks: [UnifiedFullViewingKey]? - var initAccountsTableUfvksClosure: (([UnifiedFullViewingKey]) async throws -> Void)? - func setInitAccountsTableUfvksClosure(_ param: (([UnifiedFullViewingKey]) async throws -> Void)?) async { - initAccountsTableUfvksClosure = param - } - - func initAccountsTable(ufvks: [UnifiedFullViewingKey]) async throws { - if let error = initAccountsTableUfvksThrowableError { - throw error - } - initAccountsTableUfvksCallsCount += 1 - initAccountsTableUfvksReceivedUfvks = ufvks - try await initAccountsTableUfvksClosure!(ufvks) - } - // MARK: - initDataDb var initDataDbSeedThrowableError: Error? @@ -2400,31 +2379,6 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding { } } - // MARK: - initBlocksTable - - var initBlocksTableHeightHashTimeSaplingTreeThrowableError: Error? - func setInitBlocksTableHeightHashTimeSaplingTreeThrowableError(_ param: Error?) async { - initBlocksTableHeightHashTimeSaplingTreeThrowableError = param - } - var initBlocksTableHeightHashTimeSaplingTreeCallsCount = 0 - var initBlocksTableHeightHashTimeSaplingTreeCalled: Bool { - return initBlocksTableHeightHashTimeSaplingTreeCallsCount > 0 - } - var initBlocksTableHeightHashTimeSaplingTreeReceivedArguments: (height: Int32, hash: String, time: UInt32, saplingTree: String)? - var initBlocksTableHeightHashTimeSaplingTreeClosure: ((Int32, String, UInt32, String) async throws -> Void)? - func setInitBlocksTableHeightHashTimeSaplingTreeClosure(_ param: ((Int32, String, UInt32, String) async throws -> Void)?) async { - initBlocksTableHeightHashTimeSaplingTreeClosure = param - } - - func initBlocksTable(height: Int32, hash: String, time: UInt32, saplingTree: String) async throws { - if let error = initBlocksTableHeightHashTimeSaplingTreeThrowableError { - throw error - } - initBlocksTableHeightHashTimeSaplingTreeCallsCount += 1 - initBlocksTableHeightHashTimeSaplingTreeReceivedArguments = (height: height, hash: hash, time: time, saplingTree: saplingTree) - try await initBlocksTableHeightHashTimeSaplingTreeClosure!(height, hash, time, saplingTree) - } - // MARK: - listTransparentReceivers var listTransparentReceiversAccountThrowableError: Error? @@ -2574,6 +2528,124 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding { try await rewindCacheToHeightHeightClosure!(height) } + // MARK: - updateChainTip + + var updateChainTipHeightThrowableError: Error? + func setUpdateChainTipHeightThrowableError(_ param: Error?) async { + updateChainTipHeightThrowableError = param + } + var updateChainTipHeightCallsCount = 0 + var updateChainTipHeightCalled: Bool { + return updateChainTipHeightCallsCount > 0 + } + var updateChainTipHeightReceivedHeight: Int32? + var updateChainTipHeightClosure: ((Int32) async throws -> Void)? + func setUpdateChainTipHeightClosure(_ param: ((Int32) async throws -> Void)?) async { + updateChainTipHeightClosure = param + } + + func updateChainTip(height: Int32) async throws { + if let error = updateChainTipHeightThrowableError { + throw error + } + updateChainTipHeightCallsCount += 1 + updateChainTipHeightReceivedHeight = height + try await updateChainTipHeightClosure!(height) + } + + // MARK: - fullyScannedHeight + + var fullyScannedHeightThrowableError: Error? + func setFullyScannedHeightThrowableError(_ param: Error?) async { + fullyScannedHeightThrowableError = param + } + var fullyScannedHeightCallsCount = 0 + var fullyScannedHeightCalled: Bool { + return fullyScannedHeightCallsCount > 0 + } + var fullyScannedHeightReturnValue: BlockHeight? + func setFullyScannedHeightReturnValue(_ param: BlockHeight?) async { + fullyScannedHeightReturnValue = param + } + var fullyScannedHeightClosure: (() async throws -> BlockHeight?)? + func setFullyScannedHeightClosure(_ param: (() async throws -> BlockHeight?)?) async { + fullyScannedHeightClosure = param + } + + func fullyScannedHeight() async throws -> BlockHeight? { + if let error = fullyScannedHeightThrowableError { + throw error + } + fullyScannedHeightCallsCount += 1 + if let closure = fullyScannedHeightClosure { + return try await closure() + } else { + return fullyScannedHeightReturnValue + } + } + + // MARK: - maxScannedHeight + + var maxScannedHeightThrowableError: Error? + func setMaxScannedHeightThrowableError(_ param: Error?) async { + maxScannedHeightThrowableError = param + } + var maxScannedHeightCallsCount = 0 + var maxScannedHeightCalled: Bool { + return maxScannedHeightCallsCount > 0 + } + var maxScannedHeightReturnValue: BlockHeight? + func setMaxScannedHeightReturnValue(_ param: BlockHeight?) async { + maxScannedHeightReturnValue = param + } + var maxScannedHeightClosure: (() async throws -> BlockHeight?)? + func setMaxScannedHeightClosure(_ param: (() async throws -> BlockHeight?)?) async { + maxScannedHeightClosure = param + } + + func maxScannedHeight() async throws -> BlockHeight? { + if let error = maxScannedHeightThrowableError { + throw error + } + maxScannedHeightCallsCount += 1 + if let closure = maxScannedHeightClosure { + return try await closure() + } else { + return maxScannedHeightReturnValue + } + } + + // MARK: - getScanProgress + + var getScanProgressThrowableError: Error? + func setGetScanProgressThrowableError(_ param: Error?) async { + getScanProgressThrowableError = param + } + var getScanProgressCallsCount = 0 + var getScanProgressCalled: Bool { + return getScanProgressCallsCount > 0 + } + var getScanProgressReturnValue: ScanProgress? + func setGetScanProgressReturnValue(_ param: ScanProgress?) async { + getScanProgressReturnValue = param + } + var getScanProgressClosure: (() async throws -> ScanProgress?)? + func setGetScanProgressClosure(_ param: (() async throws -> ScanProgress?)?) async { + getScanProgressClosure = param + } + + func getScanProgress() async throws -> ScanProgress? { + if let error = getScanProgressThrowableError { + throw error + } + getScanProgressCallsCount += 1 + if let closure = getScanProgressClosure { + return try await closure() + } else { + return getScanProgressReturnValue + } + } + // MARK: - suggestScanRanges var suggestScanRangesThrowableError: Error? @@ -2745,6 +2817,10 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding { // MARK: - latestCachedBlockHeight + var latestCachedBlockHeightThrowableError: Error? + func setLatestCachedBlockHeightThrowableError(_ param: Error?) async { + latestCachedBlockHeightThrowableError = param + } var latestCachedBlockHeightCallsCount = 0 var latestCachedBlockHeightCalled: Bool { return latestCachedBlockHeightCallsCount > 0 @@ -2753,15 +2829,18 @@ actor ZcashRustBackendWeldingMock: ZcashRustBackendWelding { func setLatestCachedBlockHeightReturnValue(_ param: BlockHeight) async { latestCachedBlockHeightReturnValue = param } - var latestCachedBlockHeightClosure: (() async -> BlockHeight)? - func setLatestCachedBlockHeightClosure(_ param: (() async -> BlockHeight)?) async { + var latestCachedBlockHeightClosure: (() async throws -> BlockHeight)? + func setLatestCachedBlockHeightClosure(_ param: (() async throws -> BlockHeight)?) async { latestCachedBlockHeightClosure = param } - func latestCachedBlockHeight() async -> BlockHeight { + func latestCachedBlockHeight() async throws -> BlockHeight { + if let error = latestCachedBlockHeightThrowableError { + throw error + } latestCachedBlockHeightCallsCount += 1 if let closure = latestCachedBlockHeightClosure { - return await closure() + return try await closure() } else { return latestCachedBlockHeightReturnValue } diff --git a/Tests/TestUtils/Sourcery/generateMocks.sh b/Tests/TestUtils/Sourcery/generateMocks.sh index 420b2d13..503f7af7 100755 --- a/Tests/TestUtils/Sourcery/generateMocks.sh +++ b/Tests/TestUtils/Sourcery/generateMocks.sh @@ -3,7 +3,7 @@ scriptDir=${0:a:h} cd "${scriptDir}" -sourcery_version=2.0.2 +sourcery_version=2.0.3 if which sourcery >/dev/null; then if [[ $(sourcery --version) != $sourcery_version ]]; then diff --git a/Tests/TestUtils/Stubs.swift b/Tests/TestUtils/Stubs.swift index 6d9793cd..4063dfd0 100644 --- a/Tests/TestUtils/Stubs.swift +++ b/Tests/TestUtils/Stubs.swift @@ -90,17 +90,15 @@ class RustBackendMockHelper { await rustBackendMock.setLatestCachedBlockHeightReturnValue(.empty()) await rustBackendMock.setInitBlockMetadataDbClosure() { } await rustBackendMock.setWriteBlocksMetadataBlocksClosure() { _ in } - await rustBackendMock.setInitAccountsTableUfvksClosure() { _ in } await rustBackendMock.setGetTransparentBalanceAccountReturnValue(0) await rustBackendMock.setGetVerifiedBalanceAccountReturnValue(0) await rustBackendMock.setListTransparentReceiversAccountReturnValue([]) await rustBackendMock.setGetCurrentAddressAccountThrowableError(ZcashError.rustGetCurrentAddress("mocked error")) await rustBackendMock.setGetNextAvailableAddressAccountThrowableError(ZcashError.rustGetNextAvailableAddress("mocked error")) - await rustBackendMock.setCreateAccountSeedThrowableError(ZcashError.rustInitAccountsTableViewingKeyCotainsNullBytes) + await rustBackendMock.setCreateAccountSeedTreeStateRecoverUntilThrowableError(ZcashError.rustInitAccountsTableViewingKeyCotainsNullBytes) await rustBackendMock.setGetMemoTxIdOutputIndexReturnValue(nil) await rustBackendMock.setInitDataDbSeedReturnValue(.seedRequired) await rustBackendMock.setGetNearestRewindHeightHeightReturnValue(-1) - await rustBackendMock.setInitBlocksTableHeightHashTimeSaplingTreeClosure() { _, _, _, _ in } await rustBackendMock.setPutUnspentTransparentOutputTxidIndexScriptValueHeightClosure() { _, _, _, _, _ in } await rustBackendMock.setCreateToAddressUskToValueMemoThrowableError(ZcashError.rustCreateToAddress("mocked error")) await rustBackendMock.setShieldFundsUskMemoShieldingThresholdThrowableError(ZcashError.rustShieldFunds("mocked error")) @@ -110,15 +108,6 @@ class RustBackendMockHelper { return try await rustBackend.initDataDb(seed: seed) } - await rustBackendMock.setInitBlocksTableHeightHashTimeSaplingTreeClosure() { height, hash, time, saplingTree in - try await rustBackend.initBlocksTable( - height: height, - hash: hash, - time: time, - saplingTree: saplingTree - ) - } - await rustBackendMock.setGetBalanceAccountClosure() { account in return try await rustBackend.getBalance(account: account) } diff --git a/Tests/TestUtils/TestCoordinator.swift b/Tests/TestUtils/TestCoordinator.swift index 9e1174f2..e0df83ce 100644 --- a/Tests/TestUtils/TestCoordinator.swift +++ b/Tests/TestUtils/TestCoordinator.swift @@ -110,7 +110,7 @@ class TestCoordinator { } func prepare(seed: [UInt8]) async throws -> Initializer.InitializationResult { - return try await synchronizer.prepare(with: seed, viewingKeys: [viewingKey], walletBirthday: self.birthday) + return try await synchronizer.prepare(with: seed, walletBirthday: self.birthday) } func stop() async throws {