diff --git a/Sources/ZcashLightClientKit/Initializer.swift b/Sources/ZcashLightClientKit/Initializer.swift index 085ba55e..f3ea6183 100644 --- a/Sources/ZcashLightClientKit/Initializer.swift +++ b/Sources/ZcashLightClientKit/Initializer.swift @@ -13,10 +13,9 @@ Wrapper for the Rust backend. This class basically represents all the Rust-walle capabilities and the supporting data required to exercise those abilities. */ public enum InitializerError: Error { - case cacheDbInitFailed - case dataDbInitFailed - case accountInitFailed - case falseStart + case cacheDbInitFailed(Error) + case dataDbInitFailed(Error) + case accountInitFailed(Error) case invalidViewingKey(key: String) } @@ -197,7 +196,7 @@ public class Initializer { do { try storage.createTable() } catch { - throw InitializerError.cacheDbInitFailed + throw InitializerError.cacheDbInitFailed(error) } do { @@ -205,7 +204,7 @@ public class Initializer { return .seedRequired } } catch { - throw InitializerError.dataDbInitFailed + throw InitializerError.dataDbInitFailed(error) } let checkpoint = Checkpoint.birthday(with: self.walletBirthday, network: network) @@ -221,7 +220,7 @@ public class Initializer { } catch RustWeldingError.dataDbNotEmpty { // this is fine } catch { - throw InitializerError.dataDbInitFailed + throw InitializerError.dataDbInitFailed(error) } self.walletBirthday = checkpoint.height @@ -230,19 +229,17 @@ public class Initializer { lowerBoundHeight = max(walletBirthday, lastDownloaded) do { - guard try rustBackend.initAccountsTable( + try rustBackend.initAccountsTable( dbData: dataDbURL, ufvks: viewingKeys, networkType: network.networkType - ) else { - throw rustBackend.lastError() ?? InitializerError.accountInitFailed - } + ) } catch RustWeldingError.dataDbNotEmpty { // this is fine } catch RustWeldingError.malformedStringInput { throw RustWeldingError.malformedStringInput } catch { - throw rustBackend.lastError() ?? InitializerError.accountInitFailed + throw InitializerError.accountInitFailed(error) } let migrationManager = MigrationManager( @@ -371,3 +368,19 @@ enum CompactBlockProcessorBuilder { ) } } + + +extension InitializerError: LocalizedError { + public var errorDescription: String? { + switch self { + case .invalidViewingKey: + return "The provided viewing key is invalid" + case .cacheDbInitFailed(let error): + return "cacheDb Init failed with error: \(error.localizedDescription)" + case .dataDbInitFailed(let error): + return "dataDb init failed with error: \(error.localizedDescription)" + case .accountInitFailed(let error): + return "account table init failed with error: \(error.localizedDescription)" + } + } +} diff --git a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift index 48be5c7b..65df795a 100644 --- a/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift +++ b/Sources/ZcashLightClientKit/Rust/ZcashRustBackend.swift @@ -434,7 +434,7 @@ class ZcashRustBackend: ZcashRustBackendWelding { dbData: URL, ufvks: [UnifiedFullViewingKey], networkType: NetworkType - ) throws -> Bool { + ) throws { let dbData = dbData.osStr() var ffiUfvks = [FFIEncodedKey]() @@ -470,14 +470,16 @@ class ZcashRustBackend: ZcashRustBackendWelding { networkType.networkId ) } - + defer { for ufvk in ffiUfvks { ufvk.encoding.deallocate() } } - - return result + + guard result else { + throw lastError() ?? .genericError(message: "`initAccountsTable` failed with unknown error") + } } // swiftlint:disable function_parameter_count @@ -730,3 +732,28 @@ extension UnsafeMutablePointer where Pointee == UInt8 { } } + +extension RustWeldingError: LocalizedError { + var errorDescription: String? { + switch self { + case .genericError(let message): + return "RustWeldingError generic error: \(message)" + case .dataDbInitFailed(let message): + return "`RustWeldingError.dataDbInitFailed` with message: \(message)" + case .dataDbNotEmpty: + return "`.DataDbNotEmpty`. This is usually not an error." + case .invalidInput(let message): + return "`RustWeldingError.invalidInput` with message: \(message)" + case .malformedStringInput: + return "`.malformedStringInput` Called a function with a malformed string input." + case .invalidRewind: + return "`.invalidRewind` called the rewind API with an arbitrary height that is not valid." + case .noConsensusBranchId(let branchId): + return "`.noConsensusBranchId` number \(branchId)" + case .saplingSpendParametersNotFound: + return "`.saplingSpendParametersNotFound` sapling parameters not present at specified URL" + case .unableToDeriveKeys: + return "`.unableToDeriveKeys` the requested keys could not be derived from the source provided" + } + } +} diff --git a/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift b/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift index 3f43b9b2..41ef36c0 100644 --- a/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift +++ b/Sources/ZcashLightClientKit/Rust/ZcashRustBackendWelding.swift @@ -245,7 +245,7 @@ protocol ZcashRustBackendWelding { dbData: URL, ufvks: [UnifiedFullViewingKey], networkType: NetworkType - ) throws -> Bool + ) 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. diff --git a/Tests/DarksideTests/TransactionEnhancementTests.swift b/Tests/DarksideTests/TransactionEnhancementTests.swift index 0dcfb355..aad86315 100644 --- a/Tests/DarksideTests/TransactionEnhancementTests.swift +++ b/Tests/DarksideTests/TransactionEnhancementTests.swift @@ -74,11 +74,13 @@ class TransactionEnhancementTests: XCTestCase { } ] - guard try rustBackend.initAccountsTable( - dbData: processorConfig.dataDb, - ufvks: ufvks, - networkType: network.networkType - ) else { + do { + try rustBackend.initAccountsTable( + dbData: processorConfig.dataDb, + ufvks: ufvks, + networkType: network.networkType + ) + } catch { XCTFail("Failed to init accounts table error: " + String(describing: rustBackend.getLastError())) return } diff --git a/Tests/NetworkTests/BlockScanTests.swift b/Tests/NetworkTests/BlockScanTests.swift index 77290e36..2de43c43 100644 --- a/Tests/NetworkTests/BlockScanTests.swift +++ b/Tests/NetworkTests/BlockScanTests.swift @@ -131,11 +131,13 @@ class BlockScanTests: XCTestCase { .map { try derivationTool.deriveUnifiedFullViewingKey(from: $0) } - guard try self.rustWelding.initAccountsTable( - dbData: self.dataDbURL, - ufvks: [ufvk], - networkType: network.networkType - ) else { + do { + try self.rustWelding.initAccountsTable( + dbData: self.dataDbURL, + ufvks: [ufvk], + networkType: network.networkType + ) + } catch { XCTFail("failed to init account table. error: \(self.rustWelding.getLastError() ?? "no error found")") return } diff --git a/Tests/OfflineTests/ZcashRustBackendTests.swift b/Tests/OfflineTests/ZcashRustBackendTests.swift index 067dcbd6..d4728e0b 100644 --- a/Tests/OfflineTests/ZcashRustBackendTests.swift +++ b/Tests/OfflineTests/ZcashRustBackendTests.swift @@ -71,10 +71,13 @@ class ZcashRustBackendTests: XCTestCase { .deriveFullViewingKey() ] - guard try ZcashRustBackend.initAccountsTable(dbData: dbData!, ufvks: ufvks, networkType: networkType) else { + do { + try ZcashRustBackend.initAccountsTable(dbData: dbData!, ufvks: ufvks, networkType: networkType) + } catch { XCTFail("failed with error: \(String(describing: ZcashRustBackend.lastError()))") return } + XCTAssertNotNil( try ZcashRustBackend.createAccount( dbData: dbData!, diff --git a/Tests/TestUtils/Stubs.swift b/Tests/TestUtils/Stubs.swift index 588bb46f..9a79e980 100644 --- a/Tests/TestUtils/Stubs.swift +++ b/Tests/TestUtils/Stubs.swift @@ -55,6 +55,10 @@ extension LightWalletServiceMockResponse { } class MockRustBackend: ZcashRustBackendWelding { + static func initAccountsTable(dbData: URL, ufvks: [ZcashLightClientKit.UnifiedFullViewingKey], networkType: ZcashLightClientKit.NetworkType) throws { + + } + static func createToAddress(dbData: URL, usk: ZcashLightClientKit.UnifiedSpendingKey, to address: String, value: Int64, memo: ZcashLightClientKit.MemoBytes?, spendParamsPath: String, outputParamsPath: String, networkType: ZcashLightClientKit.NetworkType) -> Int64 { -1 }