2022-09-16 12:59:31 -07:00
|
|
|
//
|
|
|
|
// SynchronizerTests.swift
|
|
|
|
// DarksideTests
|
|
|
|
//
|
|
|
|
// Created by Francisco Gindre on 9/16/22.
|
|
|
|
//
|
|
|
|
|
2023-02-07 05:22:28 -08:00
|
|
|
import Combine
|
2022-09-16 12:59:31 -07:00
|
|
|
import XCTest
|
|
|
|
@testable import TestUtils
|
|
|
|
@testable import ZcashLightClientKit
|
|
|
|
|
2023-01-18 08:09:04 -08:00
|
|
|
// swiftlint:disable implicitly_unwrapped_optional force_unwrapping
|
2022-09-16 12:59:31 -07:00
|
|
|
final class SynchronizerTests: XCTestCase {
|
2023-01-18 08:09:04 -08:00
|
|
|
// TODO: [#715] Parameterize this from environment, https://github.com/zcash/ZcashLightClientKit/issues/715?
|
2022-09-16 12:59:31 -07:00
|
|
|
// swiftlint:disable:next line_length
|
|
|
|
var seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
|
|
|
|
2023-01-18 08:09:04 -08:00
|
|
|
// TODO: [#715] Parameterize this from environment, https://github.com/zcash/ZcashLightClientKit/issues/715
|
2022-09-16 12:59:31 -07:00
|
|
|
let testRecipientAddress = "zs17mg40levjezevuhdp5pqrd52zere7r7vrjgdwn5sj4xsqtm20euwahv9anxmwr3y3kmwuz8k55a"
|
|
|
|
|
|
|
|
let sendAmount = Zatoshi(1000)
|
|
|
|
var birthday: BlockHeight = 663150
|
|
|
|
let defaultLatestHeight: BlockHeight = 663175
|
|
|
|
var coordinator: TestCoordinator!
|
|
|
|
var syncedExpectation = XCTestExpectation(description: "synced")
|
|
|
|
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
|
|
|
var expectedReorgHeight: BlockHeight = 665188
|
|
|
|
var expectedRewindHeight: BlockHeight = 665188
|
|
|
|
var reorgExpectation = XCTestExpectation(description: "reorg")
|
|
|
|
let branchID = "2bb40e60"
|
|
|
|
let chainName = "main"
|
|
|
|
let network = DarksideWalletDNetwork()
|
2023-02-07 05:22:28 -08:00
|
|
|
var cancellables: [AnyCancellable] = []
|
|
|
|
let processorEventHandler = CompactBlockProcessorEventHandler()
|
2022-09-16 12:59:31 -07:00
|
|
|
|
|
|
|
override func setUpWithError() throws {
|
|
|
|
try super.setUpWithError()
|
2022-11-28 22:40:45 -08:00
|
|
|
self.coordinator = try TestCoordinator(
|
|
|
|
seed: self.seedPhrase,
|
2023-01-18 08:09:04 -08:00
|
|
|
walletBirthday: self.birthday + 50, // don't use an exact birthday, users never do.
|
2022-11-28 22:40:45 -08:00
|
|
|
network: self.network
|
|
|
|
)
|
|
|
|
|
|
|
|
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
2023-02-07 05:22:28 -08:00
|
|
|
|
|
|
|
var stream: AnyPublisher<CompactBlockProcessor.Event, Never>!
|
|
|
|
XCTestCase.wait { await stream = self.coordinator.synchronizer.blockProcessor.eventStream }
|
|
|
|
stream
|
|
|
|
.sink { [weak self] event in
|
|
|
|
switch event {
|
|
|
|
case .handledReorg: self?.handleReorg(event: event)
|
|
|
|
default: break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.store(in: &cancellables)
|
2022-09-16 12:59:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
override func tearDownWithError() throws {
|
|
|
|
try super.tearDownWithError()
|
|
|
|
NotificationCenter.default.removeObserver(self)
|
|
|
|
try coordinator.stop()
|
2023-02-02 08:58:12 -08:00
|
|
|
try? FileManager.default.removeItem(at: coordinator.databases.fsCacheDbRoot)
|
2022-09-16 12:59:31 -07:00
|
|
|
try? FileManager.default.removeItem(at: coordinator.databases.dataDB)
|
|
|
|
try? FileManager.default.removeItem(at: coordinator.databases.pendingDB)
|
|
|
|
}
|
|
|
|
|
2023-02-07 05:22:28 -08:00
|
|
|
func handleReorg(event: CompactBlockProcessor.Event) {
|
|
|
|
guard case let .handledReorg(reorgHeight, rewindHeight) = event else { return XCTFail("empty reorg notification") }
|
2022-09-16 12:59:31 -07:00
|
|
|
|
|
|
|
logger!.debug("--- REORG DETECTED \(reorgHeight)--- RewindHeight: \(rewindHeight)", file: #file, function: #function, line: #line)
|
|
|
|
|
|
|
|
XCTAssertEqual(reorgHeight, expectedReorgHeight)
|
|
|
|
reorgExpectation.fulfill()
|
|
|
|
}
|
|
|
|
|
2022-10-27 03:51:38 -07:00
|
|
|
func testSynchronizerStops() async throws {
|
2022-09-16 12:59:31 -07:00
|
|
|
/*
|
|
|
|
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")
|
|
|
|
syncStoppedExpectation.subscribe(to: .synchronizerStopped, object: nil)
|
|
|
|
|
|
|
|
let processorStoppedExpectation = XCTestExpectation(description: "ProcessorStopped Expectation")
|
2023-02-07 05:22:28 -08:00
|
|
|
processorEventHandler.subscribe(
|
|
|
|
to: await coordinator.synchronizer.blockProcessor.eventStream,
|
|
|
|
expectations: [.stopped: processorStoppedExpectation]
|
|
|
|
)
|
2022-09-16 12:59:31 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
sync to latest height
|
|
|
|
*/
|
|
|
|
try coordinator.sync(completion: { _ in
|
|
|
|
XCTFail("Sync should have stopped")
|
|
|
|
}, error: { error in
|
|
|
|
_ = try? self.coordinator.stop()
|
|
|
|
|
|
|
|
guard let testError = error else {
|
|
|
|
XCTFail("failed with nil error")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
XCTFail("Failed with error: \(testError)")
|
|
|
|
})
|
|
|
|
|
2022-10-27 03:51:38 -07:00
|
|
|
try await Task.sleep(nanoseconds: 5_000_000_000)
|
|
|
|
self.coordinator.synchronizer.stop()
|
2022-09-16 12:59:31 -07:00
|
|
|
|
2022-10-27 03:51:38 -07:00
|
|
|
wait(for: [syncStoppedExpectation, processorStoppedExpectation], timeout: 6, enforceOrder: true)
|
2022-09-16 12:59:31 -07:00
|
|
|
|
|
|
|
XCTAssertEqual(coordinator.synchronizer.status, .stopped)
|
2022-10-27 03:51:38 -07:00
|
|
|
let state = await coordinator.synchronizer.blockProcessor.state
|
|
|
|
XCTAssertEqual(state, .stopped)
|
2022-09-16 12:59:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func handleError(_ error: Error?) {
|
|
|
|
_ = try? coordinator.stop()
|
|
|
|
guard let testError = error else {
|
|
|
|
XCTFail("failed with nil error")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
XCTFail("Failed with error: \(testError)")
|
|
|
|
}
|
|
|
|
}
|