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:
Kris Nuttycombe 2022-08-24 09:38:42 -06:00
parent 739c7a7237
commit 905ee401d1
25 changed files with 296 additions and 357 deletions

View File

@ -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
}
}
]

View File

@ -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)

View File

@ -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
)
}

View File

@ -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: "",

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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
}
}

View File

@ -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(

View File

@ -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 {

View File

@ -36,9 +36,8 @@ extension Account: UnifiedAddress {
get {
address
}
// swiftlint:disable unused_setter_value
set {
address = encoding
address = newValue
}
}
}

View File

@ -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
}
/**

View File

@ -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,

View File

@ -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

View File

@ -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.
///

View File

@ -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 {

View File

@ -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),

View File

@ -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")

View File

@ -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")

View File

@ -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()

View File

@ -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))

View File

@ -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!) )

View File

@ -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)
}
}

View File

@ -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)
}