[#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
|
||||
- tx
|
||||
- as
|
||||
- di
|
||||
|
||||
indentation_width:
|
||||
indentation_width: 4
|
||||
|
|
|
@ -330,41 +330,22 @@ actor CompactBlockProcessor {
|
|||
/// - backend: a class that complies to `ZcashRustBackendWelding`
|
||||
/// - config: `Configuration` struct for this processor
|
||||
init(
|
||||
service: LightWalletService,
|
||||
storage: CompactBlockRepository,
|
||||
rustBackend: ZcashRustBackendWelding,
|
||||
config: Configuration,
|
||||
metrics: SDKMetrics,
|
||||
logger: Logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
container: DIContainer,
|
||||
config: Configuration
|
||||
) {
|
||||
self.init(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
container: container,
|
||||
config: config,
|
||||
repository: TransactionRepositoryBuilder.build(dataDbURL: config.dataDb),
|
||||
accountRepository: AccountRepositoryBuilder.build(dataDbURL: config.dataDb, readOnly: true, logger: logger),
|
||||
metrics: metrics,
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
accountRepository: AccountRepositoryBuilder.build(dataDbURL: config.dataDb, readOnly: true, logger: container.resolve(Logger.self))
|
||||
)
|
||||
}
|
||||
|
||||
/// Initializes a CompactBlockProcessor instance from an Initialized object
|
||||
/// - Parameters:
|
||||
/// - initializer: an instance that complies to CompactBlockDownloading protocol
|
||||
init(
|
||||
initializer: Initializer,
|
||||
metrics: SDKMetrics,
|
||||
logger: Logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider,
|
||||
walletBirthdayProvider: @escaping () -> BlockHeight
|
||||
) {
|
||||
init(initializer: Initializer, walletBirthdayProvider: @escaping () -> BlockHeight) {
|
||||
self.init(
|
||||
service: initializer.lightWalletService,
|
||||
storage: initializer.storage,
|
||||
rustBackend: initializer.rustBackend,
|
||||
container: initializer.container,
|
||||
config: Configuration(
|
||||
alias: initializer.alias,
|
||||
fsBlockCacheRoot: initializer.fsBlockDbRoot,
|
||||
|
@ -375,97 +356,37 @@ actor CompactBlockProcessor {
|
|||
walletBirthdayProvider: walletBirthdayProvider,
|
||||
network: initializer.network
|
||||
),
|
||||
repository: initializer.transactionRepository,
|
||||
accountRepository: initializer.accountRepository,
|
||||
metrics: metrics,
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
accountRepository: initializer.accountRepository
|
||||
)
|
||||
}
|
||||
|
||||
internal init(
|
||||
service: LightWalletService,
|
||||
storage: CompactBlockRepository,
|
||||
rustBackend: ZcashRustBackendWelding,
|
||||
container: DIContainer,
|
||||
config: Configuration,
|
||||
repository: TransactionRepository,
|
||||
accountRepository: AccountRepository,
|
||||
metrics: SDKMetrics,
|
||||
logger: Logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
accountRepository: AccountRepository
|
||||
) {
|
||||
self.metrics = metrics
|
||||
self.logger = logger
|
||||
self.latestBlocksDataProvider = latestBlocksDataProvider
|
||||
let internalSyncProgress = InternalSyncProgress(alias: config.alias, storage: UserDefaults.standard, logger: logger)
|
||||
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
|
||||
Dependencies.setupCompactBlockProcessor(
|
||||
in: container,
|
||||
config: config,
|
||||
accountRepository: accountRepository
|
||||
)
|
||||
|
||||
self.blockDownloaderService = blockDownloaderService
|
||||
|
||||
self.blockValidator = BlockValidatorImpl(
|
||||
rustBackend: rustBackend,
|
||||
metrics: metrics,
|
||||
logger: logger
|
||||
)
|
||||
|
||||
let blockScannerConfig = BlockScannerConfig(
|
||||
networkType: config.network.networkType,
|
||||
scanningBatchSize: config.scanningBatchSize
|
||||
)
|
||||
self.blockScanner = BlockScannerImpl(
|
||||
config: blockScannerConfig,
|
||||
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.metrics = container.resolve(SDKMetrics.self)
|
||||
self.logger = container.resolve(Logger.self)
|
||||
self.latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
|
||||
self.internalSyncProgress = container.resolve(InternalSyncProgress.self)
|
||||
self.blockDownloaderService = container.resolve(BlockDownloaderService.self)
|
||||
self.blockDownloader = container.resolve(BlockDownloader.self)
|
||||
self.blockValidator = container.resolve(BlockValidator.self)
|
||||
self.blockScanner = container.resolve(BlockScanner.self)
|
||||
self.blockEnhancer = container.resolve(BlockEnhancer.self)
|
||||
self.utxoFetcher = container.resolve(UTXOFetcher.self)
|
||||
self.saplingParametersHandler = container.resolve(SaplingParametersHandler.self)
|
||||
self.service = container.resolve(LightWalletService.self)
|
||||
self.rustBackend = container.resolve(ZcashRustBackendWelding.self)
|
||||
self.storage = container.resolve(CompactBlockRepository.self)
|
||||
self.config = config
|
||||
self.transactionRepository = repository
|
||||
self.transactionRepository = container.resolve(TransactionRepository.self)
|
||||
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
|
||||
functionality, related to processing blocks.
|
||||
*/
|
||||
// swiftlint:disable:next type_body_length
|
||||
public class Initializer {
|
||||
struct URLs {
|
||||
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.
|
||||
let id = UUID()
|
||||
|
||||
let container: DIContainer
|
||||
let alias: ZcashSynchronizerAlias
|
||||
let endpoint: LightWalletEndpoint
|
||||
let fsBlockDbRoot: URL
|
||||
|
@ -156,87 +158,94 @@ public class Initializer {
|
|||
alias: ZcashSynchronizerAlias = .default,
|
||||
loggingPolicy: LoggingPolicy = .default(.debug)
|
||||
) {
|
||||
let urls = URLs(
|
||||
fsBlockDbRoot: fsBlockDbRoot,
|
||||
dataDbURL: dataDbURL,
|
||||
spendParamsURL: spendParamsURL,
|
||||
outputParamsURL: outputParamsURL
|
||||
)
|
||||
|
||||
let container = DIContainer()
|
||||
|
||||
// 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)
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
let rustBackend = ZcashRustBackend(
|
||||
dbData: updatedURLs.dataDbURL,
|
||||
fsBlockDbRoot: updatedURLs.fsBlockDbRoot,
|
||||
spendParamsPath: updatedURLs.spendParamsURL,
|
||||
outputParamsPath: updatedURLs.outputParamsURL,
|
||||
networkType: network.networkType
|
||||
)
|
||||
|
||||
self.init(
|
||||
rustBackend: rustBackend,
|
||||
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,
|
||||
service: Self.makeLightWalletServiceFactory(endpoint: endpoint).make(),
|
||||
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
|
||||
),
|
||||
network: network,
|
||||
saplingParamsSourceURL: saplingParamsSourceURL,
|
||||
alias: alias,
|
||||
urlsParsingError: parsingError,
|
||||
logger: logger
|
||||
loggingPolicy: loggingPolicy
|
||||
)
|
||||
}
|
||||
|
||||
/// Internal for dependency injection purposes.
|
||||
///
|
||||
/// !!! It's expected that URLs put here are already update with the Alias.
|
||||
init(
|
||||
rustBackend: ZcashRustBackendWelding,
|
||||
convenience init(
|
||||
container: DIContainer,
|
||||
cacheDbURL: URL?,
|
||||
fsBlockDbRoot: URL,
|
||||
dataDbURL: URL,
|
||||
endpoint: LightWalletEndpoint,
|
||||
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?,
|
||||
urls: URLs,
|
||||
endpoint: LightWalletEndpoint,
|
||||
service: LightWalletService,
|
||||
repository: TransactionRepository,
|
||||
accountRepository: AccountRepository,
|
||||
storage: CompactBlockRepository,
|
||||
network: ZcashNetwork,
|
||||
saplingParamsSourceURL: SaplingParamsSourceURL,
|
||||
alias: ZcashSynchronizerAlias,
|
||||
urlsParsingError: ZcashError?,
|
||||
logger: Logger
|
||||
loggingPolicy: LoggingPolicy = .default(.debug)
|
||||
) {
|
||||
self.container = container
|
||||
self.cacheDbURL = cacheDbURL
|
||||
self.rustBackend = rustBackend
|
||||
self.rustBackend = container.resolve(ZcashRustBackendWelding.self)
|
||||
self.fsBlockDbRoot = urls.fsBlockDbRoot
|
||||
self.dataDbURL = urls.dataDbURL
|
||||
self.endpoint = endpoint
|
||||
|
@ -244,20 +253,62 @@ public class Initializer {
|
|||
self.outputParamsURL = urls.outputParamsURL
|
||||
self.saplingParamsSourceURL = saplingParamsSourceURL
|
||||
self.alias = alias
|
||||
self.lightWalletService = service
|
||||
self.transactionRepository = repository
|
||||
self.accountRepository = accountRepository
|
||||
self.storage = storage
|
||||
self.blockDownloaderService = BlockDownloaderServiceImpl(service: service, storage: storage)
|
||||
self.lightWalletService = container.resolve(LightWalletService.self)
|
||||
self.transactionRepository = container.resolve(TransactionRepository.self)
|
||||
self.accountRepository = AccountRepositoryBuilder.build(
|
||||
dataDbURL: urls.dataDbURL,
|
||||
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.walletBirthday = Checkpoint.birthday(with: 0, network: network).height
|
||||
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)
|
||||
}
|
||||
|
||||
// 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`.
|
||||
///
|
||||
|
|
|
@ -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
|
||||
/// - Parameter initializer: a wallet Initializer object
|
||||
public convenience init(initializer: Initializer) {
|
||||
let metrics = SDKMetrics()
|
||||
let latestBlocksDataProvider = LatestBlocksDataProviderImpl(
|
||||
service: initializer.lightWalletService,
|
||||
transactionRepository: initializer.transactionRepository
|
||||
)
|
||||
self.init(
|
||||
status: .unprepared,
|
||||
initializer: initializer,
|
||||
|
@ -63,15 +58,9 @@ public class SDKSynchronizer: Synchronizer {
|
|||
utxoRepository: UTXORepositoryBuilder.build(initializer: initializer),
|
||||
blockProcessor: CompactBlockProcessor(
|
||||
initializer: initializer,
|
||||
metrics: metrics,
|
||||
logger: initializer.logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider,
|
||||
walletBirthdayProvider: { initializer.walletBirthday }
|
||||
),
|
||||
metrics: metrics,
|
||||
syncSessionIDGenerator: UniqueSyncSessionIDGenerator(),
|
||||
syncSessionTicker: .live,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
syncSessionTicker: .live
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -82,10 +71,7 @@ public class SDKSynchronizer: Synchronizer {
|
|||
transactionRepository: TransactionRepository,
|
||||
utxoRepository: UnspentTransactionOutputRepository,
|
||||
blockProcessor: CompactBlockProcessor,
|
||||
metrics: SDKMetrics,
|
||||
syncSessionIDGenerator: SyncSessionIDGenerator,
|
||||
syncSessionTicker: SessionTicker,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
syncSessionTicker: SessionTicker
|
||||
) {
|
||||
self.connectionState = .idle
|
||||
self.underlyingStatus = GenericActor(status)
|
||||
|
@ -95,12 +81,12 @@ public class SDKSynchronizer: Synchronizer {
|
|||
self.utxoRepository = utxoRepository
|
||||
self.blockProcessor = blockProcessor
|
||||
self.network = initializer.network
|
||||
self.metrics = metrics
|
||||
self.metrics = initializer.container.resolve(SDKMetrics.self)
|
||||
self.logger = initializer.logger
|
||||
self.syncSessionIDGenerator = syncSessionIDGenerator
|
||||
self.syncSessionIDGenerator = initializer.container.resolve(SyncSessionIDGenerator.self)
|
||||
self.syncSession = SyncSession(.nullID)
|
||||
self.syncSessionTicker = syncSessionTicker
|
||||
self.latestBlocksDataProvider = latestBlocksDataProvider
|
||||
self.latestBlocksDataProvider = initializer.container.resolve(LatestBlocksDataProvider.self)
|
||||
|
||||
initializer.lightWalletService.connectionStateChange = { [weak self] oldState, newState in
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
@ -52,6 +52,7 @@ class SDKSynchronizerAliasDarksideTests: XCTestCase {
|
|||
|
||||
let coordinator = try await TestCoordinator(
|
||||
alias: alias,
|
||||
container: mockContainer,
|
||||
walletBirthday: birthday,
|
||||
network: network,
|
||||
callPrepareInConstructor: true,
|
||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class AdvancedReOrgTests: XCTestCase {
|
||||
class AdvancedReOrgTests: ZcashTestCase {
|
||||
let sendAmount = Zatoshi(1000)
|
||||
var birthday: BlockHeight = 663150
|
||||
let defaultLatestHeight: BlockHeight = 663175
|
||||
|
@ -29,11 +29,10 @@ class AdvancedReOrgTests: XCTestCase {
|
|||
try await super.setUp()
|
||||
// don't use an exact birthday, users never do.
|
||||
self.coordinator = try await TestCoordinator(
|
||||
container: mockContainer,
|
||||
walletBirthday: birthday + 50,
|
||||
network: network,
|
||||
dbTracingClosure: { logger.debug($0) }
|
||||
network: network
|
||||
)
|
||||
|
||||
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class BalanceTests: XCTestCase {
|
||||
class BalanceTests: ZcashTestCase {
|
||||
let sendAmount = Zatoshi(1000)
|
||||
let defaultLatestHeight: BlockHeight = 663188
|
||||
let branchID = "2bb40e60"
|
||||
|
@ -25,7 +25,11 @@ class BalanceTests: XCTestCase {
|
|||
|
||||
override func setUp() async throws {
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import Foundation
|
|||
import XCTest
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class DarksideSanityCheckTests: XCTestCase {
|
||||
class DarksideSanityCheckTests: ZcashTestCase {
|
||||
let sendAmount: Int64 = 1000
|
||||
var birthday: BlockHeight = 663150
|
||||
let defaultLatestHeight: BlockHeight = 663175
|
||||
|
@ -27,7 +27,11 @@ class DarksideSanityCheckTests: XCTestCase {
|
|||
override func setUp() async throws {
|
||||
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.resetBlocks(dataset: .default)
|
||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
final class InternalStateConsistencyTests: XCTestCase {
|
||||
final class InternalStateConsistencyTests: ZcashTestCase {
|
||||
let sendAmount = Zatoshi(1000)
|
||||
var birthday: BlockHeight = 663150
|
||||
let defaultLatestHeight: BlockHeight = 663175
|
||||
|
@ -28,7 +28,12 @@ final class InternalStateConsistencyTests: XCTestCase {
|
|||
try await super.setUp()
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class PendingTransactionUpdatesTest: XCTestCase {
|
||||
class PendingTransactionUpdatesTest: ZcashTestCase {
|
||||
let sendAmount: Int64 = 1000
|
||||
var birthday: BlockHeight = 663150
|
||||
let defaultLatestHeight: BlockHeight = 663175
|
||||
|
@ -25,7 +25,11 @@ class PendingTransactionUpdatesTest: XCTestCase {
|
|||
override func setUp() async throws {
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
* rewind 10 blocks and request blocks 663241 to 663251
|
||||
*/
|
||||
class ReOrgTests: XCTestCase {
|
||||
class ReOrgTests: ZcashTestCase {
|
||||
let sendAmount: Int64 = 1000
|
||||
let defaultLatestHeight: BlockHeight = 663175
|
||||
let network = DarksideWalletDNetwork()
|
||||
|
@ -44,7 +44,11 @@ class ReOrgTests: XCTestCase {
|
|||
override func setUp() async throws {
|
||||
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)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
|||
@testable import ZcashLightClientKit
|
||||
|
||||
// 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 defaultLatestHeight: BlockHeight = 663175
|
||||
let branchID = "2bb40e60"
|
||||
|
@ -30,7 +30,11 @@ class RewindRescanTests: XCTestCase {
|
|||
override func setUp() async throws {
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
|||
@testable import ZcashLightClientKit
|
||||
|
||||
// FIXME: [#587] disabled until https://github.com/zcash/ZcashLightClientKit/issues/587 fixed
|
||||
class ShieldFundsTests: XCTestCase {
|
||||
class ShieldFundsTests: ZcashTestCase {
|
||||
let sendAmount = Zatoshi(1000)
|
||||
var birthday: BlockHeight = 1631000
|
||||
var coordinator: TestCoordinator!
|
||||
|
@ -25,7 +25,11 @@ class ShieldFundsTests: XCTestCase {
|
|||
override func setUp() async throws {
|
||||
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.service.clearAddedUTXOs()
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import Combine
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class SynchronizerDarksideTests: XCTestCase {
|
||||
class SynchronizerDarksideTests: ZcashTestCase {
|
||||
let sendAmount: Int64 = 1000
|
||||
let defaultLatestHeight: BlockHeight = 663175
|
||||
let branchID = "2bb40e60"
|
||||
|
@ -30,8 +30,16 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
|
||||
override func setUp() async throws {
|
||||
try await super.setUp()
|
||||
idGenerator = MockSyncSessionIDGenerator(ids: [.deadbeef])
|
||||
self.coordinator = try await TestCoordinator(walletBirthday: birthday, network: network, syncSessionIDGenerator: idGenerator)
|
||||
let idGenerator = MockSyncSessionIDGenerator(ids: [.deadbeef])
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -295,14 +303,11 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
]
|
||||
|
||||
XCTAssertEqual(states.count, expectedStates.count)
|
||||
XCTAssertEqual(states[0], expectedStates[0])
|
||||
XCTAssertEqual(states[1], expectedStates[1])
|
||||
XCTAssertEqual(states[2], expectedStates[2])
|
||||
XCTAssertEqual(states[3], expectedStates[3])
|
||||
XCTAssertEqual(states[4], expectedStates[4])
|
||||
XCTAssertEqual(states[5], expectedStates[5])
|
||||
XCTAssertEqual(states[6], expectedStates[6])
|
||||
XCTAssertEqual(states[7], expectedStates[7])
|
||||
|
||||
for (index, state) in states.enumerated() {
|
||||
let expectedState = expectedStates[index]
|
||||
XCTAssertEqual(state, expectedState, "Failed state comparison at index \(index).")
|
||||
}
|
||||
}
|
||||
|
||||
func testSyncSessionUpdates() async throws {
|
||||
|
@ -458,13 +463,11 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
]
|
||||
|
||||
XCTAssertEqual(states.count, expectedStates.count)
|
||||
XCTAssertEqual(states[0], expectedStates[0])
|
||||
XCTAssertEqual(states[1], expectedStates[1])
|
||||
XCTAssertEqual(states[2], expectedStates[2])
|
||||
XCTAssertEqual(states[3], expectedStates[3])
|
||||
XCTAssertEqual(states[4], expectedStates[4])
|
||||
XCTAssertEqual(states[5], expectedStates[5])
|
||||
XCTAssertEqual(states[7], expectedStates[7])
|
||||
|
||||
for (index, state) in states.enumerated() {
|
||||
let expectedState = expectedStates[index]
|
||||
XCTAssertEqual(state, expectedState, "Failed state comparison at index \(index).")
|
||||
}
|
||||
|
||||
try coordinator.service.applyStaged(nextLatestHeight: 663_200)
|
||||
|
||||
|
@ -532,11 +535,11 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
]
|
||||
|
||||
XCTAssertEqual(states.count, secondBatchOfExpectedStates.count)
|
||||
XCTAssertEqual(states[0], secondBatchOfExpectedStates[0])
|
||||
XCTAssertEqual(states[1], secondBatchOfExpectedStates[1])
|
||||
XCTAssertEqual(states[2], secondBatchOfExpectedStates[2])
|
||||
XCTAssertEqual(states[3], secondBatchOfExpectedStates[3])
|
||||
XCTAssertEqual(states[4], secondBatchOfExpectedStates[4])
|
||||
|
||||
for (index, state) in states.enumerated() {
|
||||
let expectedState = secondBatchOfExpectedStates[index]
|
||||
XCTAssertEqual(state, expectedState, "Failed state comparison at index \(index).")
|
||||
}
|
||||
}
|
||||
|
||||
func testSyncAfterWipeWorks() async throws {
|
||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
final class SynchronizerTests: XCTestCase {
|
||||
final class SynchronizerTests: ZcashTestCase {
|
||||
let sendAmount = Zatoshi(1000)
|
||||
var birthday: BlockHeight = 663150
|
||||
let defaultLatestHeight: BlockHeight = 663175
|
||||
|
@ -28,7 +28,11 @@ final class SynchronizerTests: XCTestCase {
|
|||
try await super.setUp()
|
||||
|
||||
// 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)
|
||||
|
||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class TransactionEnhancementTests: XCTestCase {
|
||||
class TransactionEnhancementTests: ZcashTestCase {
|
||||
var cancellables: [AnyCancellable] = []
|
||||
var processorEventHandler: CompactBlockProcessorEventHandler! = CompactBlockProcessorEventHandler()
|
||||
let mockLatestHeight = BlockHeight(663250)
|
||||
|
@ -134,14 +134,29 @@ class TransactionEnhancementTests: XCTestCase {
|
|||
)
|
||||
|
||||
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(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||
container: mockContainer,
|
||||
config: processorConfig
|
||||
)
|
||||
|
||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||
|
|
|
@ -10,7 +10,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class Z2TReceiveTests: XCTestCase {
|
||||
class Z2TReceiveTests: ZcashTestCase {
|
||||
let testRecipientAddress = "t1dRJRY7GmyeykJnMH38mdQoaZtFhn1QmGz"
|
||||
let sendAmount: Int64 = 1000
|
||||
var birthday: BlockHeight = 663150
|
||||
|
@ -28,7 +28,11 @@ class Z2TReceiveTests: XCTestCase {
|
|||
override func setUp() async throws {
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import SQLite
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class BlockScanTests: XCTestCase {
|
||||
class BlockScanTests: ZcashTestCase {
|
||||
var cancelables: [AnyCancellable] = []
|
||||
|
||||
var dataDbURL: URL!
|
||||
|
@ -51,6 +51,23 @@ class BlockScanTests: XCTestCase {
|
|||
)
|
||||
|
||||
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() {
|
||||
|
@ -73,24 +90,9 @@ class BlockScanTests: XCTestCase {
|
|||
_ = try await rustBackend.initDataDb(seed: nil)
|
||||
|
||||
let endpoint = LightWalletEndpoint(address: "lightwalletd.testnet.electriccoin.co", port: 9067)
|
||||
let service = LightWalletServiceFactory(endpoint: endpoint).make()
|
||||
let blockCount = 100
|
||||
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(
|
||||
alias: .default,
|
||||
fsBlockCacheRoot: testTempDirectory,
|
||||
|
@ -102,15 +104,12 @@ class BlockScanTests: XCTestCase {
|
|||
network: network
|
||||
)
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: fsBlockRepository,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||
LightWalletServiceFactory(endpoint: endpoint).make()
|
||||
}
|
||||
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||
|
||||
let repository = BlockSQLDAO(dbProvider: SimpleConnectionProvider.init(path: self.dataDbURL.absoluteString, readonly: true))
|
||||
var latestScannedheight = BlockHeight.empty()
|
||||
|
@ -162,22 +161,6 @@ class BlockScanTests: XCTestCase {
|
|||
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(
|
||||
alias: .default,
|
||||
fsBlockCacheRoot: testTempDirectory,
|
||||
|
@ -191,15 +174,12 @@ class BlockScanTests: XCTestCase {
|
|||
network: network
|
||||
)
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: fsBlockRepository,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: metrics,
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||
LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
||||
}
|
||||
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||
|
||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||
switch event {
|
||||
|
@ -220,7 +200,7 @@ class BlockScanTests: XCTestCase {
|
|||
try await blockDownloader.setSyncRange(range)
|
||||
await blockDownloader.startDownload(maxBlockBufferSize: 10)
|
||||
try await blockDownloader.waitUntilRequestedBlocksAreDownloaded(in: range)
|
||||
|
||||
|
||||
XCTAssertFalse(Task.isCancelled)
|
||||
|
||||
try await compactBlockProcessor.blockValidator.validate()
|
||||
|
|
|
@ -9,7 +9,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class BlockStreamingTest: XCTestCase {
|
||||
class BlockStreamingTest: ZcashTestCase {
|
||||
let testFileManager = FileManager()
|
||||
var rustBackend: ZcashRustBackendWelding!
|
||||
var testTempDirectory: URL!
|
||||
|
@ -21,6 +21,24 @@ class BlockStreamingTest: XCTestCase {
|
|||
|
||||
try self.testFileManager.createDirectory(at: testTempDirectory, withIntermediateDirectories: false)
|
||||
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 {
|
||||
|
@ -70,20 +88,6 @@ class BlockStreamingTest: XCTestCase {
|
|||
)
|
||||
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 startHeight = latestBlockHeight - 100_000
|
||||
let processorConfig = CompactBlockProcessor.Configuration.standard(
|
||||
|
@ -91,15 +95,12 @@ class BlockStreamingTest: XCTestCase {
|
|||
walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.saplingActivationHeight
|
||||
)
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||
LightWalletServiceFactory(endpoint: endpoint).make()
|
||||
}
|
||||
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||
|
||||
let cancelableTask = Task {
|
||||
do {
|
||||
|
@ -127,20 +128,6 @@ class BlockStreamingTest: XCTestCase {
|
|||
)
|
||||
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 startHeight = latestBlockHeight - 100_000
|
||||
|
@ -150,15 +137,12 @@ class BlockStreamingTest: XCTestCase {
|
|||
walletBirthday: ZcashNetworkBuilder.network(for: .testnet).constants.saplingActivationHeight
|
||||
)
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||
LightWalletServiceFactory(endpoint: endpoint).make()
|
||||
}
|
||||
try await mockContainer.resolve(CompactBlockRepository.self).create()
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||
|
||||
let date = Date()
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class CompactBlockProcessorTests: XCTestCase {
|
||||
class CompactBlockProcessorTests: ZcashTestCase {
|
||||
var processorConfig: CompactBlockProcessor.Configuration!
|
||||
var cancellables: [AnyCancellable] = []
|
||||
var processorEventHandler: CompactBlockProcessorEventHandler! = CompactBlockProcessorEventHandler()
|
||||
|
@ -73,20 +73,6 @@ class CompactBlockProcessorTests: XCTestCase {
|
|||
info.estimatedHeight = UInt64(mockLatestHeight)
|
||||
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(
|
||||
unminedCount: 0,
|
||||
|
@ -96,15 +82,28 @@ class CompactBlockProcessorTests: XCTestCase {
|
|||
network: network
|
||||
)
|
||||
|
||||
processor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||
Dependencies.setup(
|
||||
in: mockContainer,
|
||||
urls: Initializer.URLs(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
dataDbURL: processorConfig.dataDb,
|
||||
spendParamsURL: processorConfig.spendParamsURL,
|
||||
outputParamsURL: processorConfig.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 }
|
||||
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)
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class CompactBlockReorgTests: XCTestCase {
|
||||
class CompactBlockReorgTests: ZcashTestCase {
|
||||
var processorConfig: CompactBlockProcessor.Configuration!
|
||||
let testFileManager = FileManager()
|
||||
var cancellables: [AnyCancellable] = []
|
||||
|
@ -110,16 +110,29 @@ class CompactBlockReorgTests: XCTestCase {
|
|||
network: network
|
||||
)
|
||||
|
||||
processor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: realCache,
|
||||
rustBackend: rustBackendMockHelper.rustBackendMock,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||
Dependencies.setup(
|
||||
in: mockContainer,
|
||||
urls: Initializer.URLs(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
dataDbURL: processorConfig.dataDb,
|
||||
spendParamsURL: processorConfig.spendParamsURL,
|
||||
outputParamsURL: processorConfig.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.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")
|
||||
stopNotificationExpectation = XCTestExpectation(description: "\(self.description) stopNotificationExpectation")
|
||||
updatedNotificationExpectation = XCTestExpectation(description: "\(self.description) updatedNotificationExpectation")
|
||||
|
|
|
@ -11,7 +11,7 @@ import SQLite
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class DownloadTests: XCTestCase {
|
||||
class DownloadTests: ZcashTestCase {
|
||||
let testFileManager = FileManager()
|
||||
var network = ZcashNetworkBuilder.network(for: .testnet)
|
||||
var testTempDirectory: URL!
|
||||
|
@ -23,6 +23,22 @@ class DownloadTests: XCTestCase {
|
|||
await InternalSyncProgress(alias: .default, storage: UserDefaults.standard, logger: logger).rewind(to: 0)
|
||||
|
||||
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 {
|
||||
|
@ -32,21 +48,13 @@ class DownloadTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testSingleDownload() async throws {
|
||||
let service = LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
||||
let rustBackend = ZcashRustBackend.makeForTests(fsBlockDbRoot: testTempDirectory, networkType: network.networkType)
|
||||
|
||||
let storage = FSCompactBlockRepository(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
metadataStore: FSMetadataStore.live(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
rustBackend: rustBackend,
|
||||
logger: logger
|
||||
),
|
||||
blockDescriptor: .live,
|
||||
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||
logger: logger
|
||||
)
|
||||
|
||||
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in
|
||||
ZcashRustBackend.makeForTests(fsBlockDbRoot: self.testTempDirectory, networkType: self.network.networkType)
|
||||
}
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in
|
||||
LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
||||
}
|
||||
let storage = mockContainer.resolve(CompactBlockRepository.self)
|
||||
try await storage.create()
|
||||
|
||||
let blockCount = 100
|
||||
|
@ -58,15 +66,7 @@ class DownloadTests: XCTestCase {
|
|||
walletBirthday: network.constants.saplingActivationHeight
|
||||
)
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
let compactBlockProcessor = CompactBlockProcessor(container: mockContainer, config: processorConfig)
|
||||
|
||||
do {
|
||||
try await compactBlockProcessor.blockDownloaderService.downloadBlockRange(range)
|
||||
|
|
|
@ -9,7 +9,7 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class BlockBatchValidationTests: XCTestCase {
|
||||
class BlockBatchValidationTests: ZcashTestCase {
|
||||
let testFileManager = FileManager()
|
||||
var rustBackend: ZcashRustBackendWelding!
|
||||
var testTempDirectory: URL!
|
||||
|
@ -17,6 +17,23 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
override func setUpWithError() throws {
|
||||
try super.setUpWithError()
|
||||
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)
|
||||
rustBackend = ZcashRustBackend.makeForTests(fsBlockDbRoot: testTempDirectory, networkType: .testnet)
|
||||
}
|
||||
|
@ -34,6 +51,7 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
latestBlockHeight: 1210000,
|
||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||
|
||||
let storage = FSCompactBlockRepository(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
|
@ -46,11 +64,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||
logger: logger
|
||||
)
|
||||
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||
|
||||
try await storage.create()
|
||||
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
}
|
||||
|
||||
let config = CompactBlockProcessor.Configuration(
|
||||
alias: .default,
|
||||
fsBlockCacheRoot: testTempDirectory,
|
||||
|
@ -77,19 +99,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
service.mockLightDInfo = info
|
||||
|
||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: Int32(0xd34d))
|
||||
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
container: mockContainer,
|
||||
config: config
|
||||
)
|
||||
|
||||
do {
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||
XCTAssertFalse(Task.isCancelled)
|
||||
} catch {
|
||||
switch error {
|
||||
|
@ -107,6 +125,7 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
latestBlockHeight: 1210000,
|
||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||
|
||||
let storage = FSCompactBlockRepository(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
|
@ -119,11 +138,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||
logger: logger
|
||||
)
|
||||
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||
|
||||
try await storage.create()
|
||||
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
}
|
||||
|
||||
let config = CompactBlockProcessor.Configuration(
|
||||
alias: .default,
|
||||
fsBlockCacheRoot: testTempDirectory,
|
||||
|
@ -150,19 +173,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
service.mockLightDInfo = info
|
||||
|
||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
||||
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
container: mockContainer,
|
||||
config: config
|
||||
)
|
||||
|
||||
do {
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||
XCTAssertFalse(Task.isCancelled)
|
||||
} catch {
|
||||
switch error {
|
||||
|
@ -180,6 +199,7 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
latestBlockHeight: 1210000,
|
||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||
|
||||
let storage = FSCompactBlockRepository(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
|
@ -192,11 +212,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||
logger: logger
|
||||
)
|
||||
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||
|
||||
try await storage.create()
|
||||
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
}
|
||||
|
||||
let config = CompactBlockProcessor.Configuration(
|
||||
alias: .default,
|
||||
fsBlockCacheRoot: testTempDirectory,
|
||||
|
@ -223,19 +247,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
service.mockLightDInfo = info
|
||||
|
||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
||||
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
container: mockContainer,
|
||||
config: config
|
||||
)
|
||||
|
||||
do {
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||
XCTAssertFalse(Task.isCancelled)
|
||||
} catch {
|
||||
switch error {
|
||||
|
@ -253,6 +273,7 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
latestBlockHeight: 1210000,
|
||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||
|
||||
let storage = FSCompactBlockRepository(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
|
@ -265,11 +286,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||
logger: logger
|
||||
)
|
||||
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||
|
||||
try await storage.create()
|
||||
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
mockContainer.mock(type: BlockDownloaderService.self, isSingleton: true) { _ in
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
|
||||
return BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
}
|
||||
|
||||
let config = CompactBlockProcessor.Configuration(
|
||||
alias: .default,
|
||||
fsBlockCacheRoot: testTempDirectory,
|
||||
|
@ -297,19 +322,15 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
service.mockLightDInfo = info
|
||||
|
||||
let mockBackend = await RustBackendMockHelper(rustBackend: rustBackend, consensusBranchID: 0xd34db4d)
|
||||
mockContainer.mock(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in mockBackend.rustBackendMock }
|
||||
|
||||
let compactBlockProcessor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
container: mockContainer,
|
||||
config: config
|
||||
)
|
||||
|
||||
do {
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: downloaderService)
|
||||
try await compactBlockProcessor.figureNextBatch(downloaderService: mockContainer.resolve(BlockDownloaderService.self))
|
||||
XCTAssertFalse(Task.isCancelled)
|
||||
} catch {
|
||||
switch error {
|
||||
|
|
|
@ -9,13 +9,28 @@ import XCTest
|
|||
@testable import TestUtils
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class CompactBlockProcessorOfflineTests: XCTestCase {
|
||||
class CompactBlockProcessorOfflineTests: ZcashTestCase {
|
||||
let testFileManager = FileManager()
|
||||
var testTempDirectory: URL!
|
||||
|
||||
override func setUpWithError() throws {
|
||||
try super.setUpWithError()
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -37,6 +52,7 @@ class CompactBlockProcessorOfflineTests: XCTestCase {
|
|||
latestBlockHeight: 690000,
|
||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.eccTestnet).make()
|
||||
)
|
||||
mockContainer.mock(type: LightWalletService.self, isSingleton: true) { _ in service }
|
||||
|
||||
let storage = FSCompactBlockRepository(
|
||||
fsBlockDbRoot: testTempDirectory,
|
||||
|
@ -49,15 +65,12 @@ class CompactBlockProcessorOfflineTests: XCTestCase {
|
|||
contentProvider: DirectoryListingProviders.defaultSorted,
|
||||
logger: logger
|
||||
)
|
||||
mockContainer.mock(type: CompactBlockRepository.self, isSingleton: true) { _ in storage }
|
||||
mockContainer.mock(type: LatestBlocksDataProvider.self, isSingleton: true) { _ in LatestBlocksDataProviderMock() }
|
||||
|
||||
let processor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
container: mockContainer,
|
||||
config: processorConfig
|
||||
)
|
||||
|
||||
let fullRange = 0...1000
|
||||
|
|
|
@ -11,7 +11,7 @@ import Foundation
|
|||
import XCTest
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
class SynchronizerOfflineTests: XCTestCase {
|
||||
class SynchronizerOfflineTests: ZcashTestCase {
|
||||
let data = TestsData(networkType: .testnet)
|
||||
var network: ZcashNetwork!
|
||||
var cancellables: [AnyCancellable] = []
|
||||
|
@ -31,6 +31,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
func testCallPrepareWithAlreadyUsedAliasThrowsError() async throws {
|
||||
let firstTestCoordinator = try await TestCoordinator(
|
||||
alias: .custom("alias"),
|
||||
container: mockContainer,
|
||||
walletBirthday: 10,
|
||||
network: network,
|
||||
callPrepareInConstructor: false
|
||||
|
@ -38,6 +39,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
|
||||
let secondTestCoordinator = try await TestCoordinator(
|
||||
alias: .custom("alias"),
|
||||
container: mockContainer,
|
||||
walletBirthday: 10,
|
||||
network: network,
|
||||
callPrepareInConstructor: false
|
||||
|
@ -58,6 +60,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
func testWhenSynchronizerIsDeallocatedAliasIsntUsedAnymore() async throws {
|
||||
var testCoordinator: TestCoordinator! = try await TestCoordinator(
|
||||
alias: .default,
|
||||
container: mockContainer,
|
||||
walletBirthday: 10,
|
||||
network: network,
|
||||
callPrepareInConstructor: false
|
||||
|
@ -71,6 +74,7 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
|
||||
testCoordinator = try await TestCoordinator(
|
||||
alias: .default,
|
||||
container: mockContainer,
|
||||
walletBirthday: 10,
|
||||
network: network,
|
||||
callPrepareInConstructor: false
|
||||
|
@ -84,8 +88,21 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testCallWipeWithAlreadyUsedAliasThrowsError() async throws {
|
||||
let firstTestCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
||||
let secondTestCoordinator = try await TestCoordinator(alias: .default, walletBirthday: 10, network: network, callPrepareInConstructor: false)
|
||||
let firstTestCoordinator = try await TestCoordinator(
|
||||
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")
|
||||
|
||||
|
@ -129,7 +146,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
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")
|
||||
|
||||
|
@ -157,7 +180,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
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 {
|
||||
_ = 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 {
|
||||
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 {
|
||||
_ = try await testCoordinator.synchronizer.shieldFunds(
|
||||
|
@ -213,7 +229,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
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 {
|
||||
_ = try await testCoordinator.synchronizer.refreshUTXOs(address: data.transparentAddress, from: 1)
|
||||
|
@ -227,7 +249,13 @@ class SynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
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()
|
||||
|
||||
|
|
|
@ -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(
|
||||
alias: ZcashSynchronizerAlias = .default,
|
||||
container: DIContainer,
|
||||
walletBirthday: BlockHeight,
|
||||
network: ZcashNetwork,
|
||||
callPrepareInConstructor: Bool = true,
|
||||
|
@ -63,86 +64,40 @@ class TestCoordinator {
|
|||
dbTracingClosure: ((String) -> Void)? = nil
|
||||
) async throws {
|
||||
await InternalSyncProgress(alias: alias, storage: UserDefaults.standard, logger: logger).rewind(to: 0)
|
||||
|
||||
|
||||
let databases = TemporaryDbBuilder.build()
|
||||
self.databases = databases
|
||||
|
||||
let urls = Initializer.URLs(
|
||||
|
||||
let initializer = Initializer(
|
||||
container: container,
|
||||
cacheDbURL: nil,
|
||||
fsBlockDbRoot: databases.fsCacheDbRoot,
|
||||
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,
|
||||
service: service,
|
||||
repository: transactionRepository,
|
||||
accountRepository: accountRepository,
|
||||
storage: fsBlockRepository,
|
||||
network: network,
|
||||
spendParamsURL: try __spendParamsURL(),
|
||||
outputParamsURL: try __outputParamsURL(),
|
||||
saplingParamsSourceURL: SaplingParamsSourceURL.tests,
|
||||
alias: alias,
|
||||
urlsParsingError: parsingError,
|
||||
logger: OSLogger(logLevel: .debug)
|
||||
loggingPolicy: .default(.debug)
|
||||
)
|
||||
|
||||
|
||||
let derivationTool = DerivationTool(networkType: network.networkType)
|
||||
|
||||
|
||||
self.spendingKey = try derivationTool.deriveUnifiedSpendingKey(
|
||||
seed: Environment.seedBytes,
|
||||
accountIndex: 0
|
||||
)
|
||||
|
||||
|
||||
self.viewingKey = try derivationTool.deriveUnifiedFullViewingKey(from: spendingKey)
|
||||
self.birthday = walletBirthday
|
||||
self.network = network
|
||||
|
||||
|
||||
let liveService = LightWalletServiceFactory(endpoint: endpoint).make()
|
||||
self.service = DarksideWalletService(endpoint: endpoint, service: liveService)
|
||||
|
||||
self.synchronizer = SDKSynchronizer(initializer: initializer, sessionGenerator: syncSessionIDGenerator, sessionTicker: .live)
|
||||
self.synchronizer = SDKSynchronizer(initializer: initializer)
|
||||
subscribeToState(synchronizer: self.synchronizer)
|
||||
|
||||
|
||||
if callPrepareInConstructor {
|
||||
if case .seedRequired = try await prepare(seed: Environment.seedBytes) {
|
||||
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