ZcashLightClientKit/Tests/TestUtils/TestCoordinator.swift

373 lines
13 KiB
Swift
Raw Normal View History

//
// TestCoordinator.swift
// ZcashLightClientKit-Unit-Tests
//
// Created by Francisco Gindre on 4/29/20.
//
import Foundation
@testable import ZcashLightClientKit
/**
2021-09-23 06:26:41 -07:00
This is the TestCoordinator
What does it do? quite a lot.
Is it a nice "SOLID" "Clean Code" piece of source code?
Hell no. It's your testing overlord and you will be grateful it is.
*/
// swiftlint:disable force_try function_parameter_count
class TestCoordinator {
enum CoordinatorError: Error {
case notDarksideWallet
case notificationFromUnknownSynchronizer
case notMockLightWalletService
2020-11-05 14:02:01 -08:00
case builderError
case seedRequiredForMigration
}
enum SyncThreshold {
case upTo(height: BlockHeight)
case latestHeight
}
enum DarksideData {
case `default`
case predefined(dataset: DarksideDataset)
case url(urlString: String, startHeigth: BlockHeight)
}
var completionHandler: ((SDKSynchronizer) throws -> Void)?
var errorHandler: ((Error?) -> Void)?
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
var spendingKey: SaplingExtendedSpendingKey
var birthday: BlockHeight
var channelProvider: ChannelProvider
var synchronizer: SDKSynchronizer
var service: DarksideWalletService
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
var spendingKeys: [SaplingExtendedSpendingKey]?
var databases: TemporaryTestDatabases
2021-07-28 09:59:10 -07:00
let network: ZcashNetwork
2021-09-23 06:26:41 -07:00
convenience init(
seed: String,
walletBirthday: BlockHeight,
channelProvider: ChannelProvider,
network: ZcashNetwork
) throws {
2021-07-28 09:59:10 -07:00
let derivationTool = DerivationTool(networkType: network.networkType)
2021-09-23 06:26:41 -07:00
guard
let spendingKey = try derivationTool
.deriveSpendingKeys(
seed: TestSeed().seed(),
numberOfAccounts: 1
)
.first
else {
2020-11-05 14:02:01 -08:00
throw CoordinatorError.builderError
}
2021-04-02 15:18:16 -07:00
2021-09-23 06:26:41 -07:00
guard
let ufvk = try derivationTool
.deriveUnifiedFullViewingKeysFromSeed(
2021-09-23 06:26:41 -07:00
TestSeed().seed(),
numberOfAccounts: 1
)
.first
else {
2021-04-02 15:18:16 -07:00
throw CoordinatorError.builderError
}
2021-09-23 06:26:41 -07:00
try self.init(
spendingKey: spendingKey,
unifiedFullViewingKey: ufvk,
2021-09-23 06:26:41 -07:00
walletBirthday: walletBirthday,
channelProvider: channelProvider,
network: network
)
2020-11-05 14:02:01 -08:00
}
2021-04-02 15:18:16 -07:00
required init(
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
spendingKey: SaplingExtendedSpendingKey,
unifiedFullViewingKey: UnifiedFullViewingKey,
2021-07-28 09:59:10 -07:00
walletBirthday: BlockHeight,
channelProvider: ChannelProvider,
2021-09-23 06:26:41 -07:00
network: ZcashNetwork
) throws {
2020-11-05 14:02:01 -08:00
self.spendingKey = spendingKey
self.birthday = walletBirthday
self.channelProvider = channelProvider
self.databases = TemporaryDbBuilder.build()
2021-07-28 09:59:10 -07:00
self.network = network
2021-09-23 06:26:41 -07:00
self.service = DarksideWalletService(
service: LightWalletGRPCService(
host: Constants.address,
port: 9067,
secure: false,
singleCallTimeout: 10000,
streamingCallTimeout: 1000000
)
)
let storage = CompactBlockStorage(url: databases.cacheDB, readonly: false)
try storage.createTable()
let buildResult = try TestSynchronizerBuilder.build(
2021-09-23 06:26:41 -07:00
rustBackend: ZcashRustBackend.self,
lowerBoundHeight: self.birthday,
cacheDbURL: databases.cacheDB,
dataDbURL: databases.dataDB,
pendingDbURL: databases.pendingDB,
endpoint: LightWalletEndpointBuilder.default,
service: self.service,
repository: TransactionSQLDAO(dbProvider: SimpleConnectionProvider(path: databases.dataDB.absoluteString)),
accountRepository: AccountRepositoryBuilder.build(
dataDbURL: databases.dataDB,
readOnly: true
),
storage: storage,
spendParamsURL: try __spendParamsURL(),
outputParamsURL: try __outputParamsURL(),
spendingKey: spendingKey,
unifiedFullViewingKey: unifiedFullViewingKey,
walletBirthday: walletBirthday,
2021-09-23 06:26:41 -07:00
network: network,
loggerProxy: SampleLogger(logLevel: .debug)
)
self.synchronizer = buildResult.synchronizer
self.spendingKeys = buildResult.spendingKeys
subscribeToNotifications(synchronizer: self.synchronizer)
}
func stop() throws {
2020-10-14 15:50:26 -07:00
synchronizer.stop()
self.completionHandler = nil
self.errorHandler = nil
}
func setDarksideWalletState(_ state: DarksideData) throws {
switch state {
case .default:
try service.useDataset(DarksideDataset.beforeReOrg.rawValue)
case .predefined(let dataset):
try service.useDataset(dataset.rawValue)
2021-09-23 06:26:41 -07:00
case .url(let urlString, _):
try service.useDataset(from: urlString)
}
}
func setLatestHeight(height: BlockHeight) throws {
try service.applyStaged(nextLatestHeight: height)
}
func sync(completion: @escaping (SDKSynchronizer) throws -> Void, error: @escaping (Error?) -> Void) throws {
self.completionHandler = completion
self.errorHandler = error
2020-12-05 10:10:22 -08:00
try synchronizer.start(retry: true)
}
/**
2021-09-23 06:26:41 -07:00
Notifications
*/
func subscribeToNotifications(synchronizer: Synchronizer) {
NotificationCenter.default.addObserver(self, selector: #selector(synchronizerFailed(_:)), name: .synchronizerFailed, object: synchronizer)
NotificationCenter.default.addObserver(self, selector: #selector(synchronizerSynced(_:)), name: .synchronizerSynced, object: synchronizer)
}
@objc func synchronizerFailed(_ notification: Notification) {
self.errorHandler?(notification.userInfo?[SDKSynchronizer.NotificationKeys.error] as? Error)
}
@objc func synchronizerSynced(_ notification: Notification) {
if case .stopped = self.synchronizer.status {
LoggerProxy.debug("WARNING: notification received after synchronizer was stopped")
return
}
try? self.completionHandler?(self.synchronizer)
}
@objc func synchronizerDisconnected(_ notification: Notification) {
/// TODO: See if we need hooks for this
}
@objc func synchronizerStarted(_ notification: Notification) {
/// TODO: See if we need hooks for this
}
@objc func synchronizerStopped(_ notification: Notification) {
/// TODO: See if we need hooks for this
}
@objc func synchronizerSyncing(_ notification: Notification) {
/// TODO: See if we need hooks for this
}
}
extension TestCoordinator {
func resetBlocks(dataset: DarksideData) throws {
switch dataset {
case .default:
try service.useDataset(DarksideDataset.beforeReOrg.rawValue)
case .predefined(let blocks):
try service.useDataset(blocks.rawValue)
2021-09-23 06:26:41 -07:00
case .url(let urlString, _):
try service.useDataset(urlString)
}
}
func stageBlockCreate(height: BlockHeight, count: Int = 1, nonce: Int = 0) throws {
try service.stageBlocksCreate(from: height, count: count, nonce: 0)
}
func applyStaged(blockheight: BlockHeight) throws {
try service.applyStaged(nextLatestHeight: blockheight)
}
2021-09-23 06:26:41 -07:00
func stageTransaction(_ transaction: RawTransaction, at height: BlockHeight) throws {
try service.stageTransaction(transaction, at: height)
}
func stageTransaction(url: String, at height: BlockHeight) throws {
try service.stageTransaction(from: url, at: height)
}
func latestHeight() throws -> BlockHeight {
try service.latestBlockHeight()
}
2021-05-18 14:22:29 -07:00
func reset(saplingActivation: BlockHeight, branchID: String, chainName: String) throws {
let config = self.synchronizer.blockProcessor.config
self.synchronizer.blockProcessor.config = CompactBlockProcessor.Configuration(
2021-09-23 06:26:41 -07:00
cacheDb: config.cacheDb,
dataDb: config.dataDb,
downloadBatchSize: config.downloadBatchSize,
retries: config.retries,
maxBackoffInterval: config.maxBackoffInterval,
rewindDistance: config.rewindDistance,
walletBirthday: config.walletBirthday,
saplingActivation: config.saplingActivation,
network: config.network
)
2021-05-18 14:22:29 -07:00
try service.reset(saplingActivation: saplingActivation, branchID: branchID, chainName: chainName)
}
func getIncomingTransactions() throws -> [RawTransaction]? {
return try service.getIncomingTransactions()
}
}
struct TemporaryTestDatabases {
2021-09-23 06:26:41 -07:00
var cacheDB: URL
var dataDB: URL
var pendingDB: URL
}
2021-09-23 06:26:41 -07:00
enum TemporaryDbBuilder {
static func build() -> TemporaryTestDatabases {
let tempUrl = try! __documentsDirectory()
let timestamp = String(Int(Date().timeIntervalSince1970))
2021-09-23 06:26:41 -07:00
return TemporaryTestDatabases(
cacheDB: tempUrl.appendingPathComponent("cache_db_\(timestamp).db"),
dataDB: tempUrl.appendingPathComponent("data_db_\(timestamp).db"),
pendingDB: tempUrl.appendingPathComponent("pending_db_\(timestamp).db")
)
}
}
2021-09-23 06:26:41 -07:00
enum TestSynchronizerBuilder {
static func build(
rustBackend: ZcashRustBackendWelding.Type,
lowerBoundHeight: BlockHeight,
cacheDbURL: URL,
dataDbURL: URL,
pendingDbURL: URL,
2020-10-14 15:50:26 -07:00
endpoint: LightWalletEndpoint,
service: LightWalletService,
repository: TransactionRepository,
2021-04-08 10:18:16 -07:00
accountRepository: AccountRepository,
storage: CompactBlockStorage,
spendParamsURL: URL,
outputParamsURL: URL,
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
spendingKey: SaplingExtendedSpendingKey,
unifiedFullViewingKey: UnifiedFullViewingKey,
walletBirthday: BlockHeight,
2021-07-28 09:59:10 -07:00
network: ZcashNetwork,
seed: [UInt8]? = nil,
loggerProxy: Logger? = nil
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
) throws -> (spendingKeys: [SaplingExtendedSpendingKey]?, synchronizer: SDKSynchronizer) {
let initializer = Initializer(
cacheDbURL: cacheDbURL,
dataDbURL: dataDbURL,
pendingDbURL: pendingDbURL,
2020-10-14 15:50:26 -07:00
endpoint: endpoint,
network: network,
spendParamsURL: spendParamsURL,
outputParamsURL: outputParamsURL,
viewingKeys: [unifiedFullViewingKey],
walletBirthday: walletBirthday,
alias: "",
loggerProxy: loggerProxy
)
2021-09-23 06:26:41 -07:00
let synchronizer = try SDKSynchronizer(initializer: initializer)
if case .seedRequired = try synchronizer.prepare(with: seed) {
throw TestCoordinator.CoordinatorError.seedRequiredForMigration
}
2021-05-07 11:50:50 -07:00
return ([spendingKey], synchronizer)
}
2021-09-23 06:26:41 -07:00
2020-11-05 14:02:01 -08:00
static func build(
rustBackend: ZcashRustBackendWelding.Type,
lowerBoundHeight: BlockHeight,
cacheDbURL: URL,
dataDbURL: URL,
pendingDbURL: URL,
endpoint: LightWalletEndpoint,
service: LightWalletService,
repository: TransactionRepository,
2021-04-08 10:18:16 -07:00
accountRepository: AccountRepository,
storage: CompactBlockStorage,
2020-11-05 14:02:01 -08:00
spendParamsURL: URL,
outputParamsURL: URL,
seedBytes: [UInt8],
walletBirthday: BlockHeight,
2021-07-28 09:59:10 -07:00
network: ZcashNetwork,
2020-11-05 14:02:01 -08:00
loggerProxy: Logger? = nil
[#461] Adopt a Type-Safe Keys and Addresses API This PR creates data types for Addresses and Keys so that they are not represented by Strings anymore. This avoids mistakenly use the wrong keys because they are all alike for the type system. New Protocols: ============= StringEncoded -> Protocol that makes a type can be expressed in an string-encoded fashion either for UI or Interchange purposes. Undescribable -> A protocol that implements methods that override default decriptions used by debuggers, loggers and event trackers to avoid types conforming to it to be leaked to logs. Deleted Protocols: ================== UnifiedFullViewingKey --> turned into a struct. UnifiedAddress --> turned into a struct new Error Type: ================ ```` enum KeyEncodingError: Error { case invalidEncoding } ```` This error is thrown when an Address or Key type (addresses are public keys in the end) can be decoded from their String representation, typically upon initialization from a User input. New Types: ========= SaplingExtendedSpendingKey -> Type for Sapling Extended Full Viewing Keys this type will be replaced with Unified Spending Keys soon. SaplingExtendedFullViewingKey -> Extended Full Viewing Key for Sapling. Maintains existing funcionality. Will be probably deprecated in favor of UFVK. TransparentAccountPrivKey -> Private key for transparent account. Used only for shielding operations. Note: this will probably be deprecated soon. UnifiedFullViewingKey -> Replaces the protocol that had the same name. TransparentAddress -> Replaces a type alias with a struct SaplingAddress --> Represents a Sapling receiver address. Comonly called zAddress. This address corresponds to the Zcash Sapling shielded pool. Although this it is fully functional, we encourage developers to choose `UnifiedAddress` before Sapling or Transparent ones. UnifiedAddress -> Represents a UA. String-encodable and Equatable. Use of UAs must be favored instead of individual receivers for different pools. This type can't be decomposed into their Receiver types yet. Recipient -> This represents all valid receiver types to be used as inputs for outgoing transactions. ```` public enum Recipient: Equatable, StringEncoded { case transparent(TransparentAddress) case sapling(SaplingAddress) case unified(UnifiedAddress) ```` The wrapped concrete receiver is a valid receiver type. Deleted Type Aliases: ===================== The following aliases were deleted and turned into types ```` public typealias TransparentAddress = String public typealias SaplingShieldedAddress = String ```` Changes to Derivation Tool ========================== DerivationTool has been changed to accomodate this new types and remove Strings whenever possible. Changes to Synchronizer and CompactBlockProcessor ================================================= Accordingly these to components have been modified to accept the new types intead of strings when possible. Changes to Demo App =================== The demo App has been patch to compile and work with the new types. Developers must consider that the use (and abuse) of forced_try and forced unwrapping is a "license" that maintainers are using for the sake of brevity. We consider that clients of this SDK do know how to handle Errors and Optional and it is not the objective of the demo code to show good practices on those matters. Closes #461
2022-08-20 15:10:22 -07:00
) throws -> (spendingKeys: [SaplingExtendedSpendingKey]?, synchronizer: SDKSynchronizer) {
2021-09-23 06:26:41 -07:00
guard
let spendingKey = try DerivationTool(networkType: network.networkType)
.deriveSpendingKeys(seed: seedBytes, numberOfAccounts: 1)
.first
else {
2020-11-05 14:02:01 -08:00
throw TestCoordinator.CoordinatorError.builderError
}
2021-04-02 15:18:16 -07:00
2021-09-23 06:26:41 -07:00
guard let uvk = try DerivationTool(networkType: network.networkType)
.deriveUnifiedFullViewingKeysFromSeed(seedBytes, numberOfAccounts: 1)
2021-09-23 06:26:41 -07:00
.first
else {
2021-04-02 15:18:16 -07:00
throw TestCoordinator.CoordinatorError.builderError
}
2021-09-23 06:26:41 -07:00
return try build(
rustBackend: rustBackend,
2020-11-05 14:02:01 -08:00
lowerBoundHeight: lowerBoundHeight,
cacheDbURL: cacheDbURL,
dataDbURL: dataDbURL,
pendingDbURL: pendingDbURL,
endpoint: endpoint,
service: service,
repository: repository,
2021-04-08 10:18:16 -07:00
accountRepository: accountRepository,
storage: storage,
2020-11-05 14:02:01 -08:00
spendParamsURL: spendParamsURL,
outputParamsURL: outputParamsURL,
spendingKey: spendingKey,
unifiedFullViewingKey: uvk,
2021-07-28 09:59:10 -07:00
walletBirthday: walletBirthday,
2021-09-23 06:26:41 -07:00
network: network
)
2020-11-05 14:02:01 -08:00
}
}