[#1012] Introduce dependency injection in the SDK
Closes #1012 - This is the first change for the dependency injection. This change adds `DIContainer` which is used to register and resolve dependencies. - Then this change shows how `DIContainer` can be used to resolve dependencies. And it also shows how to mock dependencies in tests. - Constructors of `Initializer` are changed to support mocking of depedendencies. But it doesn't affect public API in any way. - Depedencies are registered in `Dependencies.setup()`. Then in the code `container.resolve(SomeType.self)` is called to get instance of the dependency. - `ZcashTestCase` class is added. It inherits from `XCTestCase` and should be used for base class in tests. `ZcashTestCase` takes care of creation of `DIContainer` for dependencies mocking. In future we can maybe move there more things that are used in each test. - Lot is missing here. Not all the code is using dependency injection. Tests for `DIContainer` are missing. Only `OfflineTests` work now (other tests can't be even compiled). It will be added in future changes.
This commit is contained in:
parent
b582e1e4e1
commit
5d2b2298b5
|
@ -149,6 +149,7 @@ identifier_name:
|
||||||
- nf
|
- nf
|
||||||
- tx
|
- tx
|
||||||
- as
|
- as
|
||||||
|
- di
|
||||||
|
|
||||||
indentation_width:
|
indentation_width:
|
||||||
indentation_width: 4
|
indentation_width: 4
|
||||||
|
|
|
@ -330,41 +330,22 @@ actor CompactBlockProcessor {
|
||||||
/// - backend: a class that complies to `ZcashRustBackendWelding`
|
/// - backend: a class that complies to `ZcashRustBackendWelding`
|
||||||
/// - config: `Configuration` struct for this processor
|
/// - config: `Configuration` struct for this processor
|
||||||
init(
|
init(
|
||||||
service: LightWalletService,
|
container: DIContainer,
|
||||||
storage: CompactBlockRepository,
|
config: Configuration
|
||||||
rustBackend: ZcashRustBackendWelding,
|
|
||||||
config: Configuration,
|
|
||||||
metrics: SDKMetrics,
|
|
||||||
logger: Logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
|
||||||
) {
|
) {
|
||||||
self.init(
|
self.init(
|
||||||
service: service,
|
container: container,
|
||||||
storage: storage,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
config: config,
|
config: config,
|
||||||
repository: TransactionRepositoryBuilder.build(dataDbURL: config.dataDb),
|
accountRepository: AccountRepositoryBuilder.build(dataDbURL: config.dataDb, readOnly: true, logger: container.resolve(Logger.self))
|
||||||
accountRepository: AccountRepositoryBuilder.build(dataDbURL: config.dataDb, readOnly: true, logger: logger),
|
|
||||||
metrics: metrics,
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: latestBlocksDataProvider
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes a CompactBlockProcessor instance from an Initialized object
|
/// Initializes a CompactBlockProcessor instance from an Initialized object
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - initializer: an instance that complies to CompactBlockDownloading protocol
|
/// - initializer: an instance that complies to CompactBlockDownloading protocol
|
||||||
init(
|
init(initializer: Initializer, walletBirthdayProvider: @escaping () -> BlockHeight) {
|
||||||
initializer: Initializer,
|
|
||||||
metrics: SDKMetrics,
|
|
||||||
logger: Logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProvider,
|
|
||||||
walletBirthdayProvider: @escaping () -> BlockHeight
|
|
||||||
) {
|
|
||||||
self.init(
|
self.init(
|
||||||
service: initializer.lightWalletService,
|
container: initializer.container,
|
||||||
storage: initializer.storage,
|
|
||||||
rustBackend: initializer.rustBackend,
|
|
||||||
config: Configuration(
|
config: Configuration(
|
||||||
alias: initializer.alias,
|
alias: initializer.alias,
|
||||||
fsBlockCacheRoot: initializer.fsBlockDbRoot,
|
fsBlockCacheRoot: initializer.fsBlockDbRoot,
|
||||||
|
@ -375,97 +356,37 @@ actor CompactBlockProcessor {
|
||||||
walletBirthdayProvider: walletBirthdayProvider,
|
walletBirthdayProvider: walletBirthdayProvider,
|
||||||
network: initializer.network
|
network: initializer.network
|
||||||
),
|
),
|
||||||
repository: initializer.transactionRepository,
|
accountRepository: initializer.accountRepository
|
||||||
accountRepository: initializer.accountRepository,
|
|
||||||
metrics: metrics,
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: latestBlocksDataProvider
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(
|
internal init(
|
||||||
service: LightWalletService,
|
container: DIContainer,
|
||||||
storage: CompactBlockRepository,
|
|
||||||
rustBackend: ZcashRustBackendWelding,
|
|
||||||
config: Configuration,
|
config: Configuration,
|
||||||
repository: TransactionRepository,
|
accountRepository: AccountRepository
|
||||||
accountRepository: AccountRepository,
|
|
||||||
metrics: SDKMetrics,
|
|
||||||
logger: Logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
|
||||||
) {
|
) {
|
||||||
self.metrics = metrics
|
Dependencies.setupCompactBlockProcessor(
|
||||||
self.logger = logger
|
in: container,
|
||||||
self.latestBlocksDataProvider = latestBlocksDataProvider
|
config: config,
|
||||||
let internalSyncProgress = InternalSyncProgress(alias: config.alias, storage: UserDefaults.standard, logger: logger)
|
accountRepository: accountRepository
|
||||||
self.internalSyncProgress = internalSyncProgress
|
|
||||||
let blockDownloaderService = BlockDownloaderServiceImpl(service: service, storage: storage)
|
|
||||||
self.blockDownloader = BlockDownloaderImpl(
|
|
||||||
service: service,
|
|
||||||
downloaderService: blockDownloaderService,
|
|
||||||
storage: storage,
|
|
||||||
internalSyncProgress: internalSyncProgress,
|
|
||||||
metrics: metrics,
|
|
||||||
logger: logger
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.blockDownloaderService = blockDownloaderService
|
self.metrics = container.resolve(SDKMetrics.self)
|
||||||
|
self.logger = container.resolve(Logger.self)
|
||||||
self.blockValidator = BlockValidatorImpl(
|
self.latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
|
||||||
rustBackend: rustBackend,
|
self.internalSyncProgress = container.resolve(InternalSyncProgress.self)
|
||||||
metrics: metrics,
|
self.blockDownloaderService = container.resolve(BlockDownloaderService.self)
|
||||||
logger: logger
|
self.blockDownloader = container.resolve(BlockDownloader.self)
|
||||||
)
|
self.blockValidator = container.resolve(BlockValidator.self)
|
||||||
|
self.blockScanner = container.resolve(BlockScanner.self)
|
||||||
let blockScannerConfig = BlockScannerConfig(
|
self.blockEnhancer = container.resolve(BlockEnhancer.self)
|
||||||
networkType: config.network.networkType,
|
self.utxoFetcher = container.resolve(UTXOFetcher.self)
|
||||||
scanningBatchSize: config.scanningBatchSize
|
self.saplingParametersHandler = container.resolve(SaplingParametersHandler.self)
|
||||||
)
|
self.service = container.resolve(LightWalletService.self)
|
||||||
self.blockScanner = BlockScannerImpl(
|
self.rustBackend = container.resolve(ZcashRustBackendWelding.self)
|
||||||
config: blockScannerConfig,
|
self.storage = container.resolve(CompactBlockRepository.self)
|
||||||
rustBackend: rustBackend,
|
|
||||||
transactionRepository: repository,
|
|
||||||
metrics: metrics,
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: latestBlocksDataProvider
|
|
||||||
)
|
|
||||||
|
|
||||||
self.blockEnhancer = BlockEnhancerImpl(
|
|
||||||
blockDownloaderService: blockDownloaderService,
|
|
||||||
internalSyncProgress: internalSyncProgress,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
transactionRepository: repository,
|
|
||||||
metrics: metrics,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
let utxoFetcherConfig = UTXOFetcherConfig(walletBirthdayProvider: config.walletBirthdayProvider)
|
|
||||||
self.utxoFetcher = UTXOFetcherImpl(
|
|
||||||
accountRepository: accountRepository,
|
|
||||||
blockDownloaderService: blockDownloaderService,
|
|
||||||
config: utxoFetcherConfig,
|
|
||||||
internalSyncProgress: internalSyncProgress,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
metrics: metrics,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
let saplingParametersHandlerConfig = SaplingParametersHandlerConfig(
|
|
||||||
outputParamsURL: config.outputParamsURL,
|
|
||||||
spendParamsURL: config.spendParamsURL,
|
|
||||||
saplingParamsSourceURL: config.saplingParamsSourceURL
|
|
||||||
)
|
|
||||||
self.saplingParametersHandler = SaplingParametersHandlerImpl(
|
|
||||||
config: saplingParametersHandlerConfig,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
self.service = service
|
|
||||||
self.rustBackend = rustBackend
|
|
||||||
self.storage = storage
|
|
||||||
self.config = config
|
self.config = config
|
||||||
self.transactionRepository = repository
|
self.transactionRepository = container.resolve(TransactionRepository.self)
|
||||||
self.accountRepository = accountRepository
|
self.accountRepository = accountRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ class initializes the Rust backend and the supporting data required to exercise
|
||||||
The [cash.z.wallet.sdk.block.CompactBlockProcessor] handles all the remaining Rust backend
|
The [cash.z.wallet.sdk.block.CompactBlockProcessor] handles all the remaining Rust backend
|
||||||
functionality, related to processing blocks.
|
functionality, related to processing blocks.
|
||||||
*/
|
*/
|
||||||
|
// swiftlint:disable:next type_body_length
|
||||||
public class Initializer {
|
public class Initializer {
|
||||||
struct URLs {
|
struct URLs {
|
||||||
let fsBlockDbRoot: URL
|
let fsBlockDbRoot: URL
|
||||||
|
@ -107,6 +108,7 @@ public class Initializer {
|
||||||
// This is used to uniquely identify instance of the SDKSynchronizer. It's used when checking if the Alias is already used or not.
|
// This is used to uniquely identify instance of the SDKSynchronizer. It's used when checking if the Alias is already used or not.
|
||||||
let id = UUID()
|
let id = UUID()
|
||||||
|
|
||||||
|
let container: DIContainer
|
||||||
let alias: ZcashSynchronizerAlias
|
let alias: ZcashSynchronizerAlias
|
||||||
let endpoint: LightWalletEndpoint
|
let endpoint: LightWalletEndpoint
|
||||||
let fsBlockDbRoot: URL
|
let fsBlockDbRoot: URL
|
||||||
|
@ -156,87 +158,94 @@ public class Initializer {
|
||||||
alias: ZcashSynchronizerAlias = .default,
|
alias: ZcashSynchronizerAlias = .default,
|
||||||
loggingPolicy: LoggingPolicy = .default(.debug)
|
loggingPolicy: LoggingPolicy = .default(.debug)
|
||||||
) {
|
) {
|
||||||
let urls = URLs(
|
let container = DIContainer()
|
||||||
fsBlockDbRoot: fsBlockDbRoot,
|
|
||||||
dataDbURL: dataDbURL,
|
|
||||||
spendParamsURL: spendParamsURL,
|
|
||||||
outputParamsURL: outputParamsURL
|
|
||||||
)
|
|
||||||
|
|
||||||
// It's not possible to fail from constructor. Technically it's possible but it can be pain for the client apps to handle errors thrown
|
// It's not possible to fail from constructor. Technically it's possible but it can be pain for the client apps to handle errors thrown
|
||||||
// from constructor. So `parsingError` is just stored in initializer and `SDKSynchronizer.prepare()` throw this error if it exists.
|
// from constructor. So `parsingError` is just stored in initializer and `SDKSynchronizer.prepare()` throw this error if it exists.
|
||||||
let (updatedURLs, parsingError) = Self.tryToUpdateURLs(with: alias, urls: urls)
|
let (updatedURLs, parsingError) = Self.setup(
|
||||||
|
container: container,
|
||||||
let logger: Logger
|
cacheDbURL: cacheDbURL,
|
||||||
switch loggingPolicy {
|
fsBlockDbRoot: fsBlockDbRoot,
|
||||||
case let .default(logLevel):
|
dataDbURL: dataDbURL,
|
||||||
logger = OSLogger(logLevel: logLevel, alias: alias)
|
endpoint: endpoint,
|
||||||
case let .custom(customLogger):
|
|
||||||
logger = customLogger
|
|
||||||
case .noLogging:
|
|
||||||
logger = NullLogger()
|
|
||||||
}
|
|
||||||
|
|
||||||
let rustBackend = ZcashRustBackend(
|
|
||||||
dbData: updatedURLs.dataDbURL,
|
|
||||||
fsBlockDbRoot: updatedURLs.fsBlockDbRoot,
|
|
||||||
spendParamsPath: updatedURLs.spendParamsURL,
|
|
||||||
outputParamsPath: updatedURLs.outputParamsURL,
|
|
||||||
networkType: network.networkType
|
|
||||||
)
|
|
||||||
|
|
||||||
self.init(
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
network: network,
|
network: network,
|
||||||
|
spendParamsURL: spendParamsURL,
|
||||||
|
outputParamsURL: outputParamsURL,
|
||||||
|
saplingParamsSourceURL: saplingParamsSourceURL,
|
||||||
|
alias: alias,
|
||||||
|
loggingPolicy: loggingPolicy
|
||||||
|
)
|
||||||
|
|
||||||
|
self.init(
|
||||||
|
container: container,
|
||||||
cacheDbURL: cacheDbURL,
|
cacheDbURL: cacheDbURL,
|
||||||
urls: updatedURLs,
|
urls: updatedURLs,
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
service: Self.makeLightWalletServiceFactory(endpoint: endpoint).make(),
|
network: network,
|
||||||
repository: TransactionRepositoryBuilder.build(dataDbURL: updatedURLs.dataDbURL),
|
|
||||||
accountRepository: AccountRepositoryBuilder.build(
|
|
||||||
dataDbURL: updatedURLs.dataDbURL,
|
|
||||||
readOnly: true,
|
|
||||||
caching: true,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
storage: FSCompactBlockRepository(
|
|
||||||
fsBlockDbRoot: updatedURLs.fsBlockDbRoot,
|
|
||||||
metadataStore: .live(
|
|
||||||
fsBlockDbRoot: updatedURLs.fsBlockDbRoot,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: .live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
saplingParamsSourceURL: saplingParamsSourceURL,
|
saplingParamsSourceURL: saplingParamsSourceURL,
|
||||||
alias: alias,
|
alias: alias,
|
||||||
urlsParsingError: parsingError,
|
urlsParsingError: parsingError,
|
||||||
logger: logger
|
loggingPolicy: loggingPolicy
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal for dependency injection purposes.
|
/// Internal for dependency injection purposes.
|
||||||
///
|
convenience init(
|
||||||
/// !!! It's expected that URLs put here are already update with the Alias.
|
container: DIContainer,
|
||||||
init(
|
cacheDbURL: URL?,
|
||||||
rustBackend: ZcashRustBackendWelding,
|
fsBlockDbRoot: URL,
|
||||||
|
dataDbURL: URL,
|
||||||
|
endpoint: LightWalletEndpoint,
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
|
spendParamsURL: URL,
|
||||||
|
outputParamsURL: URL,
|
||||||
|
saplingParamsSourceURL: SaplingParamsSourceURL,
|
||||||
|
alias: ZcashSynchronizerAlias = .default,
|
||||||
|
loggingPolicy: LoggingPolicy = .default(.debug)
|
||||||
|
) {
|
||||||
|
// It's not possible to fail from constructor. Technically it's possible but it can be pain for the client apps to handle errors thrown
|
||||||
|
// from constructor. So `parsingError` is just stored in initializer and `SDKSynchronizer.prepare()` throw this error if it exists.
|
||||||
|
let (updatedURLs, parsingError) = Self.setup(
|
||||||
|
container: container,
|
||||||
|
cacheDbURL: cacheDbURL,
|
||||||
|
fsBlockDbRoot: fsBlockDbRoot,
|
||||||
|
dataDbURL: dataDbURL,
|
||||||
|
endpoint: endpoint,
|
||||||
|
network: network,
|
||||||
|
spendParamsURL: spendParamsURL,
|
||||||
|
outputParamsURL: outputParamsURL,
|
||||||
|
saplingParamsSourceURL: saplingParamsSourceURL,
|
||||||
|
alias: alias,
|
||||||
|
loggingPolicy: loggingPolicy
|
||||||
|
)
|
||||||
|
|
||||||
|
self.init(
|
||||||
|
container: container,
|
||||||
|
cacheDbURL: cacheDbURL,
|
||||||
|
urls: updatedURLs,
|
||||||
|
endpoint: endpoint,
|
||||||
|
network: network,
|
||||||
|
saplingParamsSourceURL: saplingParamsSourceURL,
|
||||||
|
alias: alias,
|
||||||
|
urlsParsingError: parsingError,
|
||||||
|
loggingPolicy: loggingPolicy
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private init(
|
||||||
|
container: DIContainer,
|
||||||
cacheDbURL: URL?,
|
cacheDbURL: URL?,
|
||||||
urls: URLs,
|
urls: URLs,
|
||||||
endpoint: LightWalletEndpoint,
|
endpoint: LightWalletEndpoint,
|
||||||
service: LightWalletService,
|
network: ZcashNetwork,
|
||||||
repository: TransactionRepository,
|
|
||||||
accountRepository: AccountRepository,
|
|
||||||
storage: CompactBlockRepository,
|
|
||||||
saplingParamsSourceURL: SaplingParamsSourceURL,
|
saplingParamsSourceURL: SaplingParamsSourceURL,
|
||||||
alias: ZcashSynchronizerAlias,
|
alias: ZcashSynchronizerAlias,
|
||||||
urlsParsingError: ZcashError?,
|
urlsParsingError: ZcashError?,
|
||||||
logger: Logger
|
loggingPolicy: LoggingPolicy = .default(.debug)
|
||||||
) {
|
) {
|
||||||
|
self.container = container
|
||||||
self.cacheDbURL = cacheDbURL
|
self.cacheDbURL = cacheDbURL
|
||||||
self.rustBackend = rustBackend
|
self.rustBackend = container.resolve(ZcashRustBackendWelding.self)
|
||||||
self.fsBlockDbRoot = urls.fsBlockDbRoot
|
self.fsBlockDbRoot = urls.fsBlockDbRoot
|
||||||
self.dataDbURL = urls.dataDbURL
|
self.dataDbURL = urls.dataDbURL
|
||||||
self.endpoint = endpoint
|
self.endpoint = endpoint
|
||||||
|
@ -244,20 +253,62 @@ public class Initializer {
|
||||||
self.outputParamsURL = urls.outputParamsURL
|
self.outputParamsURL = urls.outputParamsURL
|
||||||
self.saplingParamsSourceURL = saplingParamsSourceURL
|
self.saplingParamsSourceURL = saplingParamsSourceURL
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
self.lightWalletService = service
|
self.lightWalletService = container.resolve(LightWalletService.self)
|
||||||
self.transactionRepository = repository
|
self.transactionRepository = container.resolve(TransactionRepository.self)
|
||||||
self.accountRepository = accountRepository
|
self.accountRepository = AccountRepositoryBuilder.build(
|
||||||
self.storage = storage
|
dataDbURL: urls.dataDbURL,
|
||||||
self.blockDownloaderService = BlockDownloaderServiceImpl(service: service, storage: storage)
|
readOnly: true,
|
||||||
|
caching: true,
|
||||||
|
logger: container.resolve(Logger.self)
|
||||||
|
)
|
||||||
|
self.storage = container.resolve(CompactBlockRepository.self)
|
||||||
|
self.blockDownloaderService = container.resolve(BlockDownloaderService.self)
|
||||||
self.network = network
|
self.network = network
|
||||||
self.walletBirthday = Checkpoint.birthday(with: 0, network: network).height
|
self.walletBirthday = Checkpoint.birthday(with: 0, network: network).height
|
||||||
self.urlsParsingError = urlsParsingError
|
self.urlsParsingError = urlsParsingError
|
||||||
self.logger = logger
|
self.logger = container.resolve(Logger.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func makeLightWalletServiceFactory(endpoint: LightWalletEndpoint) -> LightWalletServiceFactory {
|
private static func makeLightWalletServiceFactory(endpoint: LightWalletEndpoint) -> LightWalletServiceFactory {
|
||||||
return LightWalletServiceFactory(endpoint: endpoint)
|
return LightWalletServiceFactory(endpoint: endpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable:next function_parameter_count
|
||||||
|
private static func setup(
|
||||||
|
container: DIContainer,
|
||||||
|
cacheDbURL: URL?,
|
||||||
|
fsBlockDbRoot: URL,
|
||||||
|
dataDbURL: URL,
|
||||||
|
endpoint: LightWalletEndpoint,
|
||||||
|
network: ZcashNetwork,
|
||||||
|
spendParamsURL: URL,
|
||||||
|
outputParamsURL: URL,
|
||||||
|
saplingParamsSourceURL: SaplingParamsSourceURL,
|
||||||
|
alias: ZcashSynchronizerAlias,
|
||||||
|
loggingPolicy: LoggingPolicy = .default(.debug)
|
||||||
|
) -> (URLs, ZcashError?) {
|
||||||
|
let urls = URLs(
|
||||||
|
fsBlockDbRoot: fsBlockDbRoot,
|
||||||
|
dataDbURL: dataDbURL,
|
||||||
|
spendParamsURL: spendParamsURL,
|
||||||
|
outputParamsURL: outputParamsURL
|
||||||
|
)
|
||||||
|
|
||||||
|
// It's not possible to fail from constructor. Technically it's possible but it can be pain for the client apps to handle errors thrown
|
||||||
|
// from constructor. So `parsingError` is just stored in initializer and `SDKSynchronizer.prepare()` throw this error if it exists.
|
||||||
|
let (updatedURLs, parsingError) = Self.tryToUpdateURLs(with: alias, urls: urls)
|
||||||
|
|
||||||
|
Dependencies.setup(
|
||||||
|
in: container,
|
||||||
|
urls: updatedURLs,
|
||||||
|
alias: alias,
|
||||||
|
networkType: network.networkType,
|
||||||
|
endpoint: endpoint,
|
||||||
|
loggingPolicy: loggingPolicy
|
||||||
|
)
|
||||||
|
|
||||||
|
return (updatedURLs, parsingError)
|
||||||
|
}
|
||||||
|
|
||||||
/// Try to update URLs with `alias`.
|
/// Try to update URLs with `alias`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -0,0 +1,208 @@
|
||||||
|
//
|
||||||
|
// Dependencies.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 01.05.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum Dependencies {
|
||||||
|
// swiftlint:disable:next function_parameter_count
|
||||||
|
static func setup(
|
||||||
|
in container: DIContainer,
|
||||||
|
urls: Initializer.URLs,
|
||||||
|
alias: ZcashSynchronizerAlias,
|
||||||
|
networkType: NetworkType,
|
||||||
|
endpoint: LightWalletEndpoint,
|
||||||
|
loggingPolicy: Initializer.LoggingPolicy = .default(.debug)
|
||||||
|
) {
|
||||||
|
container.register(type: Logger.self, isSingleton: true) { _ in
|
||||||
|
let logger: Logger
|
||||||
|
switch loggingPolicy {
|
||||||
|
case let .default(logLevel):
|
||||||
|
logger = OSLogger(logLevel: logLevel, alias: alias)
|
||||||
|
case let .custom(customLogger):
|
||||||
|
logger = customLogger
|
||||||
|
case .noLogging:
|
||||||
|
logger = NullLogger()
|
||||||
|
}
|
||||||
|
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in
|
||||||
|
return ZcashRustBackend(
|
||||||
|
dbData: urls.dataDbURL,
|
||||||
|
fsBlockDbRoot: urls.fsBlockDbRoot,
|
||||||
|
spendParamsPath: urls.spendParamsURL,
|
||||||
|
outputParamsPath: urls.outputParamsURL,
|
||||||
|
networkType: networkType
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: LightWalletService.self, isSingleton: true) { _ in
|
||||||
|
return LightWalletGRPCService(endpoint: endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: TransactionRepository.self, isSingleton: true) { _ in
|
||||||
|
TransactionSQLDAO(dbProvider: SimpleConnectionProvider(path: urls.dataDbURL.path, readonly: true))
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: CompactBlockRepository.self, isSingleton: true) { di in
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
let rustBackend = di.resolve(ZcashRustBackendWelding.self)
|
||||||
|
|
||||||
|
return FSCompactBlockRepository(
|
||||||
|
fsBlockDbRoot: urls.fsBlockDbRoot,
|
||||||
|
metadataStore: .live(
|
||||||
|
fsBlockDbRoot: urls.fsBlockDbRoot,
|
||||||
|
rustBackend: rustBackend,
|
||||||
|
logger: logger
|
||||||
|
),
|
||||||
|
blockDescriptor: .live,
|
||||||
|
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||||
|
logger: logger
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: BlockDownloaderService.self, isSingleton: true) { di in
|
||||||
|
let service = di.resolve(LightWalletService.self)
|
||||||
|
let storage = di.resolve(CompactBlockRepository.self)
|
||||||
|
|
||||||
|
return BlockDownloaderServiceImpl(service: service, storage: storage)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: SDKMetrics.self, isSingleton: true) { _ in
|
||||||
|
SDKMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: LatestBlocksDataProvider.self, isSingleton: true) { di in
|
||||||
|
let service = di.resolve(LightWalletService.self)
|
||||||
|
let transactionRepository = di.resolve(TransactionRepository.self)
|
||||||
|
|
||||||
|
return LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: SyncSessionIDGenerator.self, isSingleton: false) { _ in
|
||||||
|
UniqueSyncSessionIDGenerator()
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: InternalSyncProgress.self, isSingleton: true) { di in
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
return InternalSyncProgress(alias: alias, storage: UserDefaults.standard, logger: logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func setupCompactBlockProcessor(
|
||||||
|
in container: DIContainer,
|
||||||
|
config: CompactBlockProcessor.Configuration,
|
||||||
|
accountRepository: AccountRepository
|
||||||
|
) {
|
||||||
|
container.register(type: BlockDownloader.self, isSingleton: true) { di in
|
||||||
|
let service = di.resolve(LightWalletService.self)
|
||||||
|
let blockDownloaderService = di.resolve(BlockDownloaderService.self)
|
||||||
|
let storage = di.resolve(CompactBlockRepository.self)
|
||||||
|
let internalSyncProgress = di.resolve(InternalSyncProgress.self)
|
||||||
|
let metrics = di.resolve(SDKMetrics.self)
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
|
||||||
|
return BlockDownloaderImpl(
|
||||||
|
service: service,
|
||||||
|
downloaderService: blockDownloaderService,
|
||||||
|
storage: storage,
|
||||||
|
internalSyncProgress: internalSyncProgress,
|
||||||
|
metrics: metrics,
|
||||||
|
logger: logger
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: BlockValidator.self, isSingleton: true) { di in
|
||||||
|
let rustBackend = di.resolve(ZcashRustBackendWelding.self)
|
||||||
|
let metrics = di.resolve(SDKMetrics.self)
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
|
||||||
|
return BlockValidatorImpl(
|
||||||
|
rustBackend: rustBackend,
|
||||||
|
metrics: metrics,
|
||||||
|
logger: logger
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: BlockScanner.self, isSingleton: true) { di in
|
||||||
|
let rustBackend = di.resolve(ZcashRustBackendWelding.self)
|
||||||
|
let transactionRepository = di.resolve(TransactionRepository.self)
|
||||||
|
let metrics = di.resolve(SDKMetrics.self)
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
let latestBlocksDataProvider = di.resolve(LatestBlocksDataProvider.self)
|
||||||
|
|
||||||
|
let blockScannerConfig = BlockScannerConfig(
|
||||||
|
networkType: config.network.networkType,
|
||||||
|
scanningBatchSize: config.scanningBatchSize
|
||||||
|
)
|
||||||
|
|
||||||
|
return BlockScannerImpl(
|
||||||
|
config: blockScannerConfig,
|
||||||
|
rustBackend: rustBackend,
|
||||||
|
transactionRepository: transactionRepository,
|
||||||
|
metrics: metrics,
|
||||||
|
logger: logger,
|
||||||
|
latestBlocksDataProvider: latestBlocksDataProvider
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: BlockEnhancer.self, isSingleton: true) { di in
|
||||||
|
let blockDownloaderService = di.resolve(BlockDownloaderService.self)
|
||||||
|
let internalSyncProgress = di.resolve(InternalSyncProgress.self)
|
||||||
|
let rustBackend = di.resolve(ZcashRustBackendWelding.self)
|
||||||
|
let transactionRepository = di.resolve(TransactionRepository.self)
|
||||||
|
let metrics = di.resolve(SDKMetrics.self)
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
|
||||||
|
return BlockEnhancerImpl(
|
||||||
|
blockDownloaderService: blockDownloaderService,
|
||||||
|
internalSyncProgress: internalSyncProgress,
|
||||||
|
rustBackend: rustBackend,
|
||||||
|
transactionRepository: transactionRepository,
|
||||||
|
metrics: metrics,
|
||||||
|
logger: logger
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: UTXOFetcher.self, isSingleton: true) { di in
|
||||||
|
let blockDownloaderService = di.resolve(BlockDownloaderService.self)
|
||||||
|
let utxoFetcherConfig = UTXOFetcherConfig(walletBirthdayProvider: config.walletBirthdayProvider)
|
||||||
|
let internalSyncProgress = di.resolve(InternalSyncProgress.self)
|
||||||
|
let rustBackend = di.resolve(ZcashRustBackendWelding.self)
|
||||||
|
let metrics = di.resolve(SDKMetrics.self)
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
|
||||||
|
return UTXOFetcherImpl(
|
||||||
|
accountRepository: accountRepository,
|
||||||
|
blockDownloaderService: blockDownloaderService,
|
||||||
|
config: utxoFetcherConfig,
|
||||||
|
internalSyncProgress: internalSyncProgress,
|
||||||
|
rustBackend: rustBackend,
|
||||||
|
metrics: metrics,
|
||||||
|
logger: logger
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.register(type: SaplingParametersHandler.self, isSingleton: true) { di in
|
||||||
|
let rustBackend = di.resolve(ZcashRustBackendWelding.self)
|
||||||
|
let logger = di.resolve(Logger.self)
|
||||||
|
|
||||||
|
let saplingParametersHandlerConfig = SaplingParametersHandlerConfig(
|
||||||
|
outputParamsURL: config.outputParamsURL,
|
||||||
|
spendParamsURL: config.spendParamsURL,
|
||||||
|
saplingParamsSourceURL: config.saplingParamsSourceURL
|
||||||
|
)
|
||||||
|
|
||||||
|
return SaplingParametersHandlerImpl(
|
||||||
|
config: saplingParametersHandlerConfig,
|
||||||
|
rustBackend: rustBackend,
|
||||||
|
logger: logger
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,11 +50,6 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
/// Creates an SDKSynchronizer instance
|
/// Creates an SDKSynchronizer instance
|
||||||
/// - Parameter initializer: a wallet Initializer object
|
/// - Parameter initializer: a wallet Initializer object
|
||||||
public convenience init(initializer: Initializer) {
|
public convenience init(initializer: Initializer) {
|
||||||
let metrics = SDKMetrics()
|
|
||||||
let latestBlocksDataProvider = LatestBlocksDataProviderImpl(
|
|
||||||
service: initializer.lightWalletService,
|
|
||||||
transactionRepository: initializer.transactionRepository
|
|
||||||
)
|
|
||||||
self.init(
|
self.init(
|
||||||
status: .unprepared,
|
status: .unprepared,
|
||||||
initializer: initializer,
|
initializer: initializer,
|
||||||
|
@ -63,15 +58,9 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
utxoRepository: UTXORepositoryBuilder.build(initializer: initializer),
|
utxoRepository: UTXORepositoryBuilder.build(initializer: initializer),
|
||||||
blockProcessor: CompactBlockProcessor(
|
blockProcessor: CompactBlockProcessor(
|
||||||
initializer: initializer,
|
initializer: initializer,
|
||||||
metrics: metrics,
|
|
||||||
logger: initializer.logger,
|
|
||||||
latestBlocksDataProvider: latestBlocksDataProvider,
|
|
||||||
walletBirthdayProvider: { initializer.walletBirthday }
|
walletBirthdayProvider: { initializer.walletBirthday }
|
||||||
),
|
),
|
||||||
metrics: metrics,
|
syncSessionTicker: .live
|
||||||
syncSessionIDGenerator: UniqueSyncSessionIDGenerator(),
|
|
||||||
syncSessionTicker: .live,
|
|
||||||
latestBlocksDataProvider: latestBlocksDataProvider
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +71,7 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
transactionRepository: TransactionRepository,
|
transactionRepository: TransactionRepository,
|
||||||
utxoRepository: UnspentTransactionOutputRepository,
|
utxoRepository: UnspentTransactionOutputRepository,
|
||||||
blockProcessor: CompactBlockProcessor,
|
blockProcessor: CompactBlockProcessor,
|
||||||
metrics: SDKMetrics,
|
syncSessionTicker: SessionTicker
|
||||||
syncSessionIDGenerator: SyncSessionIDGenerator,
|
|
||||||
syncSessionTicker: SessionTicker,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
|
||||||
) {
|
) {
|
||||||
self.connectionState = .idle
|
self.connectionState = .idle
|
||||||
self.underlyingStatus = GenericActor(status)
|
self.underlyingStatus = GenericActor(status)
|
||||||
|
@ -95,12 +81,12 @@ public class SDKSynchronizer: Synchronizer {
|
||||||
self.utxoRepository = utxoRepository
|
self.utxoRepository = utxoRepository
|
||||||
self.blockProcessor = blockProcessor
|
self.blockProcessor = blockProcessor
|
||||||
self.network = initializer.network
|
self.network = initializer.network
|
||||||
self.metrics = metrics
|
self.metrics = initializer.container.resolve(SDKMetrics.self)
|
||||||
self.logger = initializer.logger
|
self.logger = initializer.logger
|
||||||
self.syncSessionIDGenerator = syncSessionIDGenerator
|
self.syncSessionIDGenerator = initializer.container.resolve(SyncSessionIDGenerator.self)
|
||||||
self.syncSession = SyncSession(.nullID)
|
self.syncSession = SyncSession(.nullID)
|
||||||
self.syncSessionTicker = syncSessionTicker
|
self.syncSessionTicker = syncSessionTicker
|
||||||
self.latestBlocksDataProvider = latestBlocksDataProvider
|
self.latestBlocksDataProvider = initializer.container.resolve(LatestBlocksDataProvider.self)
|
||||||
|
|
||||||
initializer.lightWalletService.connectionStateChange = { [weak self] oldState, newState in
|
initializer.lightWalletService.connectionStateChange = { [weak self] oldState, newState in
|
||||||
self?.connectivityStateChanged(oldState: oldState, newState: newState)
|
self?.connectivityStateChanged(oldState: oldState, newState: newState)
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
//
|
||||||
|
// DIContainer.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 01.05.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// This class represents depedency injection containers.
|
||||||
|
class DIContainer {
|
||||||
|
/// Structure that represents one registered dependency.
|
||||||
|
struct Dependency {
|
||||||
|
/// Closure which creates instance of the dependency.
|
||||||
|
let factory: (DIContainer) -> Any
|
||||||
|
/// Indicates if dependency is singleton. If this is `true` then `DIContainer` creates only one instance of this dependency and returns
|
||||||
|
/// it every time `resolve()` for the dependency is called.
|
||||||
|
let isSingleton: Bool
|
||||||
|
/// If the dependency is singleton then instance is stored here.
|
||||||
|
let instance: Any?
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If this is `true` then `mockedDependencies` is used first to resolve dependencies. This is used for mocking in tests.
|
||||||
|
var isTestEnvironment = false
|
||||||
|
|
||||||
|
private let lock = NSRecursiveLock()
|
||||||
|
/// Dependencies are stored here.
|
||||||
|
private var dependencies: [String: Dependency] = [:]
|
||||||
|
/// Mocked dependencies are stored here.
|
||||||
|
private var mockedDependencies: [String: Dependency] = [:]
|
||||||
|
|
||||||
|
init() { }
|
||||||
|
|
||||||
|
private func key<T>(for type: T.Type) -> String {
|
||||||
|
return String(describing: T.self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func register<T>(type: T.Type, isSingleton: Bool, factory: @escaping (DIContainer) -> T) {
|
||||||
|
lock.lock()
|
||||||
|
let key = self.key(for: type)
|
||||||
|
let depedency = Dependency(factory: factory, isSingleton: isSingleton, instance: nil)
|
||||||
|
dependencies[key] = depedency
|
||||||
|
lock.unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func mock<T>(type: T.Type, isSingleton: Bool, factory: @escaping (DIContainer) -> T) {
|
||||||
|
lock.lock()
|
||||||
|
let key = self.key(for: type)
|
||||||
|
let depedency = Dependency(factory: factory, isSingleton: isSingleton, instance: nil)
|
||||||
|
mockedDependencies[key] = depedency
|
||||||
|
lock.unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolve<T>(_ type: T.Type) -> T {
|
||||||
|
lock.lock()
|
||||||
|
defer { lock.unlock() }
|
||||||
|
let key = self.key(for: type)
|
||||||
|
|
||||||
|
let possibleDependency = (isTestEnvironment ? mockedDependencies[key] : dependencies[key]) ?? dependencies[key]
|
||||||
|
guard let dependency = possibleDependency else {
|
||||||
|
// When dependency is resolved before it's registered then the app crashes. It would be possible to not crash and throw some error here.
|
||||||
|
// But it complicates the rest of the code. And maybe it doesn't make sense because this kind of error is not recoverable. It can be fixed
|
||||||
|
// only by updating the code.
|
||||||
|
fatalError("Doesn't have registered dependency for type \(type).")
|
||||||
|
}
|
||||||
|
|
||||||
|
let instance: Any
|
||||||
|
if dependency.isSingleton, let singleton = dependency.instance {
|
||||||
|
instance = singleton
|
||||||
|
} else {
|
||||||
|
instance = dependency.factory(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dependency.isSingleton && dependency.instance == nil {
|
||||||
|
dependencies[key] = Dependency(factory: dependency.factory, isSingleton: dependency.isSingleton, instance: instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let instance = instance as? T else {
|
||||||
|
// When dependency is resolved but instance of created depedency is different than expected type the app crashes. It would be possible to
|
||||||
|
// not crash and throw some error here. But it complicates the rest of the code. And maybe it doesn't make sense because this kind of
|
||||||
|
// error is not recoverable. It can be fixed only by updating the code.
|
||||||
|
fatalError("Getting dependency for type \(type) but created instance is \(instance)")
|
||||||
|
}
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ import XCTest
|
||||||
5. Run this test.
|
5. Run this test.
|
||||||
6. When you are done use `kill_and_clean_servers.zsh` script to shutdown servers and clean all the data (pidfile, rundirs, logs).
|
6. When you are done use `kill_and_clean_servers.zsh` script to shutdown servers and clean all the data (pidfile, rundirs, logs).
|
||||||
*/
|
*/
|
||||||
class SDKSynchronizerAliasDarksideTests: XCTestCase {
|
class SDKSynchronizerAliasDarksideTests: ZcashTestCase {
|
||||||
// Test creates instance of the `SDKSynchronizer` for each of these aliases.
|
// Test creates instance of the `SDKSynchronizer` for each of these aliases.
|
||||||
let aliases: [ZcashSynchronizerAlias] = [.default, .custom("custom-1"), .custom("custom-2"), .custom("custom-3"), .custom("custom-4")]
|
let aliases: [ZcashSynchronizerAlias] = [.default, .custom("custom-1"), .custom("custom-2"), .custom("custom-3"), .custom("custom-4")]
|
||||||
// First instance of the `SDKSynchronizer` uses this port. Second one uses startPort + 1, thirs one uses startPort + 2 and so on.
|
// First instance of the `SDKSynchronizer` uses this port. Second one uses startPort + 1, thirs one uses startPort + 2 and so on.
|
||||||
|
@ -52,6 +52,7 @@ class SDKSynchronizerAliasDarksideTests: XCTestCase {
|
||||||
|
|
||||||
let coordinator = try await TestCoordinator(
|
let coordinator = try await TestCoordinator(
|
||||||
alias: alias,
|
alias: alias,
|
||||||
|
container: mockContainer,
|
||||||
walletBirthday: birthday,
|
walletBirthday: birthday,
|
||||||
network: network,
|
network: network,
|
||||||
callPrepareInConstructor: true,
|
callPrepareInConstructor: true,
|
||||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class AdvancedReOrgTests: XCTestCase {
|
class AdvancedReOrgTests: ZcashTestCase {
|
||||||
let sendAmount = Zatoshi(1000)
|
let sendAmount = Zatoshi(1000)
|
||||||
var birthday: BlockHeight = 663150
|
var birthday: BlockHeight = 663150
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
|
@ -29,11 +29,10 @@ class AdvancedReOrgTests: XCTestCase {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
// don't use an exact birthday, users never do.
|
// don't use an exact birthday, users never do.
|
||||||
self.coordinator = try await TestCoordinator(
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
walletBirthday: birthday + 50,
|
walletBirthday: birthday + 50,
|
||||||
network: network,
|
network: network
|
||||||
dbTracingClosure: { logger.debug($0) }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class BalanceTests: XCTestCase {
|
class BalanceTests: ZcashTestCase {
|
||||||
let sendAmount = Zatoshi(1000)
|
let sendAmount = Zatoshi(1000)
|
||||||
let defaultLatestHeight: BlockHeight = 663188
|
let defaultLatestHeight: BlockHeight = 663188
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
|
@ -25,7 +25,11 @@ class BalanceTests: XCTestCase {
|
||||||
|
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class DarksideSanityCheckTests: XCTestCase {
|
class DarksideSanityCheckTests: ZcashTestCase {
|
||||||
let sendAmount: Int64 = 1000
|
let sendAmount: Int64 = 1000
|
||||||
var birthday: BlockHeight = 663150
|
var birthday: BlockHeight = 663150
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
|
@ -27,7 +27,11 @@ class DarksideSanityCheckTests: XCTestCase {
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
|
|
||||||
try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
|
try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
|
||||||
try self.coordinator.resetBlocks(dataset: .default)
|
try self.coordinator.resetBlocks(dataset: .default)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
final class InternalStateConsistencyTests: XCTestCase {
|
final class InternalStateConsistencyTests: ZcashTestCase {
|
||||||
let sendAmount = Zatoshi(1000)
|
let sendAmount = Zatoshi(1000)
|
||||||
var birthday: BlockHeight = 663150
|
var birthday: BlockHeight = 663150
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
|
@ -28,7 +28,12 @@ final class InternalStateConsistencyTests: XCTestCase {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
// don't use an exact birthday, users never do.
|
// don't use an exact birthday, users never do.
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday + 50, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday + 50,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
|
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class PendingTransactionUpdatesTest: XCTestCase {
|
class PendingTransactionUpdatesTest: ZcashTestCase {
|
||||||
let sendAmount: Int64 = 1000
|
let sendAmount: Int64 = 1000
|
||||||
var birthday: BlockHeight = 663150
|
var birthday: BlockHeight = 663150
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
|
@ -25,7 +25,11 @@ class PendingTransactionUpdatesTest: XCTestCase {
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ basic reorg test. Scan, get a reorg and then reach latest height.
|
||||||
* observe that the prev hash of that block does not match the hash that we have for 663250
|
* observe that the prev hash of that block does not match the hash that we have for 663250
|
||||||
* rewind 10 blocks and request blocks 663241 to 663251
|
* rewind 10 blocks and request blocks 663241 to 663251
|
||||||
*/
|
*/
|
||||||
class ReOrgTests: XCTestCase {
|
class ReOrgTests: ZcashTestCase {
|
||||||
let sendAmount: Int64 = 1000
|
let sendAmount: Int64 = 1000
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
let network = DarksideWalletDNetwork()
|
let network = DarksideWalletDNetwork()
|
||||||
|
@ -44,7 +44,11 @@ class ReOrgTests: XCTestCase {
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: self.birthday, network: self.network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: self.birthday,
|
||||||
|
network: self.network
|
||||||
|
)
|
||||||
|
|
||||||
try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
|
try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
// FIXME: [#586] disabled until this is resolved https://github.com/zcash/ZcashLightClientKit/issues/586
|
// FIXME: [#586] disabled until this is resolved https://github.com/zcash/ZcashLightClientKit/issues/586
|
||||||
class RewindRescanTests: XCTestCase {
|
class RewindRescanTests: ZcashTestCase {
|
||||||
let sendAmount: Int64 = 1000
|
let sendAmount: Int64 = 1000
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
|
@ -30,7 +30,11 @@ class RewindRescanTests: XCTestCase {
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
// FIXME: [#587] disabled until https://github.com/zcash/ZcashLightClientKit/issues/587 fixed
|
// FIXME: [#587] disabled until https://github.com/zcash/ZcashLightClientKit/issues/587 fixed
|
||||||
class ShieldFundsTests: XCTestCase {
|
class ShieldFundsTests: ZcashTestCase {
|
||||||
let sendAmount = Zatoshi(1000)
|
let sendAmount = Zatoshi(1000)
|
||||||
var birthday: BlockHeight = 1631000
|
var birthday: BlockHeight = 1631000
|
||||||
var coordinator: TestCoordinator!
|
var coordinator: TestCoordinator!
|
||||||
|
@ -25,7 +25,11 @@ class ShieldFundsTests: XCTestCase {
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
try coordinator.reset(saplingActivation: birthday, branchID: self.branchID, chainName: self.chainName)
|
try coordinator.reset(saplingActivation: birthday, branchID: self.branchID, chainName: self.chainName)
|
||||||
try coordinator.service.clearAddedUTXOs()
|
try coordinator.service.clearAddedUTXOs()
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Combine
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class SynchronizerDarksideTests: XCTestCase {
|
class SynchronizerDarksideTests: ZcashTestCase {
|
||||||
let sendAmount: Int64 = 1000
|
let sendAmount: Int64 = 1000
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
let branchID = "2bb40e60"
|
let branchID = "2bb40e60"
|
||||||
|
@ -30,8 +30,16 @@ class SynchronizerDarksideTests: XCTestCase {
|
||||||
|
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
idGenerator = MockSyncSessionIDGenerator(ids: [.deadbeef])
|
let idGenerator = MockSyncSessionIDGenerator(ids: [.deadbeef])
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network, syncSessionIDGenerator: idGenerator)
|
mockContainer.mock(type: SyncSessionIDGenerator.self, isSingleton: false) { _ in idGenerator }
|
||||||
|
self.idGenerator = idGenerator
|
||||||
|
|
||||||
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
|
|
||||||
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,14 +303,11 @@ class SynchronizerDarksideTests: XCTestCase {
|
||||||
]
|
]
|
||||||
|
|
||||||
XCTAssertEqual(states.count, expectedStates.count)
|
XCTAssertEqual(states.count, expectedStates.count)
|
||||||
XCTAssertEqual(states[0], expectedStates[0])
|
|
||||||
XCTAssertEqual(states[1], expectedStates[1])
|
for (index, state) in states.enumerated() {
|
||||||
XCTAssertEqual(states[2], expectedStates[2])
|
let expectedState = expectedStates[index]
|
||||||
XCTAssertEqual(states[3], expectedStates[3])
|
XCTAssertEqual(state, expectedState, "Failed state comparison at index \(index).")
|
||||||
XCTAssertEqual(states[4], expectedStates[4])
|
}
|
||||||
XCTAssertEqual(states[5], expectedStates[5])
|
|
||||||
XCTAssertEqual(states[6], expectedStates[6])
|
|
||||||
XCTAssertEqual(states[7], expectedStates[7])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSyncSessionUpdates() async throws {
|
func testSyncSessionUpdates() async throws {
|
||||||
|
@ -458,13 +463,11 @@ class SynchronizerDarksideTests: XCTestCase {
|
||||||
]
|
]
|
||||||
|
|
||||||
XCTAssertEqual(states.count, expectedStates.count)
|
XCTAssertEqual(states.count, expectedStates.count)
|
||||||
XCTAssertEqual(states[0], expectedStates[0])
|
|
||||||
XCTAssertEqual(states[1], expectedStates[1])
|
for (index, state) in states.enumerated() {
|
||||||
XCTAssertEqual(states[2], expectedStates[2])
|
let expectedState = expectedStates[index]
|
||||||
XCTAssertEqual(states[3], expectedStates[3])
|
XCTAssertEqual(state, expectedState, "Failed state comparison at index \(index).")
|
||||||
XCTAssertEqual(states[4], expectedStates[4])
|
}
|
||||||
XCTAssertEqual(states[5], expectedStates[5])
|
|
||||||
XCTAssertEqual(states[7], expectedStates[7])
|
|
||||||
|
|
||||||
try coordinator.service.applyStaged(nextLatestHeight: 663_200)
|
try coordinator.service.applyStaged(nextLatestHeight: 663_200)
|
||||||
|
|
||||||
|
@ -532,11 +535,11 @@ class SynchronizerDarksideTests: XCTestCase {
|
||||||
]
|
]
|
||||||
|
|
||||||
XCTAssertEqual(states.count, secondBatchOfExpectedStates.count)
|
XCTAssertEqual(states.count, secondBatchOfExpectedStates.count)
|
||||||
XCTAssertEqual(states[0], secondBatchOfExpectedStates[0])
|
|
||||||
XCTAssertEqual(states[1], secondBatchOfExpectedStates[1])
|
for (index, state) in states.enumerated() {
|
||||||
XCTAssertEqual(states[2], secondBatchOfExpectedStates[2])
|
let expectedState = secondBatchOfExpectedStates[index]
|
||||||
XCTAssertEqual(states[3], secondBatchOfExpectedStates[3])
|
XCTAssertEqual(state, expectedState, "Failed state comparison at index \(index).")
|
||||||
XCTAssertEqual(states[4], secondBatchOfExpectedStates[4])
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSyncAfterWipeWorks() async throws {
|
func testSyncAfterWipeWorks() async throws {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
final class SynchronizerTests: XCTestCase {
|
final class SynchronizerTests: ZcashTestCase {
|
||||||
let sendAmount = Zatoshi(1000)
|
let sendAmount = Zatoshi(1000)
|
||||||
var birthday: BlockHeight = 663150
|
var birthday: BlockHeight = 663150
|
||||||
let defaultLatestHeight: BlockHeight = 663175
|
let defaultLatestHeight: BlockHeight = 663175
|
||||||
|
@ -28,7 +28,11 @@ final class SynchronizerTests: XCTestCase {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
// don't use an exact birthday, users never do.
|
// don't use an exact birthday, users never do.
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday + 50, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday + 50,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
||||||
|
|
||||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class TransactionEnhancementTests: XCTestCase {
|
class TransactionEnhancementTests: ZcashTestCase {
|
||||||
var cancellables: [AnyCancellable] = []
|
var cancellables: [AnyCancellable] = []
|
||||||
var processorEventHandler: CompactBlockProcessorEventHandler! = CompactBlockProcessorEventHandler()
|
var processorEventHandler: CompactBlockProcessorEventHandler! = CompactBlockProcessorEventHandler()
|
||||||
let mockLatestHeight = BlockHeight(663250)
|
let mockLatestHeight = BlockHeight(663250)
|
||||||
|
@ -134,14 +134,29 @@ class TransactionEnhancementTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
downloader = BlockDownloaderServiceImpl(service: service, storage: storage)
|
downloader = BlockDownloaderServiceImpl(service: service, storage: storage)
|
||||||
|
|
||||||
|
Dependencies.setup(
|
||||||
|
in: mockContainer,
|
||||||
|
urls: Initializer.URLs(
|
||||||
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
dataDbURL: pathProvider.dataDbURL,
|
||||||
|
spendParamsURL: pathProvider.spendParamsURL,
|
||||||
|
outputParamsURL: pathProvider.outputParamsURL
|
||||||
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
|
)
|
||||||
|
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in
|
||||||
|
LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||||
|
}
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in self.rustBackend }
|
||||||
|
|
||||||
processor = CompactBlockProcessor(
|
processor = CompactBlockProcessor(
|
||||||
service: service,
|
container: mockContainer,
|
||||||
storage: storage,
|
config: processorConfig
|
||||||
rustBackend: rustBackend,
|
|
||||||
config: processorConfig,
|
|
||||||
metrics: SDKMetrics(),
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class Z2TReceiveTests: XCTestCase {
|
class Z2TReceiveTests: ZcashTestCase {
|
||||||
let testRecipientAddress = "t1dRJRY7GmyeykJnMH38mdQoaZtFhn1QmGz"
|
let testRecipientAddress = "t1dRJRY7GmyeykJnMH38mdQoaZtFhn1QmGz"
|
||||||
let sendAmount: Int64 = 1000
|
let sendAmount: Int64 = 1000
|
||||||
var birthday: BlockHeight = 663150
|
var birthday: BlockHeight = 663150
|
||||||
|
@ -28,7 +28,11 @@ class Z2TReceiveTests: XCTestCase {
|
||||||
override func setUp() async throws {
|
override func setUp() async throws {
|
||||||
try await super.setUp()
|
try await super.setUp()
|
||||||
|
|
||||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network)
|
self.coordinator = try await TestCoordinator(
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: birthday,
|
||||||
|
network: network
|
||||||
|
)
|
||||||
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import SQLite
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class BlockScanTests: XCTestCase {
|
class BlockScanTests: ZcashTestCase {
|
||||||
var cancelables: [AnyCancellable] = []
|
var cancelables: [AnyCancellable] = []
|
||||||
|
|
||||||
var dataDbURL: URL!
|
var dataDbURL: URL!
|
||||||
|
@ -51,6 +51,23 @@ class BlockScanTests: XCTestCase {
|
||||||
)
|
)
|
||||||
|
|
||||||
deleteDBs()
|
deleteDBs()
|
||||||
|
|
||||||
|
Dependencies.setup(
|
||||||
|
in: mockContainer,
|
||||||
|
urls: Initializer.URLs(
|
||||||
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
dataDbURL: dataDbURL,
|
||||||
|
spendParamsURL: spendParamsURL,
|
||||||
|
outputParamsURL: outputParamsURL
|
||||||
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
|
)
|
||||||
|
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in LatestBlocksDataProviderMock() }
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in self.rustBackend }
|
||||||
}
|
}
|
||||||
|
|
||||||
private func deleteDBs() {
|
private func deleteDBs() {
|
||||||
|
@ -73,24 +90,9 @@ class BlockScanTests: XCTestCase {
|
||||||
_ = try await rustBackend.initDataDb(seed: nil)
|
_ = try await rustBackend.initDataDb(seed: nil)
|
||||||
|
|
||||||
let endpoint = LightWalletEndpoint(address: "lightwalletd.testnet.electriccoin.co", port: 9067)
|
let endpoint = LightWalletEndpoint(address: "lightwalletd.testnet.electriccoin.co", port: 9067)
|
||||||
let service = LightWalletServiceFactory(endpoint: endpoint).make()
|
|
||||||
let blockCount = 100
|
let blockCount = 100
|
||||||
let range = network.constants.saplingActivationHeight ... network.constants.saplingActivationHeight + blockCount
|
let range = network.constants.saplingActivationHeight ... network.constants.saplingActivationHeight + blockCount
|
||||||
|
|
||||||
let fsBlockRepository = FSCompactBlockRepository(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
metadataStore: FSMetadataStore.live(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: ZcashCompactBlockDescriptor.live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
try await fsBlockRepository.create()
|
|
||||||
|
|
||||||
let processorConfig = CompactBlockProcessor.Configuration(
|
let processorConfig = CompactBlockProcessor.Configuration(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
fsBlockCacheRoot: testTempDirectory,
|
fsBlockCacheRoot: testTempDirectory,
|
||||||
|
@ -102,15 +104,12 @@ class BlockScanTests: XCTestCase {
|
||||||
network: network
|
network: network
|
||||||
)
|
)
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||||
service: service,
|
LightWalletServiceFactory(endpoint: endpoint).make()
|
||||||
storage: fsBlockRepository,
|
}
|
||||||
rustBackend: rustBackend,
|
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||||
config: processorConfig,
|
|
||||||
metrics: SDKMetrics(),
|
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
|
||||||
|
|
||||||
let repository = BlockSQLDAO(dbProvider: SimpleConnectionProvider.init(path: self.dataDbURL.absoluteString, readonly: true))
|
let repository = BlockSQLDAO(dbProvider: SimpleConnectionProvider.init(path: self.dataDbURL.absoluteString, readonly: true))
|
||||||
var latestScannedheight = BlockHeight.empty()
|
var latestScannedheight = BlockHeight.empty()
|
||||||
|
@ -162,22 +161,6 @@ class BlockScanTests: XCTestCase {
|
||||||
saplingTree: walletBirthDay.saplingTree
|
saplingTree: walletBirthDay.saplingTree
|
||||||
)
|
)
|
||||||
|
|
||||||
let service = LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
|
||||||
|
|
||||||
let fsBlockRepository = FSCompactBlockRepository(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
metadataStore: FSMetadataStore.live(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: ZcashCompactBlockDescriptor.live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
try await fsBlockRepository.create()
|
|
||||||
|
|
||||||
let processorConfig = CompactBlockProcessor.Configuration(
|
let processorConfig = CompactBlockProcessor.Configuration(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
fsBlockCacheRoot: testTempDirectory,
|
fsBlockCacheRoot: testTempDirectory,
|
||||||
|
@ -191,15 +174,12 @@ class BlockScanTests: XCTestCase {
|
||||||
network: network
|
network: network
|
||||||
)
|
)
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||||
service: service,
|
LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
||||||
storage: fsBlockRepository,
|
}
|
||||||
rustBackend: rustBackend,
|
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||||
config: processorConfig,
|
|
||||||
metrics: metrics,
|
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
|
||||||
|
|
||||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||||
switch event {
|
switch event {
|
||||||
|
@ -220,7 +200,7 @@ class BlockScanTests: XCTestCase {
|
||||||
try await blockDownloader.setSyncRange(range)
|
try await blockDownloader.setSyncRange(range)
|
||||||
await blockDownloader.startDownload(maxBlockBufferSize: 10)
|
await blockDownloader.startDownload(maxBlockBufferSize: 10)
|
||||||
try await blockDownloader.waitUntilRequestedBlocksAreDownloaded(in: range)
|
try await blockDownloader.waitUntilRequestedBlocksAreDownloaded(in: range)
|
||||||
|
|
||||||
XCTAssertFalse(Task.isCancelled)
|
XCTAssertFalse(Task.isCancelled)
|
||||||
|
|
||||||
try await compactBlockProcessor.blockValidator.validate()
|
try await compactBlockProcessor.blockValidator.validate()
|
||||||
|
|
|
@ -9,7 +9,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class BlockStreamingTest: XCTestCase {
|
class BlockStreamingTest: ZcashTestCase {
|
||||||
let testFileManager = FileManager()
|
let testFileManager = FileManager()
|
||||||
var rustBackend: ZcashRustBackendWelding!
|
var rustBackend: ZcashRustBackendWelding!
|
||||||
var testTempDirectory: URL!
|
var testTempDirectory: URL!
|
||||||
|
@ -21,6 +21,24 @@ class BlockStreamingTest: XCTestCase {
|
||||||
|
|
||||||
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
||||||
rustBackend = ZcashRustBackend.makeForTests(fsBlockDbRoot: testTempDirectory, networkType: .testnet)
|
rustBackend = ZcashRustBackend.makeForTests(fsBlockDbRoot: testTempDirectory, networkType: .testnet)
|
||||||
|
logger = OSLogger(logLevel: .debug)
|
||||||
|
|
||||||
|
Dependencies.setup(
|
||||||
|
in: mockContainer,
|
||||||
|
urls: Initializer.URLs(
|
||||||
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
dataDbURL: try! __dataDbURL(),
|
||||||
|
spendParamsURL: try! __spendParamsURL(),
|
||||||
|
outputParamsURL: try! __outputParamsURL()
|
||||||
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
|
)
|
||||||
|
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in LatestBlocksDataProviderMock() }
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in self.rustBackend }
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDownWithError() throws {
|
override func tearDownWithError() throws {
|
||||||
|
@ -70,20 +88,6 @@ class BlockStreamingTest: XCTestCase {
|
||||||
)
|
)
|
||||||
let service = LightWalletServiceFactory(endpoint: endpoint).make()
|
let service = LightWalletServiceFactory(endpoint: endpoint).make()
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
metadataStore: FSMetadataStore.live(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: .live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
try await storage.create()
|
|
||||||
|
|
||||||
let latestBlockHeight = try await service.latestBlockHeight()
|
let latestBlockHeight = try await service.latestBlockHeight()
|
||||||
let startHeight = latestBlockHeight - 100_000
|
let startHeight = latestBlockHeight - 100_000
|
||||||
let processorConfig = CompactBlockProcessor.Configuration.standard(
|
let processorConfig = CompactBlockProcessor.Configuration.standard(
|
||||||
|
@ -91,15 +95,12 @@ class BlockStreamingTest: XCTestCase {
|
||||||
walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.saplingActivationHeight
|
walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.saplingActivationHeight
|
||||||
)
|
)
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||||
service: service,
|
LightWalletServiceFactory(endpoint: endpoint).make()
|
||||||
storage: storage,
|
}
|
||||||
rustBackend: rustBackend,
|
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||||
config: processorConfig,
|
|
||||||
metrics: SDKMetrics(),
|
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
|
||||||
|
|
||||||
let cancelableTask = Task {
|
let cancelableTask = Task {
|
||||||
do {
|
do {
|
||||||
|
@ -127,20 +128,6 @@ class BlockStreamingTest: XCTestCase {
|
||||||
)
|
)
|
||||||
let service = LightWalletServiceFactory(endpoint: endpoint).make()
|
let service = LightWalletServiceFactory(endpoint: endpoint).make()
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
metadataStore: FSMetadataStore.live(
|
|
||||||
fsBlockDbRoot: testTempDirectory,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: .live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
try await storage.create()
|
|
||||||
|
|
||||||
let latestBlockHeight = try await service.latestBlockHeight()
|
let latestBlockHeight = try await service.latestBlockHeight()
|
||||||
|
|
||||||
let startHeight = latestBlockHeight - 100_000
|
let startHeight = latestBlockHeight - 100_000
|
||||||
|
@ -150,15 +137,12 @@ class BlockStreamingTest: XCTestCase {
|
||||||
walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.saplingActivationHeight
|
walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.saplingActivationHeight
|
||||||
)
|
)
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||||
service: service,
|
LightWalletServiceFactory(endpoint: endpoint).make()
|
||||||
storage: storage,
|
}
|
||||||
rustBackend: rustBackend,
|
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||||
config: processorConfig,
|
|
||||||
metrics: SDKMetrics(),
|
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
|
||||||
|
|
||||||
let date = Date()
|
let date = Date()
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class CompactBlockProcessorTests: XCTestCase {
|
class CompactBlockProcessorTests: ZcashTestCase {
|
||||||
var processorConfig: CompactBlockProcessor.Configuration!
|
var processorConfig: CompactBlockProcessor.Configuration!
|
||||||
var cancellables: [AnyCancellable] = []
|
var cancellables: [AnyCancellable] = []
|
||||||
var processorEventHandler: CompactBlockProcessorEventHandler! = CompactBlockProcessorEventHandler()
|
var processorEventHandler: CompactBlockProcessorEventHandler! = CompactBlockProcessorEventHandler()
|
||||||
|
@ -73,20 +73,6 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
info.estimatedHeight = UInt64(mockLatestHeight)
|
info.estimatedHeight = UInt64(mockLatestHeight)
|
||||||
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
|
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
|
||||||
})
|
})
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
|
||||||
fsBlockDbRoot: processorConfig.fsBlockCacheRoot,
|
|
||||||
metadataStore: FSMetadataStore.live(
|
|
||||||
fsBlockDbRoot: processorConfig.fsBlockCacheRoot,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: .live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
try await storage.create()
|
|
||||||
|
|
||||||
let transactionRepository = MockTransactionRepository(
|
let transactionRepository = MockTransactionRepository(
|
||||||
unminedCount: 0,
|
unminedCount: 0,
|
||||||
|
@ -96,15 +82,28 @@ class CompactBlockProcessorTests: XCTestCase {
|
||||||
network: network
|
network: network
|
||||||
)
|
)
|
||||||
|
|
||||||
processor = CompactBlockProcessor(
|
Dependencies.setup(
|
||||||
service: service,
|
in: mockContainer,
|
||||||
storage: storage,
|
urls: Initializer.URLs(
|
||||||
rustBackend: rustBackend,
|
fsBlockDbRoot: testTempDirectory,
|
||||||
config: processorConfig,
|
dataDbURL: processorConfig.dataDb,
|
||||||
metrics: SDKMetrics(),
|
spendParamsURL: processorConfig.spendParamsURL,
|
||||||
logger: logger,
|
outputParamsURL: processorConfig.outputParamsURL
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in
|
||||||
|
LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||||
|
}
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in self.rustBackend }
|
||||||
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||||
|
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||||
|
|
||||||
|
processor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||||
|
|
||||||
let dbInit = try await rustBackend.initDataDb(seed: nil)
|
let dbInit = try await rustBackend.initDataDb(seed: nil)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class CompactBlockReorgTests: XCTestCase {
|
class CompactBlockReorgTests: ZcashTestCase {
|
||||||
var processorConfig: CompactBlockProcessor.Configuration!
|
var processorConfig: CompactBlockProcessor.Configuration!
|
||||||
let testFileManager = FileManager()
|
let testFileManager = FileManager()
|
||||||
var cancellables: [AnyCancellable] = []
|
var cancellables: [AnyCancellable] = []
|
||||||
|
@ -110,16 +110,29 @@ class CompactBlockReorgTests: XCTestCase {
|
||||||
network: network
|
network: network
|
||||||
)
|
)
|
||||||
|
|
||||||
processor = CompactBlockProcessor(
|
Dependencies.setup(
|
||||||
service: service,
|
in: mockContainer,
|
||||||
storage: realCache,
|
urls: Initializer.URLs(
|
||||||
rustBackend: rustBackendMockHelper.rustBackendMock,
|
fsBlockDbRoot: testTempDirectory,
|
||||||
config: processorConfig,
|
dataDbURL: processorConfig.dataDb,
|
||||||
metrics: SDKMetrics(),
|
spendParamsURL: processorConfig.spendParamsURL,
|
||||||
logger: logger,
|
outputParamsURL: processorConfig.outputParamsURL
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in
|
||||||
|
LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||||
|
}
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in self.rustBackendMockHelper.rustBackendMock }
|
||||||
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||||
|
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in realCache }
|
||||||
|
|
||||||
|
processor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||||
|
|
||||||
syncStartedExpect = XCTestExpectation(description: "\(self.description) syncStartedExpect")
|
syncStartedExpect = XCTestExpectation(description: "\(self.description) syncStartedExpect")
|
||||||
stopNotificationExpectation = XCTestExpectation(description: "\(self.description) stopNotificationExpectation")
|
stopNotificationExpectation = XCTestExpectation(description: "\(self.description) stopNotificationExpectation")
|
||||||
updatedNotificationExpectation = XCTestExpectation(description: "\(self.description) updatedNotificationExpectation")
|
updatedNotificationExpectation = XCTestExpectation(description: "\(self.description) updatedNotificationExpectation")
|
||||||
|
|
|
@ -11,7 +11,7 @@ import SQLite
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class DownloadTests: XCTestCase {
|
class DownloadTests: ZcashTestCase {
|
||||||
let testFileManager = FileManager()
|
let testFileManager = FileManager()
|
||||||
var network = ZcashNetworkBuilder.network(for: .testnet)
|
var network = ZcashNetworkBuilder.network(for: .testnet)
|
||||||
var testTempDirectory: URL!
|
var testTempDirectory: URL!
|
||||||
|
@ -23,6 +23,22 @@ class DownloadTests: XCTestCase {
|
||||||
await InternalSyncProgress(alias: .default, storage: UserDefaults.standard, logger: logger).rewind(to: 0)
|
await InternalSyncProgress(alias: .default, storage: UserDefaults.standard, logger: logger).rewind(to: 0)
|
||||||
|
|
||||||
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
||||||
|
|
||||||
|
Dependencies.setup(
|
||||||
|
in: mockContainer,
|
||||||
|
urls: Initializer.URLs(
|
||||||
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
dataDbURL: try! __dataDbURL(),
|
||||||
|
spendParamsURL: try! __spendParamsURL(),
|
||||||
|
outputParamsURL: try! __outputParamsURL()
|
||||||
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
|
)
|
||||||
|
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in LatestBlocksDataProviderMock() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDownWithError() throws {
|
override func tearDownWithError() throws {
|
||||||
|
@ -32,21 +48,13 @@ class DownloadTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSingleDownload() async throws {
|
func testSingleDownload() async throws {
|
||||||
let service = LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in
|
||||||
let rustBackend = ZcashRustBackend.makeForTests(fsBlockDbRoot: testTempDirectory, networkType: network.networkType)
|
ZcashRustBackend.makeForTests(fsBlockDbRoot: self.testTempDirectory, networkType: self.network.networkType)
|
||||||
|
}
|
||||||
let storage = FSCompactBlockRepository(
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||||
fsBlockDbRoot: testTempDirectory,
|
LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
||||||
metadataStore: FSMetadataStore.live(
|
}
|
||||||
fsBlockDbRoot: testTempDirectory,
|
let storage = mockContainer.resolve(CompactBlockRepository.self)
|
||||||
rustBackend: rustBackend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: .live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
try await storage.create()
|
try await storage.create()
|
||||||
|
|
||||||
let blockCount = 100
|
let blockCount = 100
|
||||||
|
@ -58,15 +66,7 @@ class DownloadTests: XCTestCase {
|
||||||
walletBirthday: network.constants.saplingActivationHeight
|
walletBirthday: network.constants.saplingActivationHeight
|
||||||
)
|
)
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||||
service: service,
|
|
||||||
storage: storage,
|
|
||||||
rustBackend: rustBackend,
|
|
||||||
config: processorConfig,
|
|
||||||
metrics: SDKMetrics(),
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await compactBlockProcessor.blockDownloaderService.downloadBlockRange(range)
|
try await compactBlockProcessor.blockDownloaderService.downloadBlockRange(range)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class BlockBatchValidationTests: XCTestCase {
|
class BlockBatchValidationTests: ZcashTestCase {
|
||||||
let testFileManager = FileManager()
|
let testFileManager = FileManager()
|
||||||
var rustBackend: ZcashRustBackendWelding!
|
var rustBackend: ZcashRustBackendWelding!
|
||||||
var testTempDirectory: URL!
|
var testTempDirectory: URL!
|
||||||
|
@ -17,6 +17,23 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
try super.setUpWithError()
|
try super.setUpWithError()
|
||||||
testTempDirectory = Environment.uniqueTestTempDirectory
|
testTempDirectory = Environment.uniqueTestTempDirectory
|
||||||
|
|
||||||
|
Dependencies.setup(
|
||||||
|
in: mockContainer,
|
||||||
|
urls: Initializer.URLs(
|
||||||
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
dataDbURL: try! __dataDbURL(),
|
||||||
|
spendParamsURL: try! __spendParamsURL(),
|
||||||
|
outputParamsURL: try! __outputParamsURL()
|
||||||
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
|
)
|
||||||
|
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in LatestBlocksDataProviderMock() }
|
||||||
|
|
||||||
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
||||||
rustBackend = ZcashRustBackend.makeForTests(fsBlockDbRoot: testTempDirectory, networkType: .testnet)
|
rustBackend = ZcashRustBackend.makeForTests(fsBlockDbRoot: testTempDirectory, networkType: .testnet)
|
||||||
}
|
}
|
||||||
|
@ -34,6 +51,7 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
latestBlockHeight: 1210000,
|
latestBlockHeight: 1210000,
|
||||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
let storage = FSCompactBlockRepository(
|
||||||
fsBlockDbRoot: testTempDirectory,
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
@ -46,11 +64,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||||
logger: logger
|
logger: logger
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||||
|
|
||||||
try await storage.create()
|
try await storage.create()
|
||||||
|
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
|
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||||
|
}
|
||||||
|
|
||||||
let config = CompactBlockProcessor.Configuration(
|
let config = CompactBlockProcessor.Configuration(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
fsBlockCacheRoot: testTempDirectory,
|
fsBlockCacheRoot: testTempDirectory,
|
||||||
|
@ -77,19 +99,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: Int32(0xd34d))
|
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: Int32(0xd34d))
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
let compactBlockProcessor = CompactBlockProcessor(
|
||||||
service: service,
|
container: mockContainer,
|
||||||
storage: storage,
|
config: config
|
||||||
rustBackend: mockBackend.rustBackendMock,
|
|
||||||
config: config,
|
|
||||||
metrics: SDKMetrics(),
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||||
XCTAssertFalse(Task.isCancelled)
|
XCTAssertFalse(Task.isCancelled)
|
||||||
} catch {
|
} catch {
|
||||||
switch error {
|
switch error {
|
||||||
|
@ -107,6 +125,7 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
latestBlockHeight: 1210000,
|
latestBlockHeight: 1210000,
|
||||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
let storage = FSCompactBlockRepository(
|
||||||
fsBlockDbRoot: testTempDirectory,
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
@ -119,11 +138,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||||
logger: logger
|
logger: logger
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||||
|
|
||||||
try await storage.create()
|
try await storage.create()
|
||||||
|
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
|
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||||
|
}
|
||||||
|
|
||||||
let config = CompactBlockProcessor.Configuration(
|
let config = CompactBlockProcessor.Configuration(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
fsBlockCacheRoot: testTempDirectory,
|
fsBlockCacheRoot: testTempDirectory,
|
||||||
|
@ -150,19 +173,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
let compactBlockProcessor = CompactBlockProcessor(
|
||||||
service: service,
|
container: mockContainer,
|
||||||
storage: storage,
|
config: config
|
||||||
rustBackend: mockBackend.rustBackendMock,
|
|
||||||
config: config,
|
|
||||||
metrics: SDKMetrics(),
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||||
XCTAssertFalse(Task.isCancelled)
|
XCTAssertFalse(Task.isCancelled)
|
||||||
} catch {
|
} catch {
|
||||||
switch error {
|
switch error {
|
||||||
|
@ -180,6 +199,7 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
latestBlockHeight: 1210000,
|
latestBlockHeight: 1210000,
|
||||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
let storage = FSCompactBlockRepository(
|
||||||
fsBlockDbRoot: testTempDirectory,
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
@ -192,11 +212,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||||
logger: logger
|
logger: logger
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||||
|
|
||||||
try await storage.create()
|
try await storage.create()
|
||||||
|
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
|
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||||
|
}
|
||||||
|
|
||||||
let config = CompactBlockProcessor.Configuration(
|
let config = CompactBlockProcessor.Configuration(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
fsBlockCacheRoot: testTempDirectory,
|
fsBlockCacheRoot: testTempDirectory,
|
||||||
|
@ -223,19 +247,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
let compactBlockProcessor = CompactBlockProcessor(
|
||||||
service: service,
|
container: mockContainer,
|
||||||
storage: storage,
|
config: config
|
||||||
rustBackend: mockBackend.rustBackendMock,
|
|
||||||
config: config,
|
|
||||||
metrics: SDKMetrics(),
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||||
XCTAssertFalse(Task.isCancelled)
|
XCTAssertFalse(Task.isCancelled)
|
||||||
} catch {
|
} catch {
|
||||||
switch error {
|
switch error {
|
||||||
|
@ -253,6 +273,7 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
latestBlockHeight: 1210000,
|
latestBlockHeight: 1210000,
|
||||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
let storage = FSCompactBlockRepository(
|
||||||
fsBlockDbRoot: testTempDirectory,
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
@ -265,11 +286,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||||
logger: logger
|
logger: logger
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||||
|
|
||||||
try await storage.create()
|
try await storage.create()
|
||||||
|
|
||||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||||
|
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||||
|
}
|
||||||
|
|
||||||
let config = CompactBlockProcessor.Configuration(
|
let config = CompactBlockProcessor.Configuration(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
fsBlockCacheRoot: testTempDirectory,
|
fsBlockCacheRoot: testTempDirectory,
|
||||||
|
@ -297,19 +322,15 @@ class BlockBatchValidationTests: XCTestCase {
|
||||||
service.mockLightDInfo = info
|
service.mockLightDInfo = info
|
||||||
|
|
||||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
||||||
|
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||||
|
|
||||||
let compactBlockProcessor = CompactBlockProcessor(
|
let compactBlockProcessor = CompactBlockProcessor(
|
||||||
service: service,
|
container: mockContainer,
|
||||||
storage: storage,
|
config: config
|
||||||
rustBackend: mockBackend.rustBackendMock,
|
|
||||||
config: config,
|
|
||||||
metrics: SDKMetrics(),
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||||
XCTAssertFalse(Task.isCancelled)
|
XCTAssertFalse(Task.isCancelled)
|
||||||
} catch {
|
} catch {
|
||||||
switch error {
|
switch error {
|
||||||
|
|
|
@ -9,13 +9,28 @@ import XCTest
|
||||||
@testable import TestUtils
|
@testable import TestUtils
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class CompactBlockProcessorOfflineTests: XCTestCase {
|
class CompactBlockProcessorOfflineTests: ZcashTestCase {
|
||||||
let testFileManager = FileManager()
|
let testFileManager = FileManager()
|
||||||
var testTempDirectory: URL!
|
var testTempDirectory: URL!
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
override func setUpWithError() throws {
|
||||||
try super.setUpWithError()
|
try super.setUpWithError()
|
||||||
testTempDirectory = Environment.uniqueTestTempDirectory
|
testTempDirectory = Environment.uniqueTestTempDirectory
|
||||||
|
|
||||||
|
Dependencies.setup(
|
||||||
|
in: mockContainer,
|
||||||
|
urls: Initializer.URLs(
|
||||||
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
dataDbURL: try! __dataDbURL(),
|
||||||
|
spendParamsURL: try! __spendParamsURL(),
|
||||||
|
outputParamsURL: try! __outputParamsURL()
|
||||||
|
),
|
||||||
|
alias: .default,
|
||||||
|
networkType: .testnet,
|
||||||
|
endpoint: LightWalletEndpointBuilder.default,
|
||||||
|
loggingPolicy: .default(.debug)
|
||||||
|
)
|
||||||
|
|
||||||
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +52,7 @@ class CompactBlockProcessorOfflineTests: XCTestCase {
|
||||||
latestBlockHeight: 690000,
|
latestBlockHeight: 690000,
|
||||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||||
|
|
||||||
let storage = FSCompactBlockRepository(
|
let storage = FSCompactBlockRepository(
|
||||||
fsBlockDbRoot: testTempDirectory,
|
fsBlockDbRoot: testTempDirectory,
|
||||||
|
@ -49,15 +65,12 @@ class CompactBlockProcessorOfflineTests: XCTestCase {
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||||
logger: logger
|
logger: logger
|
||||||
)
|
)
|
||||||
|
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||||
|
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in LatestBlocksDataProviderMock() }
|
||||||
|
|
||||||
let processor = CompactBlockProcessor(
|
let processor = CompactBlockProcessor(
|
||||||
service: service,
|
container: mockContainer,
|
||||||
storage: storage,
|
config: processorConfig
|
||||||
rustBackend: rustBackend,
|
|
||||||
config: processorConfig,
|
|
||||||
metrics: SDKMetrics(),
|
|
||||||
logger: logger,
|
|
||||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let fullRange = 0...1000
|
let fullRange = 0...1000
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Foundation
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import ZcashLightClientKit
|
@testable import ZcashLightClientKit
|
||||||
|
|
||||||
class SynchronizerOfflineTests: XCTestCase {
|
class SynchronizerOfflineTests: ZcashTestCase {
|
||||||
let data = TestsData(networkType: .testnet)
|
let data = TestsData(networkType: .testnet)
|
||||||
var network: ZcashNetwork!
|
var network: ZcashNetwork!
|
||||||
var cancellables: [AnyCancellable] = []
|
var cancellables: [AnyCancellable] = []
|
||||||
|
@ -31,6 +31,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
func testCallPrepareWithAlreadyUsedAliasThrowsError() async throws {
|
func testCallPrepareWithAlreadyUsedAliasThrowsError() async throws {
|
||||||
let firstTestCoordinator = try await TestCoordinator(
|
let firstTestCoordinator = try await TestCoordinator(
|
||||||
alias: .custom("alias"),
|
alias: .custom("alias"),
|
||||||
|
container: mockContainer,
|
||||||
walletBirthday: 10,
|
walletBirthday: 10,
|
||||||
network: network,
|
network: network,
|
||||||
callPrepareInConstructor: false
|
callPrepareInConstructor: false
|
||||||
|
@ -38,6 +39,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
|
|
||||||
let secondTestCoordinator = try await TestCoordinator(
|
let secondTestCoordinator = try await TestCoordinator(
|
||||||
alias: .custom("alias"),
|
alias: .custom("alias"),
|
||||||
|
container: mockContainer,
|
||||||
walletBirthday: 10,
|
walletBirthday: 10,
|
||||||
network: network,
|
network: network,
|
||||||
callPrepareInConstructor: false
|
callPrepareInConstructor: false
|
||||||
|
@ -58,6 +60,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
func testWhenSynchronizerIsDeallocatedAliasIsntUsedAnymore() async throws {
|
func testWhenSynchronizerIsDeallocatedAliasIsntUsedAnymore() async throws {
|
||||||
var testCoordinator: TestCoordinator! = try await TestCoordinator(
|
var testCoordinator: TestCoordinator! = try await TestCoordinator(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
walletBirthday: 10,
|
walletBirthday: 10,
|
||||||
network: network,
|
network: network,
|
||||||
callPrepareInConstructor: false
|
callPrepareInConstructor: false
|
||||||
|
@ -71,6 +74,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
|
|
||||||
testCoordinator = try await TestCoordinator(
|
testCoordinator = try await TestCoordinator(
|
||||||
alias: .default,
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
walletBirthday: 10,
|
walletBirthday: 10,
|
||||||
network: network,
|
network: network,
|
||||||
callPrepareInConstructor: false
|
callPrepareInConstructor: false
|
||||||
|
@ -84,8 +88,21 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCallWipeWithAlreadyUsedAliasThrowsError() async throws {
|
func testCallWipeWithAlreadyUsedAliasThrowsError() async throws {
|
||||||
let firstTestCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
let firstTestCoordinator = try await TestCoordinator(
|
||||||
let secondTestCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: 10,
|
||||||
|
network: network,
|
||||||
|
callPrepareInConstructor: false
|
||||||
|
)
|
||||||
|
|
||||||
|
let secondTestCoordinator = try await TestCoordinator(
|
||||||
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: 10,
|
||||||
|
network: network,
|
||||||
|
callPrepareInConstructor: false
|
||||||
|
)
|
||||||
|
|
||||||
let firstWipeExpectation = XCTestExpectation(description: "First wipe expectation")
|
let firstWipeExpectation = XCTestExpectation(description: "First wipe expectation")
|
||||||
|
|
||||||
|
@ -129,7 +146,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPrepareCanBeCalledAfterWipeWithSameInstanceOfSDKSynchronizer() async throws {
|
func testPrepareCanBeCalledAfterWipeWithSameInstanceOfSDKSynchronizer() async throws {
|
||||||
let testCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
let testCoordinator = try await TestCoordinator(
|
||||||
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: 10,
|
||||||
|
network: network,
|
||||||
|
callPrepareInConstructor: false
|
||||||
|
)
|
||||||
|
|
||||||
let expectation = XCTestExpectation(description: "Wipe expectation")
|
let expectation = XCTestExpectation(description: "Wipe expectation")
|
||||||
|
|
||||||
|
@ -157,7 +180,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSendToAddressCalledWithoutPrepareThrowsError() async throws {
|
func testSendToAddressCalledWithoutPrepareThrowsError() async throws {
|
||||||
let testCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
let testCoordinator = try await TestCoordinator(
|
||||||
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: 10,
|
||||||
|
network: network,
|
||||||
|
callPrepareInConstructor: false
|
||||||
|
)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
_ = try await testCoordinator.synchronizer.sendToAddress(
|
_ = try await testCoordinator.synchronizer.sendToAddress(
|
||||||
|
@ -175,27 +204,14 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSendToWithTransparentAddressThrowsError() async throws {
|
|
||||||
let testCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: true)
|
|
||||||
|
|
||||||
do {
|
|
||||||
_ = try await testCoordinator.synchronizer.sendToAddress(
|
|
||||||
spendingKey: testCoordinator.spendingKey,
|
|
||||||
zatoshi: Zatoshi(1),
|
|
||||||
toAddress: .transparent(data.transparentAddress),
|
|
||||||
memo: try .init(string: "hello")
|
|
||||||
)
|
|
||||||
XCTFail("Send to address should fail.")
|
|
||||||
} catch {
|
|
||||||
if let error = error as? ZcashError, case .synchronizerSendMemoToTransparentAddress = error {
|
|
||||||
} else {
|
|
||||||
XCTFail("Send to address failed with unexpected error: \(error)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testShieldFundsCalledWithoutPrepareThrowsError() async throws {
|
func testShieldFundsCalledWithoutPrepareThrowsError() async throws {
|
||||||
let testCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
let testCoordinator = try await TestCoordinator(
|
||||||
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: 10,
|
||||||
|
network: network,
|
||||||
|
callPrepareInConstructor: false
|
||||||
|
)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
_ = try await testCoordinator.synchronizer.shieldFunds(
|
_ = try await testCoordinator.synchronizer.shieldFunds(
|
||||||
|
@ -213,7 +229,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRefreshUTXOCalledWithoutPrepareThrowsError() async throws {
|
func testRefreshUTXOCalledWithoutPrepareThrowsError() async throws {
|
||||||
let testCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
let testCoordinator = try await TestCoordinator(
|
||||||
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: 10,
|
||||||
|
network: network,
|
||||||
|
callPrepareInConstructor: false
|
||||||
|
)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
_ = try await testCoordinator.synchronizer.refreshUTXOs(address: data.transparentAddress, from: 1)
|
_ = try await testCoordinator.synchronizer.refreshUTXOs(address: data.transparentAddress, from: 1)
|
||||||
|
@ -227,7 +249,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRewindCalledWithoutPrepareThrowsError() async throws {
|
func testRewindCalledWithoutPrepareThrowsError() async throws {
|
||||||
let testCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
let testCoordinator = try await TestCoordinator(
|
||||||
|
alias: .default,
|
||||||
|
container: mockContainer,
|
||||||
|
walletBirthday: 10,
|
||||||
|
network: network,
|
||||||
|
callPrepareInConstructor: false
|
||||||
|
)
|
||||||
|
|
||||||
let expectation = XCTestExpectation()
|
let expectation = XCTestExpectation()
|
||||||
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
//
|
|
||||||
// SDKSynchronizer+Utils.swift
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Created by Francisco Gindre on 3/31/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
@testable import ZcashLightClientKit
|
|
||||||
|
|
||||||
extension SDKSynchronizer {
|
|
||||||
convenience init(initializer: Initializer, sessionGenerator: SyncSessionIDGenerator, sessionTicker: SessionTicker) {
|
|
||||||
let metrics = SDKMetrics()
|
|
||||||
let latestBlocksDataProvider = LatestBlocksDataProviderImpl(
|
|
||||||
service: initializer.lightWalletService,
|
|
||||||
transactionRepository: initializer.transactionRepository
|
|
||||||
)
|
|
||||||
self.init(
|
|
||||||
status: .unprepared,
|
|
||||||
initializer: initializer,
|
|
||||||
transactionEncoder: WalletTransactionEncoder(initializer: initializer),
|
|
||||||
transactionRepository: initializer.transactionRepository,
|
|
||||||
utxoRepository: UTXORepositoryBuilder.build(initializer: initializer),
|
|
||||||
blockProcessor: CompactBlockProcessor(
|
|
||||||
initializer: initializer,
|
|
||||||
metrics: metrics,
|
|
||||||
logger: initializer.logger,
|
|
||||||
latestBlocksDataProvider: latestBlocksDataProvider,
|
|
||||||
walletBirthdayProvider: { initializer.walletBirthday }
|
|
||||||
),
|
|
||||||
metrics: metrics,
|
|
||||||
syncSessionIDGenerator: sessionGenerator,
|
|
||||||
syncSessionTicker: sessionTicker,
|
|
||||||
latestBlocksDataProvider: latestBlocksDataProvider
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -55,6 +55,7 @@ class TestCoordinator {
|
||||||
|
|
||||||
init(
|
init(
|
||||||
alias: ZcashSynchronizerAlias = .default,
|
alias: ZcashSynchronizerAlias = .default,
|
||||||
|
container: DIContainer,
|
||||||
walletBirthday: BlockHeight,
|
walletBirthday: BlockHeight,
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
callPrepareInConstructor: Bool = true,
|
callPrepareInConstructor: Bool = true,
|
||||||
|
@ -63,86 +64,40 @@ class TestCoordinator {
|
||||||
dbTracingClosure: ((String) -> Void)? = nil
|
dbTracingClosure: ((String) -> Void)? = nil
|
||||||
) async throws {
|
) async throws {
|
||||||
await InternalSyncProgress(alias: alias, storage: UserDefaults.standard, logger: logger).rewind(to: 0)
|
await InternalSyncProgress(alias: alias, storage: UserDefaults.standard, logger: logger).rewind(to: 0)
|
||||||
|
|
||||||
let databases = TemporaryDbBuilder.build()
|
let databases = TemporaryDbBuilder.build()
|
||||||
self.databases = databases
|
self.databases = databases
|
||||||
|
|
||||||
let urls = Initializer.URLs(
|
let initializer = Initializer(
|
||||||
|
container: container,
|
||||||
|
cacheDbURL: nil,
|
||||||
fsBlockDbRoot: databases.fsCacheDbRoot,
|
fsBlockDbRoot: databases.fsCacheDbRoot,
|
||||||
dataDbURL: databases.dataDB,
|
dataDbURL: databases.dataDB,
|
||||||
spendParamsURL: try __spendParamsURL(),
|
|
||||||
outputParamsURL: try __outputParamsURL()
|
|
||||||
)
|
|
||||||
|
|
||||||
let (updatedURLs, parsingError) = Initializer.tryToUpdateURLs(with: alias, urls: urls)
|
|
||||||
|
|
||||||
let backend = ZcashRustBackend(
|
|
||||||
dbData: updatedURLs.dataDbURL,
|
|
||||||
fsBlockDbRoot: updatedURLs.fsBlockDbRoot,
|
|
||||||
spendParamsPath: updatedURLs.spendParamsURL,
|
|
||||||
outputParamsPath: updatedURLs.outputParamsURL,
|
|
||||||
networkType: network.networkType
|
|
||||||
)
|
|
||||||
|
|
||||||
let transactionRepository = TransactionSQLDAO(
|
|
||||||
dbProvider: SimpleConnectionProvider(path: updatedURLs.dataDbURL.absoluteString),
|
|
||||||
traceClosure: dbTracingClosure
|
|
||||||
)
|
|
||||||
|
|
||||||
let accountRepository = AccountRepositoryBuilder.build(
|
|
||||||
dataDbURL: updatedURLs.dataDbURL,
|
|
||||||
readOnly: true,
|
|
||||||
caching: true,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
let fsBlockRepository = FSCompactBlockRepository(
|
|
||||||
fsBlockDbRoot: updatedURLs.fsBlockDbRoot,
|
|
||||||
metadataStore: .live(
|
|
||||||
fsBlockDbRoot: updatedURLs.fsBlockDbRoot,
|
|
||||||
rustBackend: backend,
|
|
||||||
logger: logger
|
|
||||||
),
|
|
||||||
blockDescriptor: .live,
|
|
||||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
|
||||||
logger: logger
|
|
||||||
)
|
|
||||||
|
|
||||||
let service = Initializer.makeLightWalletServiceFactory(endpoint: endpoint).make()
|
|
||||||
|
|
||||||
let initializer = Initializer(
|
|
||||||
rustBackend: backend,
|
|
||||||
network: network,
|
|
||||||
cacheDbURL: nil,
|
|
||||||
urls: updatedURLs,
|
|
||||||
endpoint: endpoint,
|
endpoint: endpoint,
|
||||||
service: service,
|
network: network,
|
||||||
repository: transactionRepository,
|
spendParamsURL: try __spendParamsURL(),
|
||||||
accountRepository: accountRepository,
|
outputParamsURL: try __outputParamsURL(),
|
||||||
storage: fsBlockRepository,
|
|
||||||
saplingParamsSourceURL: SaplingParamsSourceURL.tests,
|
saplingParamsSourceURL: SaplingParamsSourceURL.tests,
|
||||||
alias: alias,
|
alias: alias,
|
||||||
urlsParsingError: parsingError,
|
loggingPolicy: .default(.debug)
|
||||||
logger: OSLogger(logLevel: .debug)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
let derivationTool = DerivationTool(networkType: network.networkType)
|
let derivationTool = DerivationTool(networkType: network.networkType)
|
||||||
|
|
||||||
self.spendingKey = try derivationTool.deriveUnifiedSpendingKey(
|
self.spendingKey = try derivationTool.deriveUnifiedSpendingKey(
|
||||||
seed: Environment.seedBytes,
|
seed: Environment.seedBytes,
|
||||||
accountIndex: 0
|
accountIndex: 0
|
||||||
)
|
)
|
||||||
|
|
||||||
self.viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey)
|
self.viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey)
|
||||||
self.birthday = walletBirthday
|
self.birthday = walletBirthday
|
||||||
self.network = network
|
self.network = network
|
||||||
|
|
||||||
let liveService = LightWalletServiceFactory(endpoint: endpoint).make()
|
let liveService = LightWalletServiceFactory(endpoint: endpoint).make()
|
||||||
self.service = DarksideWalletService(endpoint: endpoint, service: liveService)
|
self.service = DarksideWalletService(endpoint: endpoint, service: liveService)
|
||||||
|
self.synchronizer = SDKSynchronizer(initializer: initializer)
|
||||||
self.synchronizer = SDKSynchronizer(initializer: initializer, sessionGenerator: syncSessionIDGenerator, sessionTicker: .live)
|
|
||||||
subscribeToState(synchronizer: self.synchronizer)
|
subscribeToState(synchronizer: self.synchronizer)
|
||||||
|
|
||||||
if callPrepareInConstructor {
|
if callPrepareInConstructor {
|
||||||
if case .seedRequired = try await prepare(seed: Environment.seedBytes) {
|
if case .seedRequired = try await prepare(seed: Environment.seedBytes) {
|
||||||
throw TestCoordinator.CoordinatorError.seedRequiredForMigration
|
throw TestCoordinator.CoordinatorError.seedRequiredForMigration
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
//
|
||||||
|
// ZcashTestCase.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Michal Fousek on 01.05.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
@testable import ZcashLightClientKit
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
class ZcashTestCase: XCTestCase {
|
||||||
|
var mockContainer: DIContainer!
|
||||||
|
|
||||||
|
private func createMockContainer() {
|
||||||
|
guard mockContainer == nil else { return }
|
||||||
|
mockContainer = DIContainer()
|
||||||
|
mockContainer.isTestEnvironment = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func destroyMockContainer() {
|
||||||
|
mockContainer = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
try await super.setUp()
|
||||||
|
createMockContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
super.setUp()
|
||||||
|
createMockContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
try super.setUpWithError()
|
||||||
|
createMockContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() {
|
||||||
|
super.tearDown()
|
||||||
|
destroyMockContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
try await super.tearDown()
|
||||||
|
destroyMockContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDownWithError() throws {
|
||||||
|
try super.tearDownWithError()
|
||||||
|
destroyMockContainer()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue