[#700] Fix DarksideTests

Closes #1102

Some tests that can't be compiled are disabled for now. List is in #1126.

This PR contains multiple fixes. Most of the fixes is done in the code.
Not in the tests. That is good news.

Fixes:
- `config` inside `CompactBlockProcessor` can be updated during the
  tests. And it must be also updated inside the actions. So
  `ConfigProvider` is added and it is wrapper for config that is passed
  to any instance of `Action` and provides updated config.
- Fixed `EnhanceAction`. Now it should update all the blocks in the
  enhance range even when the remaining count of blocks is lower than
  1000.
- Fixed `fail()` and `validationFailed()`. These two were canceling
  `syncTask`. But that stopped run loop in a bad way.
This commit is contained in:
Michal Fousek 2023-05-24 14:53:09 +02:00
parent e267435d84
commit 213c767e3c
25 changed files with 449 additions and 550 deletions

View File

@ -8,14 +8,14 @@
import Foundation
final class ComputeSyncRangesAction {
let config: CompactBlockProcessor.Configuration
let configProvider: CompactBlockProcessor.ConfigProvider
let downloaderService: BlockDownloaderService
let internalSyncProgress: InternalSyncProgress
let latestBlocksDataProvider: LatestBlocksDataProvider
let logger: Logger
init(container: DIContainer, config: CompactBlockProcessor.Configuration) {
self.config = config
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider
downloaderService = container.resolve(BlockDownloaderService.self)
internalSyncProgress = container.resolve(InternalSyncProgress.self)
latestBlocksDataProvider = container.resolve(LatestBlocksDataProvider.self)
@ -46,6 +46,7 @@ extension ComputeSyncRangesAction: Action {
// call internalSyncProgress and compute sync ranges and store them in context
// if there is nothing sync just switch to finished state
let config = await configProvider.config
let latestDownloadHeight = try await downloaderService.lastDownloadedBlockHeight()
await internalSyncProgress.migrateIfNeeded(latestDownloadedBlockHeightFromCacheDB: latestDownloadHeight)

View File

@ -8,13 +8,13 @@
import Foundation
final class DownloadAction {
let config: CompactBlockProcessor.Configuration
let configProvider: CompactBlockProcessor.ConfigProvider
let downloader: BlockDownloader
let transactionRepository: TransactionRepository
let logger: Logger
init(container: DIContainer, config: CompactBlockProcessor.Configuration) {
self.config = config
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider
downloader = container.resolve(BlockDownloader.self)
transactionRepository = container.resolve(TransactionRepository.self)
logger = container.resolve(Logger.self)
@ -34,6 +34,7 @@ extension DownloadAction: Action {
return await update(context: context)
}
let config = await configProvider.config
let lastScannedHeight = try await transactionRepository.lastScannedHeight()
// This action is executed for each batch (batch size is 100 blocks by default) until all the blocks in whole `downloadRange` are downloaded.
// So the right range for this batch must be computed.

View File

@ -9,13 +9,13 @@ import Foundation
final class EnhanceAction {
let blockEnhancer: BlockEnhancer
let config: CompactBlockProcessor.Configuration
let configProvider: CompactBlockProcessor.ConfigProvider
let internalSyncProgress: InternalSyncProgress
let logger: Logger
let transactionRepository: TransactionRepository
init(container: DIContainer, config: CompactBlockProcessor.Configuration) {
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
blockEnhancer = container.resolve(BlockEnhancer.self)
self.config = config
self.configProvider = configProvider
internalSyncProgress = container.resolve(InternalSyncProgress.self)
logger = container.resolve(Logger.self)
transactionRepository = container.resolve(TransactionRepository.self)
@ -49,6 +49,7 @@ extension EnhanceAction: Action {
// If latestScannedHeight < context.scanRanges.downloadAndScanRange?.upperBound then set state to `download` because there are blocks to
// download and scan.
let config = await configProvider.config
let lastScannedHeight = try await transactionRepository.lastScannedHeight()
guard let range = await context.syncRanges.enhanceRange else {
@ -59,7 +60,14 @@ extension EnhanceAction: Action {
let enhanceRangeStart = max(range.lowerBound, lastEnhancedHeight)
let enhanceRangeEnd = min(range.upperBound, lastScannedHeight)
if enhanceRangeStart <= enhanceRangeEnd && lastScannedHeight - lastEnhancedHeight >= config.enhanceBatchSize {
// This may happen:
// For example whole enhance range is 0...2100 Without this force enhance is done for ranges: 0...1000, 1001...2000. And that's it.
// Last 100 blocks isn't enhanced.
//
// This force makes sure that all the blocks are enhanced even when last enhance happened < 1000 blocks ago.
let forceEnhance = enhanceRangeEnd == range.upperBound && enhanceRangeEnd - enhanceRangeStart <= config.enhanceBatchSize
if forceEnhance || (enhanceRangeStart <= enhanceRangeEnd && lastScannedHeight - lastEnhancedHeight >= config.enhanceBatchSize) {
let enhanceRange = enhanceRangeStart...enhanceRangeEnd
let transactions = try await blockEnhancer.enhance(
at: enhanceRange,

View File

@ -8,14 +8,14 @@
import Foundation
final class MigrateLegacyCacheDBAction {
private let config: CompactBlockProcessor.Configuration
private let configProvider: CompactBlockProcessor.ConfigProvider
private let internalSyncProgress: InternalSyncProgress
private let storage: CompactBlockRepository
private let transactionRepository: TransactionRepository
private let fileManager: ZcashFileManager
init(container: DIContainer, config: CompactBlockProcessor.Configuration) {
self.config = config
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider
internalSyncProgress = container.resolve(InternalSyncProgress.self)
storage = container.resolve(CompactBlockRepository.self)
transactionRepository = container.resolve(TransactionRepository.self)
@ -32,6 +32,7 @@ extension MigrateLegacyCacheDBAction: Action {
var removeBlocksCacheWhenFailed: Bool { false }
func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext {
let config = await configProvider.config
guard let legacyCacheDbURL = config.cacheDbURL else {
return await updateState(context)
}

View File

@ -8,13 +8,13 @@
import Foundation
final class ScanAction {
let config: CompactBlockProcessor.Configuration
let configProvider: CompactBlockProcessor.ConfigProvider
let blockScanner: BlockScanner
let logger: Logger
let transactionRepository: TransactionRepository
init(container: DIContainer, config: CompactBlockProcessor.Configuration) {
self.config = config
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider
blockScanner = container.resolve(BlockScanner.self)
transactionRepository = container.resolve(TransactionRepository.self)
logger = container.resolve(Logger.self)
@ -33,7 +33,8 @@ extension ScanAction: Action {
guard let scanRange = await context.syncRanges.scanRange else {
return await update(context: context)
}
let config = await configProvider.config
let lastScannedHeight = try await transactionRepository.lastScannedHeight()
// This action is executed for each batch (batch size is 100 blocks by default) until all the blocks in whole `scanRange` are scanned.
// So the right range for this batch must be computed.

View File

@ -8,12 +8,12 @@
import Foundation
final class ValidateServerAction {
let config: CompactBlockProcessor.Configuration
let configProvider: CompactBlockProcessor.ConfigProvider
let rustBackend: ZcashRustBackendWelding
let service: LightWalletService
init(container: DIContainer, config: CompactBlockProcessor.Configuration) {
self.config = config
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider
rustBackend = container.resolve(ZcashRustBackendWelding.self)
service = container.resolve(LightWalletService.self)
}
@ -23,6 +23,7 @@ extension ValidateServerAction: Action {
var removeBlocksCacheWhenFailed: Bool { false }
func run(with context: ActionContext, didUpdate: @escaping (CompactBlockProcessor.Event) async -> Void) async throws -> ActionContext {
let config = await configProvider.config
let info = try await service.getInfo()
let localNetwork = config.network
let saplingActivation = config.saplingActivation

View File

@ -25,6 +25,7 @@ actor CompactBlockProcessor {
private var context: ActionContext
private(set) var config: Configuration
private let configProvider: ConfigProvider
private var afterSyncHooksManager = AfterSyncHooksManager()
private let accountRepository: AccountRepository
@ -34,7 +35,7 @@ actor CompactBlockProcessor {
private let logger: Logger
private let metrics: SDKMetrics
private let rustBackend: ZcashRustBackendWelding
private let service: LightWalletService
let service: LightWalletService
private let storage: CompactBlockRepository
private let transactionRepository: TransactionRepository
private let fileManager: ZcashFileManager
@ -182,8 +183,9 @@ actor CompactBlockProcessor {
accountRepository: accountRepository
)
let configProvider = ConfigProvider(config: config)
context = ActionContext(state: .idle)
actions = Self.makeActions(container: container, config: config)
actions = Self.makeActions(container: container, configProvider: configProvider)
self.metrics = container.resolve(SDKMetrics.self)
self.logger = container.resolve(Logger.self)
@ -197,6 +199,7 @@ actor CompactBlockProcessor {
self.transactionRepository = container.resolve(TransactionRepository.self)
self.accountRepository = accountRepository
self.fileManager = container.resolve(ZcashFileManager.self)
self.configProvider = configProvider
}
deinit {
@ -205,28 +208,28 @@ actor CompactBlockProcessor {
}
// swiftlint:disable:next cyclomatic_complexity
private static func makeActions(container: DIContainer, config: Configuration) -> [CBPState: Action] {
private static func makeActions(container: DIContainer, configProvider: ConfigProvider) -> [CBPState: Action] {
let actionsDefinition = CBPState.allCases.compactMap { state -> (CBPState, Action)? in
let action: Action
switch state {
case .migrateLegacyCacheDB:
action = MigrateLegacyCacheDBAction(container: container, config: config)
action = MigrateLegacyCacheDBAction(container: container, configProvider: configProvider)
case .validateServer:
action = ValidateServerAction(container: container, config: config)
action = ValidateServerAction(container: container, configProvider: configProvider)
case .computeSyncRanges:
action = ComputeSyncRangesAction(container: container, config: config)
action = ComputeSyncRangesAction(container: container, configProvider: configProvider)
case .checksBeforeSync:
action = ChecksBeforeSyncAction(container: container)
case .download:
action = DownloadAction(container: container, config: config)
action = DownloadAction(container: container, configProvider: configProvider)
case .validate:
action = ValidateAction(container: container)
case .scan:
action = ScanAction(container: container, config: config)
action = ScanAction(container: container, configProvider: configProvider)
case .clearAlreadyScannedBlocks:
action = ClearAlreadyScannedBlocksAction(container: container)
case .enhance:
action = EnhanceAction(container: container, config: config)
action = EnhanceAction(container: container, configProvider: configProvider)
case .fetchUTXO:
action = FetchUTXOsAction(container: container)
case .handleSaplingParams:
@ -242,6 +245,12 @@ actor CompactBlockProcessor {
return Dictionary(uniqueKeysWithValues: actionsDefinition)
}
// This is currently used only in tests. And it should be used only in tests.
func update(config: Configuration) async {
self.config = config
await configProvider.update(config: config)
}
}
// MARK: - "Public" API
@ -271,7 +280,10 @@ extension CompactBlockProcessor {
}
func stop() async {
await rawStop()
syncTask?.cancel()
self.backoffTimer?.invalidate()
self.backoffTimer = nil
await stopAllActions()
retryAttempts = 0
}
@ -621,9 +633,6 @@ extension CompactBlockProcessor {
}
private func validationFailed(at height: BlockHeight) async throws {
// cancel all Tasks
await rawStop()
// rewind
let rewindHeight = determineLowerBound(
errorHeight: height,
@ -645,7 +654,6 @@ extension CompactBlockProcessor {
await context.update(state: .failed)
logger.error("Fail with error: \(error)")
await rawStop()
self.retryAttempts += 1
await send(event: .failed(error))
@ -728,13 +736,6 @@ extension CompactBlockProcessor {
return max(errorHeight - offset, walletBirthday - ZcashSDK.maxReorgSize)
}
private func rawStop() async {
syncTask?.cancel()
self.backoffTimer?.invalidate()
self.backoffTimer = nil
await stopAllActions()
}
private func stopAllActions() async {
for action in actions.values {
await action.stop()
@ -841,3 +842,18 @@ extension CompactBlockProcessor {
return (inserted: refreshed, skipped: skipped)
}
}
// MARK: - Config provider
extension CompactBlockProcessor {
actor ConfigProvider {
var config: Configuration
init(config: Configuration) {
self.config = config
}
func update(config: Configuration) async {
self.config = config
}
}
}

View File

@ -59,7 +59,7 @@ class SDKSynchronizerAliasDarksideTests: ZcashTestCase {
endpoint: endpoint
)
try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
try await coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
coordinators.append(coordinator)
}

View File

@ -33,7 +33,7 @@ class AdvancedReOrgTests: ZcashTestCase {
walletBirthday: birthday + 50,
network: network
)
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
try await coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
}
override func tearDown() async throws {
@ -453,7 +453,7 @@ class AdvancedReOrgTests: ZcashTestCase {
await hookToReOrgNotification()
self.expectedReorgHeight = 663196
self.expectedRewindHeight = 663175
try coordinator.reset(saplingActivation: birthday, branchID: "2bb40e60", chainName: "main")
try await coordinator.reset(saplingActivation: birthday, branchID: "2bb40e60", chainName: "main")
try coordinator.resetBlocks(dataset: .predefined(dataset: .txIndexChangeBefore))
try coordinator.applyStaged(blockheight: 663195)
sleep(1)
@ -1031,7 +1031,7 @@ class AdvancedReOrgTests: ZcashTestCase {
/// 8. sync to latest height
/// 9. verify that the balance is equal to the one before the reorg
func testReOrgChangesInboundMinedHeight() async throws {
try coordinator.reset(saplingActivation: 663150, branchID: branchID, chainName: chainName)
try await coordinator.reset(saplingActivation: 663150, branchID: branchID, chainName: chainName)
sleep(2)
try coordinator.resetBlocks(dataset: .predefined(dataset: .txHeightReOrgBefore))
sleep(2)
@ -1096,7 +1096,7 @@ class AdvancedReOrgTests: ZcashTestCase {
// FIXME [#644]: Test works with lightwalletd v0.4.13 but is broken when using newer lightwalletd. More info is in #644.
func testReOrgRemovesIncomingTxForever() async throws {
await hookToReOrgNotification()
try coordinator.reset(saplingActivation: 663150, branchID: branchID, chainName: chainName)
try await coordinator.reset(saplingActivation: 663150, branchID: branchID, chainName: chainName)
try coordinator.resetBlocks(dataset: .predefined(dataset: .txReOrgRemovesInboundTxBefore))

View File

@ -30,7 +30,7 @@ class BalanceTests: ZcashTestCase {
walletBirthday: birthday,
network: network
)
try coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
try await coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
}
override func tearDown() async throws {
@ -672,7 +672,7 @@ class BalanceTests: ZcashTestCase {
return
}
guard let changeOutput = outputs.first(where: { $0.isChange }) else {
guard outputs.first(where: { $0.isChange }) != nil else {
XCTFail("Sent transaction has no change")
return
}

View File

@ -33,7 +33,7 @@ class DarksideSanityCheckTests: ZcashTestCase {
network: network
)
try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
try await coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
try self.coordinator.resetBlocks(dataset: .default)
}

View File

@ -34,7 +34,7 @@ final class InternalStateConsistencyTests: ZcashTestCase {
network: network
)
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
try await coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
}
override func tearDown() async throws {
@ -48,95 +48,95 @@ final class InternalStateConsistencyTests: ZcashTestCase {
try? FileManager.default.removeItem(at: coordinator.databases.dataDB)
}
func testInternalStateIsConsistentWhenMigrating() async throws {
sdkSynchronizerInternalSyncStatusHandler.subscribe(
to: coordinator.synchronizer.stateStream,
expectations: [.stopped: firstSyncExpectation]
)
let fullSyncLength = 10000
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
sleep(1)
// apply the height
try coordinator.applyStaged(blockheight: 664150)
sleep(1)
try await coordinator.sync(
completion: { _ in
XCTFail("shouldn't have completed")
},
error: handleError
)
let coordinator = self.coordinator!
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
Task(priority: .userInitiated) {
coordinator.synchronizer.stop()
}
}
await fulfillment(of: [firstSyncExpectation], timeout: 2)
let isSyncing = await coordinator.synchronizer.status.isSyncing
let status = await coordinator.synchronizer.status
XCTAssertFalse(isSyncing, "SDKSynchronizer shouldn't be syncing")
XCTAssertEqual(status, .stopped)
let internalSyncState = InternalSyncProgress(
alias: .default,
storage: UserDefaults.standard,
logger: logger
)
let latestDownloadHeight = await internalSyncState.latestDownloadedBlockHeight
let latestScanHeight = try await coordinator.synchronizer.initializer.transactionRepository.lastScannedHeight()
let dbHandle = TestDbHandle(originalDb: TestDbBuilder.prePopulatedDarksideCacheDb()!)
try dbHandle.setUp()
if latestDownloadHeight > latestScanHeight {
try await coordinator.synchronizer.blockProcessor.migrateCacheDb(dbHandle.readWriteDb)
let afterMigrationDownloadedHeight = await internalSyncState.latestDownloadedBlockHeight
XCTAssertNotEqual(latestDownloadHeight, afterMigrationDownloadedHeight)
XCTAssertEqual(latestScanHeight, afterMigrationDownloadedHeight)
} else {
try await coordinator.synchronizer.blockProcessor.migrateCacheDb(dbHandle.readWriteDb)
let afterMigrationDownloadedHeight = await internalSyncState.latestDownloadedBlockHeight
XCTAssertEqual(latestDownloadHeight, afterMigrationDownloadedHeight)
XCTAssertEqual(latestScanHeight, afterMigrationDownloadedHeight)
}
XCTAssertFalse(FileManager.default.isReadableFile(atPath: dbHandle.readWriteDb.path))
// clear to simulate a clean slate from the FsBlockDb
try await coordinator.synchronizer.blockProcessor.storage.clear()
// Now let's resume scanning and see how it goes.
let secondSyncAttemptExpectation = XCTestExpectation(description: "second sync attempt")
do {
try await coordinator.sync(
completion: { _ in
XCTAssertTrue(true)
secondSyncAttemptExpectation.fulfill()
},
error: { [weak self] error in
secondSyncAttemptExpectation.fulfill()
self?.handleError(error)
}
)
} catch {
handleError(error)
}
await fulfillment(of: [secondSyncAttemptExpectation], timeout: 10)
}
// func testInternalStateIsConsistentWhenMigrating() async throws {
// sdkSynchronizerInternalSyncStatusHandler.subscribe(
// to: coordinator.synchronizer.stateStream,
// expectations: [.stopped: firstSyncExpectation]
// )
//
// let fullSyncLength = 10000
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// sleep(1)
//
// // apply the height
// try coordinator.applyStaged(blockheight: 664150)
//
// sleep(1)
//
// try await coordinator.sync(
// completion: { _ in
// XCTFail("shouldn't have completed")
// },
// error: handleError
// )
//
// let coordinator = self.coordinator!
// DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
// Task(priority: .userInitiated) {
// coordinator.synchronizer.stop()
// }
// }
//
// await fulfillment(of: [firstSyncExpectation], timeout: 2)
//
// let isSyncing = await coordinator.synchronizer.status.isSyncing
// let status = await coordinator.synchronizer.status
// XCTAssertFalse(isSyncing, "SDKSynchronizer shouldn't be syncing")
// XCTAssertEqual(status, .stopped)
//
// let internalSyncState = InternalSyncProgress(
// alias: .default,
// storage: UserDefaults.standard,
// logger: logger
// )
//
// let latestDownloadHeight = await internalSyncState.latestDownloadedBlockHeight
// let latestScanHeight = try await coordinator.synchronizer.initializer.transactionRepository.lastScannedHeight()
// let dbHandle = TestDbHandle(originalDb: TestDbBuilder.prePopulatedDarksideCacheDb()!)
// try dbHandle.setUp()
//
// if latestDownloadHeight > latestScanHeight {
// try await coordinator.synchronizer.blockProcessor.migrateCacheDb(dbHandle.readWriteDb)
//
// let afterMigrationDownloadedHeight = await internalSyncState.latestDownloadedBlockHeight
//
// XCTAssertNotEqual(latestDownloadHeight, afterMigrationDownloadedHeight)
// XCTAssertEqual(latestScanHeight, afterMigrationDownloadedHeight)
// } else {
// try await coordinator.synchronizer.blockProcessor.migrateCacheDb(dbHandle.readWriteDb)
//
// let afterMigrationDownloadedHeight = await internalSyncState.latestDownloadedBlockHeight
//
// XCTAssertEqual(latestDownloadHeight, afterMigrationDownloadedHeight)
// XCTAssertEqual(latestScanHeight, afterMigrationDownloadedHeight)
// }
//
// XCTAssertFalse(FileManager.default.isReadableFile(atPath: dbHandle.readWriteDb.path))
//
// // clear to simulate a clean slate from the FsBlockDb
// try await coordinator.synchronizer.blockProcessor.storage.clear()
//
// // Now let's resume scanning and see how it goes.
// let secondSyncAttemptExpectation = XCTestExpectation(description: "second sync attempt")
//
// do {
// try await coordinator.sync(
// completion: { _ in
// XCTAssertTrue(true)
// secondSyncAttemptExpectation.fulfill()
// },
// error: { [weak self] error in
// secondSyncAttemptExpectation.fulfill()
// self?.handleError(error)
// }
// )
// } catch {
// handleError(error)
// }
//
// await fulfillment(of: [secondSyncAttemptExpectation], timeout: 10)
// }
func handleError(_ error: Error?) {
guard let testError = error else {

View File

@ -30,7 +30,7 @@ class PendingTransactionUpdatesTest: ZcashTestCase {
walletBirthday: birthday,
network: network
)
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
try await coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
}
override func tearDown() async throws {

View File

@ -50,7 +50,7 @@ class ReOrgTests: ZcashTestCase {
network: self.network
)
try self.coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
try await coordinator.reset(saplingActivation: self.birthday, branchID: self.branchID, chainName: self.chainName)
try self.coordinator.resetBlocks(dataset: .default)
@ -128,7 +128,7 @@ class ReOrgTests: ZcashTestCase {
targetHeight: BlockHeight
) async throws {
do {
try coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
try await coordinator.reset(saplingActivation: birthday, branchID: branchID, chainName: chainName)
try coordinator.resetBlocks(dataset: .predefined(dataset: .beforeReOrg))
try coordinator.applyStaged(blockheight: firstLatestHeight)
sleep(1)

View File

@ -35,7 +35,7 @@ class RewindRescanTests: ZcashTestCase {
walletBirthday: birthday,
network: network
)
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
try await coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
}
override func tearDown() async throws {

View File

@ -30,7 +30,7 @@ class ShieldFundsTests: ZcashTestCase {
walletBirthday: birthday,
network: network
)
try coordinator.reset(saplingActivation: birthday, branchID: self.branchID, chainName: self.chainName)
try await coordinator.reset(saplingActivation: birthday, branchID: self.branchID, chainName: self.chainName)
try coordinator.service.clearAddedUTXOs()
}

View File

@ -40,7 +40,7 @@ class SynchronizerDarksideTests: ZcashTestCase {
network: network
)
try self.coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
try await coordinator.reset(saplingActivation: 663150, branchID: "e9ff75a6", chainName: "main")
}
override func tearDown() async throws {
@ -195,7 +195,7 @@ class SynchronizerDarksideTests: ZcashTestCase {
syncSessionID: uuids[0],
shieldedBalance: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)),
internalSyncStatus: .syncing(0),
latestScannedHeight: 663150,
latestBlockHeight: 0,
latestScannedTime: 1576821833
@ -204,93 +204,7 @@ class SynchronizerDarksideTests: ZcashTestCase {
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: .zero,
internalSyncStatus: .syncing(BlockProgress(startHeight: 663150, targetHeight: 663189, progressHeight: 663189)),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: .zero,
internalSyncStatus: .enhancing(
EnhancementProgress(totalTransactions: 0, enhancedTransactions: 0, lastFoundTransaction: nil, range: 0...0, newlyMined: false)
),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: .zero,
internalSyncStatus: .enhancing(
EnhancementProgress(
totalTransactions: 2,
enhancedTransactions: 1,
lastFoundTransaction: ZcashTransaction.Overview(
accountId: 0,
blockTime: 1.0,
expiryHeight: 663206,
fee: Zatoshi(0),
id: 2,
index: 1,
hasChange: false,
memoCount: 1,
minedHeight: 663188,
raw: Data(),
rawID: Data(),
receivedNoteCount: 1,
sentNoteCount: 0,
value: Zatoshi(100000),
isExpiredUmined: false
),
range: 663150...663189,
newlyMined: true
)
),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: .zero,
internalSyncStatus: .enhancing(
EnhancementProgress(
totalTransactions: 2,
enhancedTransactions: 2,
lastFoundTransaction: ZcashTransaction.Overview(
accountId: 0,
blockTime: 1.0,
expiryHeight: 663192,
fee: Zatoshi(0),
id: 1,
index: 1,
hasChange: false,
memoCount: 1,
minedHeight: 663174,
raw: Data(),
rawID: Data(),
receivedNoteCount: 1,
sentNoteCount: 0,
value: Zatoshi(100000),
isExpiredUmined: false
),
range: 663150...663189,
newlyMined: true
)
),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: .zero,
internalSyncStatus: .fetching(0),
internalSyncStatus: .syncing(0.9),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
@ -359,7 +273,7 @@ class SynchronizerDarksideTests: ZcashTestCase {
syncSessionID: uuids[0],
shieldedBalance: .zero,
transparentBalance: .zero,
internalSyncStatus: .syncing(BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)),
internalSyncStatus: .syncing(0),
latestScannedHeight: 663150,
latestBlockHeight: 0,
latestScannedTime: 1576821833.0
@ -368,93 +282,7 @@ class SynchronizerDarksideTests: ZcashTestCase {
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: .zero,
internalSyncStatus: .syncing(BlockProgress(startHeight: 663150, targetHeight: 663189, progressHeight: 663189)),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .enhancing(
EnhancementProgress(totalTransactions: 0, enhancedTransactions: 0, lastFoundTransaction: nil, range: 0...0, newlyMined: false)
),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .enhancing(
EnhancementProgress(
totalTransactions: 2,
enhancedTransactions: 1,
lastFoundTransaction: ZcashTransaction.Overview(
accountId: 0,
blockTime: 1.0,
expiryHeight: 663206,
fee: nil,
id: 2,
index: 1,
hasChange: false,
memoCount: 1,
minedHeight: 663188,
raw: Data(),
rawID: Data(),
receivedNoteCount: 1,
sentNoteCount: 0,
value: Zatoshi(100000),
isExpiredUmined: false
),
range: 663150...663189,
newlyMined: true
)
),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .enhancing(
EnhancementProgress(
totalTransactions: 2,
enhancedTransactions: 2,
lastFoundTransaction: ZcashTransaction.Overview(
accountId: 0,
blockTime: 1.0,
expiryHeight: 663192,
fee: nil,
id: 1,
index: 1,
hasChange: false,
memoCount: 1,
minedHeight: 663174,
raw: Data(),
rawID: Data(),
receivedNoteCount: 1,
sentNoteCount: 0,
value: Zatoshi(100000),
isExpiredUmined: false
),
range: 663150...663189,
newlyMined: true
)
),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[0],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .fetching(0),
internalSyncStatus: .syncing(0.9),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1
@ -499,7 +327,7 @@ class SynchronizerDarksideTests: ZcashTestCase {
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .syncing(BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)),
internalSyncStatus: .syncing(0),
latestScannedHeight: 663189,
latestBlockHeight: 663189,
latestScannedTime: 1.0
@ -508,27 +336,7 @@ class SynchronizerDarksideTests: ZcashTestCase {
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .syncing(BlockProgress(startHeight: 663190, targetHeight: 663200, progressHeight: 663200)),
latestScannedHeight: 663200,
latestBlockHeight: 663200,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .enhancing(
EnhancementProgress(totalTransactions: 0, enhancedTransactions: 0, lastFoundTransaction: nil, range: 0...0, newlyMined: true)
),
latestScannedHeight: 663200,
latestBlockHeight: 663200,
latestScannedTime: 1
),
SynchronizerState(
syncSessionID: uuids[1],
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
internalSyncStatus: .fetching(0),
internalSyncStatus: .syncing(0.9),
latestScannedHeight: 663200,
latestBlockHeight: 663200,
latestScannedTime: 1

View File

@ -33,7 +33,7 @@ final class SynchronizerTests: ZcashTestCase {
walletBirthday: birthday + 50,
network: network
)
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
try await coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
switch event {
@ -66,189 +66,189 @@ final class SynchronizerTests: ZcashTestCase {
reorgExpectation.fulfill()
}
func testSynchronizerStops() async throws {
/*
1. create fake chain
*/
let fullSyncLength = 100_000
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
sleep(10)
let syncStoppedExpectation = XCTestExpectation(description: "SynchronizerStopped Expectation")
sdkSynchronizerInternalSyncStatusHandler.subscribe(
to: coordinator.synchronizer.stateStream,
expectations: [.stopped: syncStoppedExpectation]
)
/*
sync to latest height
*/
try await coordinator.sync(
completion: { _ in
XCTFail("Sync should have stopped")
},
error: self.handleError
)
try await Task.sleep(nanoseconds: 5_000_000_000)
self.coordinator.synchronizer.stop()
await fulfillment(of: [syncStoppedExpectation], timeout: 6)
let status = await coordinator.synchronizer.status
XCTAssertEqual(status, .stopped)
let state = await coordinator.synchronizer.blockProcessor.state
XCTAssertEqual(state, .stopped)
}
// func testSynchronizerStops() async throws {
// /*
// 1. create fake chain
// */
// let fullSyncLength = 100_000
//
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
//
// sleep(10)
//
// let syncStoppedExpectation = XCTestExpectation(description: "SynchronizerStopped Expectation")
// sdkSynchronizerInternalSyncStatusHandler.subscribe(
// to: coordinator.synchronizer.stateStream,
// expectations: [.stopped: syncStoppedExpectation]
// )
//
// /*
// sync to latest height
// */
// try await coordinator.sync(
// completion: { _ in
// XCTFail("Sync should have stopped")
// },
// error: self.handleError
// )
//
// try await Task.sleep(nanoseconds: 5_000_000_000)
// self.coordinator.synchronizer.stop()
//
// await fulfillment(of: [syncStoppedExpectation], timeout: 6)
//
// let status = await coordinator.synchronizer.status
// XCTAssertEqual(status, .stopped)
// let state = await coordinator.synchronizer.blockProcessor.state
// XCTAssertEqual(state, .stopped)
// }
// MARK: Wipe tests
func testWipeCalledWhichSyncDoesntRun() async throws {
/*
create fake chain
*/
let fullSyncLength = 1000
// func testWipeCalledWhichSyncDoesntRun() async throws {
// /*
// create fake chain
// */
// let fullSyncLength = 1000
//
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
//
// sleep(2)
//
// let syncFinished = XCTestExpectation(description: "SynchronizerSyncFinished Expectation")
//
// /*
// sync to latest height
// */
// try await coordinator.sync(
// completion: { _ in
// syncFinished.fulfill()
// },
// error: handleError
// )
//
// await fulfillment(of: [syncFinished], timeout: 3)
//
// let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
//
// /*
// Call wipe
// */
// coordinator.synchronizer.wipe()
// .sink(
// receiveCompletion: { completion in
// switch completion {
// case .finished:
// wipeFinished.fulfill()
//
// case .failure(let error):
// XCTFail("Wipe should finish successfully. \(error)")
// }
// },
// receiveValue: {
// XCTFail("No no value should be received from wipe.")
// }
// )
// .store(in: &cancellables)
//
// await fulfillment(of: [wipeFinished], timeout: 1)
//
// /*
// Check that wipe cleared everything that is expected
// */
// await checkThatWipeWorked()
// }
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
// func testWipeCalledWhileSyncRuns() async throws {
// /*
// 1. create fake chain
// */
// let fullSyncLength = 50_000
//
// try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
//
// try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
//
// sleep(5)
//
// /*
// Start sync
// */
// try await coordinator.sync(
// completion: { _ in
// XCTFail("Sync should have stopped")
// },
// error: self.handleError
// )
//
// try await Task.sleep(nanoseconds: 2_000_000_000)
//
// // Just to be sure that blockProcessor is still syncing and that this test does what it should.
// let blockProcessorState = await coordinator.synchronizer.blockProcessor.state
// XCTAssertEqual(blockProcessorState, .syncing)
//
// let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
// /*
// Call wipe
// */
// coordinator.synchronizer.wipe()
// .sink(
// receiveCompletion: { completion in
// switch completion {
// case .finished:
// wipeFinished.fulfill()
//
// case .failure(let error):
// XCTFail("Wipe should finish successfully. \(error)")
// }
// },
// receiveValue: {
// XCTFail("No no value should be received from wipe.")
// }
// )
// .store(in: &cancellables)
//
// await fulfillment(of: [wipeFinished], timeout: 6)
//
// /*
// Check that wipe cleared everything that is expected
// */
// await checkThatWipeWorked()
// }
try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
sleep(2)
let syncFinished = XCTestExpectation(description: "SynchronizerSyncFinished Expectation")
/*
sync to latest height
*/
try await coordinator.sync(
completion: { _ in
syncFinished.fulfill()
},
error: handleError
)
await fulfillment(of: [syncFinished], timeout: 3)
let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
/*
Call wipe
*/
coordinator.synchronizer.wipe()
.sink(
receiveCompletion: { completion in
switch completion {
case .finished:
wipeFinished.fulfill()
case .failure(let error):
XCTFail("Wipe should finish successfully. \(error)")
}
},
receiveValue: {
XCTFail("No no value should be received from wipe.")
}
)
.store(in: &cancellables)
await fulfillment(of: [wipeFinished], timeout: 1)
/*
Check that wipe cleared everything that is expected
*/
await checkThatWipeWorked()
}
func testWipeCalledWhileSyncRuns() async throws {
/*
1. create fake chain
*/
let fullSyncLength = 50_000
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service, branchID: branchID, chainName: chainName, length: fullSyncLength)
try coordinator.applyStaged(blockheight: birthday + fullSyncLength)
sleep(5)
/*
Start sync
*/
try await coordinator.sync(
completion: { _ in
XCTFail("Sync should have stopped")
},
error: self.handleError
)
try await Task.sleep(nanoseconds: 2_000_000_000)
// Just to be sure that blockProcessor is still syncing and that this test does what it should.
let blockProcessorState = await coordinator.synchronizer.blockProcessor.state
XCTAssertEqual(blockProcessorState, .syncing)
let wipeFinished = XCTestExpectation(description: "SynchronizerWipeFinished Expectation")
/*
Call wipe
*/
coordinator.synchronizer.wipe()
.sink(
receiveCompletion: { completion in
switch completion {
case .finished:
wipeFinished.fulfill()
case .failure(let error):
XCTFail("Wipe should finish successfully. \(error)")
}
},
receiveValue: {
XCTFail("No no value should be received from wipe.")
}
)
.store(in: &cancellables)
await fulfillment(of: [wipeFinished], timeout: 6)
/*
Check that wipe cleared everything that is expected
*/
await checkThatWipeWorked()
}
private func checkThatWipeWorked() async {
let storage = await self.coordinator.synchronizer.blockProcessor.storage as! FSCompactBlockRepository
let fm = FileManager.default
print(coordinator.synchronizer.initializer.dataDbURL.path)
XCTAssertFalse(fm.fileExists(atPath: coordinator.synchronizer.initializer.dataDbURL.path), "Data DB should be deleted.")
XCTAssertTrue(fm.fileExists(atPath: storage.blocksDirectory.path), "FS Cache directory should exist")
XCTAssertEqual(try fm.contentsOfDirectory(atPath: storage.blocksDirectory.path), [], "FS Cache directory should be empty")
let internalSyncProgress = InternalSyncProgress(
alias: .default,
storage: UserDefaults.standard,
logger: logger
)
let latestDownloadedBlockHeight = await internalSyncProgress.load(.latestDownloadedBlockHeight)
let latestEnhancedHeight = await internalSyncProgress.load(.latestEnhancedHeight)
let latestUTXOFetchedHeight = await internalSyncProgress.load(.latestUTXOFetchedHeight)
XCTAssertEqual(latestDownloadedBlockHeight, 0, "internalSyncProgress latestDownloadedBlockHeight should be 0")
XCTAssertEqual(latestEnhancedHeight, 0, "internalSyncProgress latestEnhancedHeight should be 0")
XCTAssertEqual(latestUTXOFetchedHeight, 0, "internalSyncProgress latestUTXOFetchedHeight should be 0")
let blockProcessorState = await coordinator.synchronizer.blockProcessor.state
XCTAssertEqual(blockProcessorState, .stopped, "CompactBlockProcessor state should be stopped")
let status = await coordinator.synchronizer.status
XCTAssertEqual(status, .unprepared, "SDKSynchronizer state should be unprepared")
}
// private func checkThatWipeWorked() async {
// let storage = await self.coordinator.synchronizer.blockProcessor.storage as! FSCompactBlockRepository
// let fm = FileManager.default
// print(coordinator.synchronizer.initializer.dataDbURL.path)
//
// XCTAssertFalse(fm.fileExists(atPath: coordinator.synchronizer.initializer.dataDbURL.path), "Data DB should be deleted.")
// XCTAssertTrue(fm.fileExists(atPath: storage.blocksDirectory.path), "FS Cache directory should exist")
// XCTAssertEqual(try fm.contentsOfDirectory(atPath: storage.blocksDirectory.path), [], "FS Cache directory should be empty")
//
// let internalSyncProgress = InternalSyncProgress(
// alias: .default,
// storage: UserDefaults.standard,
// logger: logger
// )
//
// let latestDownloadedBlockHeight = await internalSyncProgress.load(.latestDownloadedBlockHeight)
// let latestEnhancedHeight = await internalSyncProgress.load(.latestEnhancedHeight)
// let latestUTXOFetchedHeight = await internalSyncProgress.load(.latestUTXOFetchedHeight)
//
// XCTAssertEqual(latestDownloadedBlockHeight, 0, "internalSyncProgress latestDownloadedBlockHeight should be 0")
// XCTAssertEqual(latestEnhancedHeight, 0, "internalSyncProgress latestEnhancedHeight should be 0")
// XCTAssertEqual(latestUTXOFetchedHeight, 0, "internalSyncProgress latestUTXOFetchedHeight should be 0")
//
// let blockProcessorState = await coordinator.synchronizer.blockProcessor.state
// XCTAssertEqual(blockProcessorState, .stopped, "CompactBlockProcessor state should be stopped")
//
// let status = await coordinator.synchronizer.status
// XCTAssertEqual(status, .unprepared, "SDKSynchronizer state should be unprepared")
// }
func handleError(_ error: Error?) async {
_ = try? await coordinator.stop()

View File

@ -33,7 +33,7 @@ class Z2TReceiveTests: ZcashTestCase {
walletBirthday: birthday,
network: network
)
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
try await coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
}
override func tearDown() async throws {

View File

@ -212,7 +212,7 @@ final class ComputeSyncRangesActionTests: ZcashTestCase {
return ComputeSyncRangesAction(
container: mockContainer,
config: config
configProvider: CompactBlockProcessor.ConfigProvider(config: config)
)
}

View File

@ -178,7 +178,7 @@ final class DownloadActionTests: ZcashTestCase {
return DownloadAction(
container: mockContainer,
config: config
configProvider: CompactBlockProcessor.ConfigProvider(config: config)
)
}
}

View File

@ -245,6 +245,71 @@ final class EnhanceActionTests: ZcashTestCase {
XCTFail("testEnhanceAction_EnhancementOfBlocksCalled_minedTransaction is not expected to fail. \(error)")
}
}
func testEnhanceAction_EnhancementOfBlocksCalled_usingSmallRange_minedTransaction() async throws {
let blockEnhancerMock = BlockEnhancerMock()
let transactionRepositoryMock = TransactionRepositoryMock()
let internalSyncProgressStorageMock = InternalSyncProgressStorageMock()
transactionRepositoryMock.lastScannedHeightReturnValue = 200
internalSyncProgressStorageMock.integerForKeyReturnValue = 1
let transaction = ZcashTransaction.Overview(
accountId: 0,
blockTime: 1.0,
expiryHeight: 663206,
fee: Zatoshi(0),
id: 2,
index: 1,
hasChange: false,
memoCount: 1,
minedHeight: 663188,
raw: Data(),
rawID: Data(),
receivedNoteCount: 1,
sentNoteCount: 0,
value: Zatoshi(100000),
isExpiredUmined: false
)
blockEnhancerMock.enhanceAtDidEnhanceClosure = { _, didEnhance in
await didEnhance(
EnhancementProgress(
totalTransactions: 0,
enhancedTransactions: 0,
lastFoundTransaction: transaction,
range: 0...0,
newlyMined: true
)
)
return nil
}
let enhanceAction = setupAction(
blockEnhancerMock,
transactionRepositoryMock,
internalSyncProgressStorageMock
)
underlyingEnhanceRange = CompactBlockRange(uncheckedBounds: (100, 200))
let syncContext = await setupActionContext()
do {
_ = try await enhanceAction.run(with: syncContext) { event in
guard case .minedTransaction(let minedTransaction) = event else {
XCTFail("Event is expected to be .minedTransaction but received \(event)")
return
}
XCTAssertEqual(minedTransaction.expiryHeight, transaction.expiryHeight, "MinedTransaction differs from mocked one.")
}
XCTAssertTrue(transactionRepositoryMock.lastScannedHeightCalled, "transactionRepository.lastScannedHeight() is expected to be called.")
XCTAssertTrue(internalSyncProgressStorageMock.integerForKeyCalled, "internalSyncProgress.load() is expected to be called.")
XCTAssertTrue(blockEnhancerMock.enhanceAtDidEnhanceCalled, "blockEnhancer.enhance() is expected to be called.")
} catch {
XCTFail("testEnhanceAction_EnhancementOfBlocksCalled_minedTransaction is not expected to fail. \(error)")
}
}
private func setupActionContext() async -> ActionContext {
let syncContext: ActionContext = .init(state: .enhance)
@ -285,7 +350,7 @@ final class EnhanceActionTests: ZcashTestCase {
return EnhanceAction(
container: mockContainer,
config: config
configProvider: CompactBlockProcessor.ConfigProvider(config: config)
)
}
}

View File

@ -101,7 +101,7 @@ final class ScanActionTests: ZcashTestCase {
return ScanAction(
container: mockContainer,
config: config
configProvider: CompactBlockProcessor.ConfigProvider(config: config)
)
}

View File

@ -157,7 +157,7 @@ final class ValidateServerActionTests: ZcashTestCase {
return ValidateServerAction(
container: mockContainer,
config: config
configProvider: CompactBlockProcessor.ConfigProvider(config: config)
)
}
}

View File

@ -209,29 +209,26 @@ extension TestCoordinator {
try await service.latestBlockHeight()
}
func reset(saplingActivation: BlockHeight, branchID: String, chainName: String) throws {
Task {
await self.synchronizer.blockProcessor.stop()
// TODO: [#1102] review and potentially fix/remove commented code https://github.com/zcash/ZcashLightClientKit/issues/1102
// let config = await self.synchronizer.blockProcessor.config
//
// let newConfig = CompactBlockProcessor.Configuration(
// alias: config.alias,
// fsBlockCacheRoot: config.fsBlockCacheRoot,
// dataDb: config.dataDb,
// spendParamsURL: config.spendParamsURL,
// outputParamsURL: config.outputParamsURL,
// saplingParamsSourceURL: config.saplingParamsSourceURL,
// retries: config.retries,
// maxBackoffInterval: config.maxBackoffInterval,
// rewindDistance: config.rewindDistance,
// walletBirthdayProvider: config.walletBirthdayProvider,
// saplingActivation: saplingActivation,
// network: config.network
// )
func reset(saplingActivation: BlockHeight, branchID: String, chainName: String) async throws {
await self.synchronizer.blockProcessor.stop()
// await self.synchronizer.blockProcessor.update(config: newConfig)
}
let config = await self.synchronizer.blockProcessor.config
let newConfig = CompactBlockProcessor.Configuration(
alias: config.alias,
fsBlockCacheRoot: config.fsBlockCacheRoot,
dataDb: config.dataDb,
spendParamsURL: config.spendParamsURL,
outputParamsURL: config.outputParamsURL,
saplingParamsSourceURL: config.saplingParamsSourceURL,
retries: config.retries,
maxBackoffInterval: config.maxBackoffInterval,
rewindDistance: config.rewindDistance,
walletBirthdayProvider: config.walletBirthdayProvider,
saplingActivation: saplingActivation,
network: config.network
)
await self.synchronizer.blockProcessor.update(config: newConfig)
try service.reset(saplingActivation: saplingActivation, branchID: branchID, chainName: chainName)
}