Use zcash_client_sqlite to manage migrations for the wallet db.
This change removes responsibility for maintaining the state of the wallet database from `ZcashLightClientKit` in favor of using the migration system now provided by librustzcash. This will help to ensure that the structure of the database is kept consistent with the functions that query and update the database state. Co-authored-by: Francisco Gindre <francisco.gindre@gmail.com>
This commit is contained in:
parent
739c7a7237
commit
905ee401d1
|
@ -138,11 +138,11 @@
|
|||
},
|
||||
{
|
||||
"package": "libzcashlc",
|
||||
"repositoryURL": "https://github.com/zcash-hackworks/zcash-light-client-ffi.git",
|
||||
"repositoryURL": "https://github.com/nuttycom/zcash-light-client-ffi.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "b7e8a2abab84c44046b4afe4ee4522a0fa2fcc7f",
|
||||
"version": "0.0.3"
|
||||
"branch": "bin/librustzcash_0_7-migrations",
|
||||
"revision": "dbf7ac51a7de0bbc2c1088973236d68ceb752361",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -49,7 +49,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
loggerProxy: loggerProxy
|
||||
)
|
||||
|
||||
try! wallet.initialize()
|
||||
_ = try! wallet.initialize(with: DemoAppConfig.seed)
|
||||
var storage = SampleStorage.shared
|
||||
storage!.seed = Data(DemoAppConfig.seed)
|
||||
storage!.privateKey = try! DerivationTool(networkType: kZcashNetwork.networkType)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -109,18 +109,18 @@ class DerivationToolViewController: UIViewController {
|
|||
throw DerivationErrors.couldNotDeriveSpendingKeys(underlyingError: DerivationErrors.unknown)
|
||||
}
|
||||
|
||||
guard let viewingKey = try derivationTool.deriveViewingKeys(seed: seedBytes, numberOfAccounts: 1).first else {
|
||||
guard let viewingKey = try derivationTool.deriveUnifiedFullViewingKeysFromSeed(seedBytes, numberOfAccounts: 1).first else {
|
||||
throw DerivationErrors.couldNotDeriveViewingKeys(underlyingError: DerivationErrors.unknown)
|
||||
}
|
||||
|
||||
let shieldedAddress = try derivationTool.deriveShieldedAddress(viewingKey: viewingKey)
|
||||
let unifiedAddress = try derivationTool.deriveUnifiedAddress(viewingKey: viewingKey.encoding)
|
||||
|
||||
let transparentAddress = try derivationTool.deriveTransparentAddress(seed: seedBytes)
|
||||
|
||||
updateLabels(
|
||||
spendingKey: spendingKey,
|
||||
viewingKey: viewingKey,
|
||||
shieldedAddress: shieldedAddress,
|
||||
viewingKey: viewingKey.encoding,
|
||||
shieldedAddress: unifiedAddress,
|
||||
transaparentAddress: transparentAddress
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import UIKit
|
||||
import ZcashLightClientKit
|
||||
class GetAddressViewController: UIViewController {
|
||||
@IBOutlet weak var zAddressLabel: UILabel!
|
||||
@IBOutlet weak var unifiedAddressLabel: UILabel!
|
||||
@IBOutlet weak var tAddressLabel: UILabel!
|
||||
@IBOutlet weak var spendingKeyLabel: UILabel! // THIS SHOULD BE SUPER SECRET!!!!!
|
||||
|
||||
|
@ -18,16 +18,16 @@ class GetAddressViewController: UIViewController {
|
|||
let derivationTool = DerivationTool(networkType: kZcashNetwork.networkType)
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
zAddressLabel.text = (try? derivationTool.deriveShieldedAddress(seed: DemoAppConfig.seed, accountIndex: 0)) ?? "No Addresses found"
|
||||
unifiedAddressLabel.text = (try? derivationTool.deriveUnifiedAddress(seed: DemoAppConfig.seed, accountIndex: 0)) ?? "No Addresses found"
|
||||
tAddressLabel.text = (try? derivationTool.deriveTransparentAddress(seed: DemoAppConfig.seed)) ?? "could not derive t-address"
|
||||
spendingKeyLabel.text = SampleStorage.shared.privateKey ?? "No Spending Key found"
|
||||
zAddressLabel.addGestureRecognizer(
|
||||
unifiedAddressLabel.addGestureRecognizer(
|
||||
UITapGestureRecognizer(
|
||||
target: self,
|
||||
action: #selector(addressTapped(_:))
|
||||
)
|
||||
)
|
||||
zAddressLabel.isUserInteractionEnabled = true
|
||||
unifiedAddressLabel.isUserInteractionEnabled = true
|
||||
|
||||
tAddressLabel.isUserInteractionEnabled = true
|
||||
tAddressLabel.addGestureRecognizer(
|
||||
|
@ -70,8 +70,7 @@ class GetAddressViewController: UIViewController {
|
|||
@IBAction func addressTapped(_ gesture: UIGestureRecognizer) {
|
||||
loggerProxy.event("copied to clipboard")
|
||||
|
||||
UIPasteboard.general.string = try? DerivationTool(networkType: kZcashNetwork.networkType)
|
||||
.deriveShieldedAddress(seed: DemoAppConfig.seed, accountIndex: 0)
|
||||
UIPasteboard.general.string = unifiedAddressLabel.text
|
||||
|
||||
let alert = UIAlertController(
|
||||
title: "",
|
||||
|
|
|
@ -42,13 +42,13 @@ class GetUTXOsViewController: UIViewController {
|
|||
let derivationTool = DerivationTool(networkType: kZcashNetwork.networkType)
|
||||
// swiftlint:disable:next force_unwrapping
|
||||
let spendingKey = try derivationTool.deriveSpendingKeys(seed: seed, numberOfAccounts: 1).first!
|
||||
let transparentSecretKey = try derivationTool.deriveTransparentPrivateKey(seed: seed)
|
||||
let transparentSecretKey = try derivationTool.deriveTransparentAccountPrivateKey(seed: seed, account: 0)
|
||||
|
||||
KRProgressHUD.showMessage("🛡 Shielding 🛡")
|
||||
|
||||
AppDelegate.shared.sharedSynchronizer.shieldFunds(
|
||||
spendingKey: spendingKey,
|
||||
transparentSecretKey: transparentSecretKey,
|
||||
transparentAccountPrivateKey: transparentSecretKey,
|
||||
memo: "shielding is fun!",
|
||||
from: 0,
|
||||
resultBlock: { result in
|
||||
|
|
|
@ -33,7 +33,7 @@ class SendViewController: UIViewController {
|
|||
super.viewDidLoad()
|
||||
synchronizer = AppDelegate.shared.sharedSynchronizer
|
||||
// swiftlint:disable:next force_try
|
||||
try! synchronizer.prepare()
|
||||
_ = try! synchronizer.prepare(with: DemoAppConfig.seed)
|
||||
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewTapped(_:)))
|
||||
self.view.addGestureRecognizer(tapRecognizer)
|
||||
setUp()
|
||||
|
|
|
@ -29,7 +29,7 @@ class SyncBlocksViewController: UIViewController {
|
|||
|
||||
let wallet = Initializer.shared
|
||||
// swiftlint:disable:next force_try
|
||||
try! wallet.initialize()
|
||||
_ = try! wallet.initialize(with: DemoAppConfig.seed)
|
||||
processor = CompactBlockProcessor(initializer: wallet)
|
||||
statusLabel.text = textFor(state: processor?.state ?? .stopped)
|
||||
progressBar.progress = 0
|
||||
|
|
|
@ -86,8 +86,8 @@
|
|||
"package": "libzcashlc",
|
||||
"repositoryURL": "https://github.com/zcash-hackworks/zcash-light-client-ffi.git",
|
||||
"state": {
|
||||
"branch": "librustzcash_0_7",
|
||||
"revision": "127a6b9d19841fea232bf0d0887ae5f2cad8df04",
|
||||
"branch": "librustzcash_0_7_build_test",
|
||||
"revision": "5a48541c1da48eb082defaf0fa127657f4f99094",
|
||||
"version": null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ let package = Package(
|
|||
dependencies: [
|
||||
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.8.0"),
|
||||
.package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.13.0"),
|
||||
.package(name:"libzcashlc", url: "https://github.com/zcash-hackworks/zcash-light-client-ffi.git", branch: "librustzcash_0_7"),
|
||||
.package(name:"libzcashlc", url: "https://github.com/zcash-hackworks/zcash-light-client-ffi.git", branch: "librustzcash_0_7_build_test"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
|
@ -9,11 +9,6 @@ import Foundation
|
|||
import SQLite
|
||||
|
||||
class MigrationManager {
|
||||
enum DataDbMigrations: Int32 {
|
||||
case none = 0
|
||||
case version1 = 1
|
||||
}
|
||||
|
||||
enum CacheDbMigration: Int32 {
|
||||
case none = 0
|
||||
}
|
||||
|
@ -22,136 +17,27 @@ class MigrationManager {
|
|||
case none = 0
|
||||
}
|
||||
|
||||
static let latestDataDbMigrationVersion: Int32 = DataDbMigrations.version1.rawValue
|
||||
static let latestCacheDbMigrationVersion: Int32 = CacheDbMigration.none.rawValue
|
||||
static let latestPendingDbMigrationVersion: Int32 = PendingDbMigration.none.rawValue
|
||||
|
||||
var cacheDb: ConnectionProvider
|
||||
var dataDb: ConnectionProvider
|
||||
var pendingDb: ConnectionProvider
|
||||
var network: NetworkType
|
||||
|
||||
init(
|
||||
cacheDbConnection: ConnectionProvider,
|
||||
dataDbConnection: ConnectionProvider,
|
||||
pendingDbConnection: ConnectionProvider,
|
||||
networkType: NetworkType
|
||||
) {
|
||||
self.cacheDb = cacheDbConnection
|
||||
self.dataDb = dataDbConnection
|
||||
self.pendingDb = pendingDbConnection
|
||||
self.network = networkType
|
||||
}
|
||||
|
||||
func performMigration(ufvks: [UnifiedFullViewingKey]) throws {
|
||||
// TODO: DataDB migrations will be handled by rustBackend.initDataDb
|
||||
// once https://github.com/zcash/librustzcash/pull/600 merges, and in
|
||||
// the interim the old migrations here will fail if we try to run them
|
||||
// due to changes to table column names in zcash/librustzcash.
|
||||
//try migrateDataDb(ufvks: ufvks)
|
||||
try migrateCacheDb()
|
||||
try migratePendingDb()
|
||||
}
|
||||
|
||||
func performVersion1Migration(viewingKeys: [UnifiedFullViewingKey]) throws {
|
||||
LoggerProxy.debug("Starting migration version 1 from viewing Keys")
|
||||
let db = try self.dataDb.connection()
|
||||
|
||||
let placeholder = "deriveMe"
|
||||
let migrationStatement =
|
||||
"""
|
||||
BEGIN TRANSACTION;
|
||||
PRAGMA foreign_keys = OFF;
|
||||
DROP TABLE utxos;
|
||||
CREATE TABLE IF NOT EXISTS utxos(
|
||||
id_utxo INTEGER PRIMARY KEY,
|
||||
address TEXT NOT NULL,
|
||||
prevout_txid BLOB NOT NULL,
|
||||
prevout_idx INTEGER NOT NULL,
|
||||
script BLOB NOT NULL,
|
||||
value_zat INTEGER NOT NULL,
|
||||
height INTEGER NOT NULL,
|
||||
spent_in_tx INTEGER,
|
||||
FOREIGN KEY (spent_in_tx) REFERENCES transactions(id_tx),
|
||||
CONSTRAINT tx_outpoint UNIQUE (prevout_txid, prevout_idx)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS accounts_new (
|
||||
account INTEGER PRIMARY KEY,
|
||||
extfvk TEXT NOT NULL,
|
||||
address TEXT NOT NULL,
|
||||
transparent_address TEXT NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO accounts_new SELECT account, extfvk, address, '\(placeholder)' FROM accounts;
|
||||
DROP TABLE accounts;
|
||||
|
||||
ALTER TABLE accounts_new RENAME TO accounts;
|
||||
|
||||
PRAGMA user_version = 1;
|
||||
PRAGMA foreign_keys = ON;
|
||||
COMMIT TRANSACTION;
|
||||
"""
|
||||
LoggerProxy.debug("db.execute(\"\(migrationStatement)\")")
|
||||
try db.execute(migrationStatement)
|
||||
|
||||
LoggerProxy.debug("db.run() succeeded")
|
||||
|
||||
// derive transparent (shielding) addresses
|
||||
let accountsDao = AccountSQDAO(dbProvider: self.dataDb)
|
||||
|
||||
let accounts = try accountsDao.getAll()
|
||||
|
||||
guard !accounts.isEmpty else {
|
||||
LoggerProxy.debug("no existing accounts found while performing this migration")
|
||||
return
|
||||
}
|
||||
|
||||
guard accounts.count == viewingKeys.count else {
|
||||
let message = """
|
||||
Number of accounts found and viewing keys provided don't match.
|
||||
Found \(accounts.count) account(s) and there were \(viewingKeys.count) Viewing key(s) provided.
|
||||
"""
|
||||
LoggerProxy.debug(message)
|
||||
throw StorageError.migrationFailedWithMessage(message: message)
|
||||
}
|
||||
|
||||
let derivationTool = DerivationTool(networkType: self.network)
|
||||
|
||||
for tuple in zip(accounts, viewingKeys) {
|
||||
// TODO: Should the v1 migration be changed to "migrate from pre-v1 database to v2"?
|
||||
let tAddr = try derivationTool.deriveTransparentAddressFromPublicKey(tuple.1.encoding)
|
||||
var account = tuple.0
|
||||
account.transparentAddress = tAddr
|
||||
try accountsDao.update(account)
|
||||
}
|
||||
|
||||
// sanity check
|
||||
guard try accountsDao.getAll().first(where: { $0.transparentAddress == placeholder }) == nil else {
|
||||
LoggerProxy.error("Accounts Migration performed but the transparent addresses were not derived")
|
||||
throw StorageError.migrationFailed(underlyingError: KeyDerivationErrors.unableToDerive)
|
||||
}
|
||||
}
|
||||
|
||||
func performVersion1Migration(_ seedBytes: [UInt8]) throws {
|
||||
LoggerProxy.debug("Starting migration version 1")
|
||||
|
||||
// derive transparent (shielding) addresses
|
||||
let accountsDao = AccountSQDAO(dbProvider: self.dataDb)
|
||||
|
||||
let accounts = try accountsDao.getAll()
|
||||
|
||||
guard !accounts.isEmpty else {
|
||||
LoggerProxy.debug("no existing accounts found while performing this migration")
|
||||
return
|
||||
}
|
||||
|
||||
let derivationTool = DerivationTool(networkType: self.network)
|
||||
|
||||
let ufvks = try derivationTool.deriveUnifiedFullViewingKeysFromSeed(seedBytes, numberOfAccounts: accounts.count)
|
||||
|
||||
try performVersion1Migration(viewingKeys: ufvks)
|
||||
}
|
||||
}
|
||||
|
||||
private extension MigrationManager {
|
||||
|
@ -186,31 +72,6 @@ private extension MigrationManager {
|
|||
LoggerProxy.debug("Cache Db - no migration needed")
|
||||
}
|
||||
}
|
||||
|
||||
func migrateDataDb(ufvks: [UnifiedFullViewingKey]) throws {
|
||||
let currentDataDbVersion = try dataDb.connection().getUserVersion()
|
||||
LoggerProxy.debug(
|
||||
"Attempting to perform migration for data Db - currentVersion: \(currentDataDbVersion)." +
|
||||
"Latest version is: \(Self.latestDataDbMigrationVersion)"
|
||||
)
|
||||
|
||||
if currentDataDbVersion < Self.latestDataDbMigrationVersion {
|
||||
for dbVersion in (currentDataDbVersion + 1) ... Self.latestDataDbMigrationVersion {
|
||||
guard let version = DataDbMigrations.init(rawValue: dbVersion) else {
|
||||
LoggerProxy.error("failed to determine migration version")
|
||||
throw StorageError.invalidMigrationVersion(version: dbVersion)
|
||||
}
|
||||
switch version {
|
||||
case .version1:
|
||||
try performVersion1Migration(viewingKeys: ufvks)
|
||||
case .none:
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LoggerProxy.debug("Data Db - no migration needed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Connection {
|
||||
|
|
|
@ -36,9 +36,8 @@ extension Account: UnifiedAddress {
|
|||
get {
|
||||
address
|
||||
}
|
||||
// swiftlint:disable unused_setter_value
|
||||
set {
|
||||
address = encoding
|
||||
address = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,12 @@ The [cash.z.wallet.sdk.block.CompactBlockProcessor] handles all the remaining Ru
|
|||
functionality, related to processing blocks.
|
||||
*/
|
||||
public class Initializer {
|
||||
|
||||
public enum InitializationResult {
|
||||
case success
|
||||
case seedRequired
|
||||
}
|
||||
|
||||
private(set) var rustBackend: ZcashRustBackendWelding.Type
|
||||
private(set) var alias: String
|
||||
private(set) var endpoint: LightWalletEndpoint
|
||||
|
@ -188,7 +194,7 @@ public class Initializer {
|
|||
- Parameters:
|
||||
- viewingKeys: Extended Full Viewing Keys to initialize the DBs with
|
||||
*/
|
||||
public func initialize() throws {
|
||||
public func initialize(with seed: [UInt8]?) throws -> InitializationResult {
|
||||
do {
|
||||
try storage.createTable()
|
||||
} catch {
|
||||
|
@ -196,9 +202,9 @@ public class Initializer {
|
|||
}
|
||||
|
||||
do {
|
||||
try rustBackend.initDataDb(dbData: dataDbURL, networkType: network.networkType)
|
||||
} catch RustWeldingError.dataDbNotEmpty {
|
||||
// this is fine
|
||||
if case .seedRequired = try rustBackend.initDataDb(dbData: dataDbURL, seed: seed, networkType: network.networkType) {
|
||||
return .seedRequired
|
||||
}
|
||||
} catch {
|
||||
throw InitializerError.dataDbInitFailed
|
||||
}
|
||||
|
@ -242,12 +248,13 @@ public class Initializer {
|
|||
|
||||
let migrationManager = MigrationManager(
|
||||
cacheDbConnection: SimpleConnectionProvider(path: cacheDbURL.path),
|
||||
dataDbConnection: SimpleConnectionProvider(path: dataDbURL.path),
|
||||
pendingDbConnection: SimpleConnectionProvider(path: pendingDbURL.path),
|
||||
networkType: self.network.networkType
|
||||
)
|
||||
|
||||
try migrationManager.performMigration(ufvks: viewingKeys)
|
||||
|
||||
return .success
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,13 +39,19 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
|||
/**
|
||||
* Sets up the internal structure of the data database.
|
||||
*/
|
||||
static func initDataDb(dbData: URL, networkType: NetworkType) throws {
|
||||
static func initDataDb(dbData: URL, seed: [UInt8]?, networkType: NetworkType) throws -> DbInitResult {
|
||||
let dbData = dbData.osStr()
|
||||
guard zcashlc_init_data_database(dbData.0, dbData.1, networkType.networkId) != 0 else {
|
||||
switch zcashlc_init_data_database(dbData.0, dbData.1, seed, UInt(seed?.count ?? 0), networkType.networkId) {
|
||||
case 0: //ok
|
||||
return DbInitResult.success
|
||||
case 1:
|
||||
return DbInitResult.seedRequired
|
||||
default:
|
||||
if let error = lastError() {
|
||||
throw throwDataDbError(error)
|
||||
} else {
|
||||
throw RustWeldingError.dataDbInitFailed(message: "Database initialization failed: unknown error")
|
||||
}
|
||||
throw RustWeldingError.dataDbInitFailed(message: "unknown error")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,6 +171,7 @@ class ZcashRustBackend: ZcashRustBackendWelding {
|
|||
|
||||
return result
|
||||
}
|
||||
|
||||
// swiftlint:disable function_parameter_count
|
||||
static func initBlocksTable(
|
||||
dbData: URL,
|
||||
|
|
|
@ -22,6 +22,15 @@ public enum ZcashRustBackendWeldingConstants {
|
|||
static let validChain: Int32 = -1
|
||||
}
|
||||
|
||||
/**
|
||||
Enumeration of potential return states for database initialization. If `seedRequired` is returned, the caller must
|
||||
re-attempt initialization providing the seed
|
||||
*/
|
||||
public enum DbInitResult {
|
||||
case success
|
||||
case seedRequired
|
||||
}
|
||||
|
||||
public protocol ZcashRustBackendWelding {
|
||||
/**
|
||||
gets the latest error if available. Clear the existing error
|
||||
|
@ -37,7 +46,7 @@ public protocol ZcashRustBackendWelding {
|
|||
initializes the data db
|
||||
- Parameter dbData: location of the data db sql file
|
||||
*/
|
||||
static func initDataDb(dbData: URL, networkType: NetworkType) throws
|
||||
static func initDataDb(dbData: URL, seed: [UInt8]?, networkType: NetworkType) throws -> DbInitResult
|
||||
|
||||
/**
|
||||
- Returns: true when the address is valid and shielded. Returns false in any other case
|
||||
|
|
|
@ -80,7 +80,7 @@ public protocol Synchronizer {
|
|||
|
||||
/// prepares this initializer to operate. Initializes the internal state with the given
|
||||
/// Extended Viewing Keys and a wallet birthday found in the initializer object
|
||||
func prepare() throws
|
||||
func prepare(with seed: [UInt8]?) throws -> Initializer.InitializationResult
|
||||
|
||||
///Starts this synchronizer within the given scope.
|
||||
///
|
||||
|
|
|
@ -154,17 +154,18 @@ public class SDKSynchronizer: Synchronizer {
|
|||
self.blockProcessor.stop()
|
||||
}
|
||||
|
||||
public func initialize() throws {
|
||||
try self.initializer.initialize()
|
||||
try self.blockProcessor.setStartHeight(initializer.walletBirthday)
|
||||
}
|
||||
|
||||
public func prepare() throws {
|
||||
try self.initializer.initialize()
|
||||
public func prepare(with seed: [UInt8]?) throws -> Initializer.InitializationResult {
|
||||
if case .seedRequired = try self.initializer.initialize(with: seed) {
|
||||
return .seedRequired
|
||||
}
|
||||
|
||||
try self.blockProcessor.setStartHeight(initializer.walletBirthday)
|
||||
self.status = .disconnected
|
||||
|
||||
return .success
|
||||
}
|
||||
|
||||
|
||||
/// Starts the synchronizer
|
||||
/// - Throws: CompactBlockProcessorError when failures occur
|
||||
public func start(retry: Bool = false) throws {
|
||||
|
|
|
@ -64,7 +64,14 @@ class TransactionEnhancementTests: XCTestCase {
|
|||
try? FileManager.default.removeItem(at: processorConfig.dataDb)
|
||||
|
||||
_ = rustBackend.initAccountsTable(dbData: processorConfig.dataDb, seed: TestSeed().seed(), accounts: 1, networkType: network.networkType)
|
||||
_ = try rustBackend.initDataDb(dbData: processorConfig.dataDb, networkType: network.networkType)
|
||||
|
||||
let dbInit = try rustBackend.initDataDb(dbData: processorConfig.dataDb, seed: nil, networkType: network.networkType)
|
||||
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))")
|
||||
return
|
||||
}
|
||||
|
||||
_ = try rustBackend.initBlocksTable(
|
||||
dbData: processorConfig.dataDb,
|
||||
height: Int32(birthday.height),
|
||||
|
|
|
@ -59,7 +59,13 @@ class BlockScanOperationTests: XCTestCase {
|
|||
func testSingleDownloadAndScanOperation() {
|
||||
logger = SampleLogger(logLevel: .debug)
|
||||
|
||||
XCTAssertNoThrow(try rustWelding.initDataDb(dbData: dataDbURL, networkType: network.networkType))
|
||||
var dbInit: DbInitResult!
|
||||
XCTAssertNoThrow(try { dbInit = try ZcashRustBackend.initDataDb(dbData: self.dataDbURL, seed: nil, networkType: .testnet) }())
|
||||
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))")
|
||||
return
|
||||
}
|
||||
|
||||
let downloadStartedExpect = XCTestExpectation(description: "\(self.description) download started")
|
||||
let downloadExpect = XCTestExpectation(description: "\(self.description) download")
|
||||
|
@ -157,8 +163,12 @@ class BlockScanOperationTests: XCTestCase {
|
|||
name: SDKMetrics.notificationName,
|
||||
object: nil
|
||||
)
|
||||
|
||||
try self.rustWelding.initDataDb(dbData: dataDbURL, networkType: network.networkType)
|
||||
|
||||
let dbInit = try self.rustWelding.initDataDb(dbData: dataDbURL, seed: nil, networkType: network.networkType)
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(dbInit)")
|
||||
return
|
||||
}
|
||||
|
||||
guard try self.rustWelding.initAccountsTable(dbData: self.dataDbURL, ufvks: [ufvk], networkType: network.networkType) else {
|
||||
XCTFail("failed to init account table")
|
||||
|
|
|
@ -55,7 +55,13 @@ class CompactBlockProcessorTests: XCTestCase {
|
|||
backend: ZcashRustBackend.self,
|
||||
config: processorConfig
|
||||
)
|
||||
try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, networkType: .testnet)
|
||||
let dbInit = try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, seed: nil, networkType: .testnet)
|
||||
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(dbInit)")
|
||||
return
|
||||
}
|
||||
|
||||
downloadStartedExpect = XCTestExpectation(description: "\(self.description) downloadStartedExpect")
|
||||
stopNotificationExpectation = XCTestExpectation(description: "\(self.description) stopNotificationExpectation")
|
||||
updatedNotificationExpectation = XCTestExpectation(description: "\(self.description) updatedNotificationExpectation")
|
||||
|
|
|
@ -46,9 +46,14 @@ class CompactBlockReorgTests: XCTestCase {
|
|||
info.estimatedHeight = UInt64(mockLatestHeight)
|
||||
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
|
||||
}
|
||||
|
||||
try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, networkType: .testnet)
|
||||
|
||||
|
||||
let dbInit = try ZcashRustBackend.initDataDb(dbData: processorConfig.dataDb, seed: nil, networkType: .testnet)
|
||||
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(dbInit)")
|
||||
return
|
||||
}
|
||||
|
||||
let storage = CompactBlockStorage.init(connectionProvider: SimpleConnectionProvider(path: processorConfig.cacheDb.absoluteString))
|
||||
try! storage.createTable()
|
||||
|
||||
|
|
|
@ -37,9 +37,15 @@ class ZcashRustBackendTests: XCTestCase {
|
|||
|
||||
func testInitWithShortSeedAndFail() {
|
||||
let seed = "testreferencealice"
|
||||
|
||||
XCTAssertNoThrow(try ZcashRustBackend.initDataDb(dbData: dbData!, networkType: networkType))
|
||||
|
||||
|
||||
var dbInit: DbInitResult!
|
||||
XCTAssertNoThrow(try { dbInit = try ZcashRustBackend.initDataDb(dbData: self.dbData!, seed: nil, networkType: self.networkType) }())
|
||||
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))")
|
||||
return
|
||||
}
|
||||
|
||||
_ = ZcashRustBackend.initAccountsTable(dbData: dbData!, seed: Array(seed.utf8), accounts: 1, networkType: networkType)
|
||||
XCTAssertNotNil(ZcashRustBackend.getLastError())
|
||||
}
|
||||
|
@ -99,7 +105,15 @@ class ZcashRustBackendTests: XCTestCase {
|
|||
return
|
||||
}
|
||||
let seed = "testreferencealicetestreferencealice"
|
||||
XCTAssertNoThrow(try ZcashRustBackend.initDataDb(dbData: dbData!, networkType: networkType))
|
||||
|
||||
var dbInit: DbInitResult!
|
||||
XCTAssertNoThrow(try { dbInit = try ZcashRustBackend.initDataDb(dbData: self.dbData!, seed: nil, networkType: self.networkType) }())
|
||||
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))")
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssertEqual(ZcashRustBackend.getLastError(), nil)
|
||||
|
||||
XCTAssertNotNil(ZcashRustBackend.initAccountsTable(dbData: dbData!, seed: Array(seed.utf8), accounts: 1, networkType: networkType))
|
||||
|
|
|
@ -49,7 +49,15 @@ class WalletTests: XCTestCase {
|
|||
)
|
||||
|
||||
let synchronizer = try SDKSynchronizer(initializer: wallet)
|
||||
XCTAssertNoThrow(try synchronizer.prepare())
|
||||
|
||||
var dbInit: Initializer.InitializationResult!
|
||||
|
||||
XCTAssertNoThrow(try { dbInit = try synchronizer.prepare(with: nil) }())
|
||||
|
||||
guard case .success = dbInit else {
|
||||
XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))")
|
||||
return
|
||||
}
|
||||
|
||||
// fileExists actually sucks, so attempting to delete the file and checking what happens is far better :)
|
||||
XCTAssertNoThrow( try FileManager.default.removeItem(at: dbData!) )
|
||||
|
|
|
@ -77,6 +77,10 @@ extension LightWalletServiceMockResponse {
|
|||
}
|
||||
|
||||
class MockRustBackend: ZcashRustBackendWelding {
|
||||
static func initDataDb(dbData: URL, seed: [UInt8]?, networkType: ZcashLightClientKit.NetworkType) throws -> ZcashLightClientKit.DbInitResult {
|
||||
.seedRequired
|
||||
}
|
||||
|
||||
static func clearUtxos(dbData: URL, address: String, sinceHeight: BlockHeight, networkType: NetworkType) throws -> Int32 {
|
||||
-1
|
||||
}
|
||||
|
@ -246,7 +250,7 @@ class MockRustBackend: ZcashRustBackendWelding {
|
|||
|
||||
static func initDataDb(dbData: URL, networkType: NetworkType) throws {
|
||||
if !mockDataDb {
|
||||
try rustBackend.initDataDb(dbData: dbData, networkType: networkType)
|
||||
_ = try rustBackend.initDataDb(dbData: dbData, seed: nil, networkType: networkType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ class TestCoordinator {
|
|||
case notificationFromUnknownSynchronizer
|
||||
case notMockLightWalletService
|
||||
case builderError
|
||||
case seedRequiredForMigration
|
||||
}
|
||||
|
||||
enum SyncThreshold {
|
||||
|
@ -291,6 +292,7 @@ enum TestSynchronizerBuilder {
|
|||
unifiedFullViewingKey: UnifiedFullViewingKey,
|
||||
walletBirthday: BlockHeight,
|
||||
network: ZcashNetwork,
|
||||
seed: [UInt8]? = nil,
|
||||
loggerProxy: Logger? = nil
|
||||
) throws -> (spendingKeys: [String]?, synchronizer: SDKSynchronizer) {
|
||||
let initializer = Initializer(
|
||||
|
@ -308,7 +310,9 @@ enum TestSynchronizerBuilder {
|
|||
)
|
||||
|
||||
let synchronizer = try SDKSynchronizer(initializer: initializer)
|
||||
try synchronizer.prepare()
|
||||
if case .seedRequired = try synchronizer.prepare(with: seed) {
|
||||
throw TestCoordinator.CoordinatorError.seedRequiredForMigration
|
||||
}
|
||||
|
||||
return ([spendingKey], synchronizer)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue