2020-04-23 10:11:03 -07:00
|
|
|
//
|
|
|
|
// TransactionEnhancementTests.swift
|
|
|
|
// ZcashLightClientKit-Unit-Tests
|
|
|
|
//
|
|
|
|
// Created by Francisco Gindre on 4/15/20.
|
|
|
|
//
|
|
|
|
|
2023-02-07 05:22:28 -08:00
|
|
|
import Combine
|
2020-04-23 10:11:03 -07:00
|
|
|
import XCTest
|
2022-02-28 09:03:20 -08:00
|
|
|
@testable import TestUtils
|
2020-04-23 10:11:03 -07:00
|
|
|
@testable import ZcashLightClientKit
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2020-04-23 10:11:03 -07:00
|
|
|
class TransactionEnhancementTests: XCTestCase {
|
2023-02-07 05:22:28 -08:00
|
|
|
var cancellables: [AnyCancellable] = []
|
2023-02-16 08:14:31 -08:00
|
|
|
var processorEventHandler: CompactBlockProcessorEventHandler! = CompactBlockProcessorEventHandler()
|
2021-09-23 06:26:41 -07:00
|
|
|
let mockLatestHeight = BlockHeight(663250)
|
|
|
|
let targetLatestHeight = BlockHeight(663251)
|
|
|
|
let walletBirthday = BlockHeight(663150)
|
|
|
|
let network = DarksideWalletDNetwork()
|
|
|
|
let branchID = "2bb40e60"
|
|
|
|
let chainName = "main"
|
2023-02-02 08:58:12 -08:00
|
|
|
let testTempDirectory = URL(fileURLWithPath: NSString(
|
|
|
|
string: NSTemporaryDirectory()
|
|
|
|
)
|
|
|
|
.appendingPathComponent("tmp-\(Int.random(in: 0 ... .max))"))
|
|
|
|
|
|
|
|
let testFileManager = FileManager()
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2020-04-23 10:11:03 -07:00
|
|
|
var initializer: Initializer!
|
|
|
|
var processorConfig: CompactBlockProcessor.Configuration!
|
|
|
|
var processor: CompactBlockProcessor!
|
|
|
|
var darksideWalletService: DarksideWalletService!
|
2023-01-31 02:11:00 -08:00
|
|
|
var downloader: BlockDownloaderServiceImpl!
|
2022-12-01 08:57:13 -08:00
|
|
|
var syncStartedExpect: XCTestExpectation!
|
2020-04-23 10:11:03 -07:00
|
|
|
var updatedNotificationExpectation: XCTestExpectation!
|
|
|
|
var stopNotificationExpectation: XCTestExpectation!
|
2023-02-07 05:22:28 -08:00
|
|
|
var finishedNotificationExpectation: XCTestExpectation!
|
2020-04-23 10:11:03 -07:00
|
|
|
var reorgNotificationExpectation: XCTestExpectation!
|
|
|
|
var afterReorgIdleNotification: XCTestExpectation!
|
|
|
|
var txFoundNotificationExpectation: XCTestExpectation!
|
|
|
|
var waitExpectation: XCTestExpectation!
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2020-04-23 10:11:03 -07:00
|
|
|
override func setUpWithError() throws {
|
2021-09-23 06:26:41 -07:00
|
|
|
try super.setUpWithError()
|
2023-02-02 08:58:12 -08:00
|
|
|
try self.testFileManager.createDirectory(at: self.testTempDirectory, withIntermediateDirectories: false)
|
2022-11-23 10:05:49 -08:00
|
|
|
XCTestCase.wait { await InternalSyncProgress(storage: UserDefaults.standard).rewind(to: 0) }
|
|
|
|
|
2023-01-26 09:14:07 -08:00
|
|
|
logger = OSLogger(logLevel: .debug)
|
2020-04-23 10:11:03 -07:00
|
|
|
|
2022-12-01 08:57:13 -08:00
|
|
|
syncStartedExpect = XCTestExpectation(description: "\(self.description) syncStartedExpect")
|
2021-09-23 06:26:41 -07:00
|
|
|
stopNotificationExpectation = XCTestExpectation(description: "\(self.description) stopNotificationExpectation")
|
|
|
|
updatedNotificationExpectation = XCTestExpectation(description: "\(self.description) updatedNotificationExpectation")
|
2023-02-07 05:22:28 -08:00
|
|
|
finishedNotificationExpectation = XCTestExpectation(description: "\(self.description) finishedNotificationExpectation")
|
2021-09-23 06:26:41 -07:00
|
|
|
afterReorgIdleNotification = XCTestExpectation(description: "\(self.description) afterReorgIdleNotification")
|
|
|
|
reorgNotificationExpectation = XCTestExpectation(description: "\(self.description) reorgNotificationExpectation")
|
|
|
|
txFoundNotificationExpectation = XCTestExpectation(description: "\(self.description) txFoundNotificationExpectation")
|
|
|
|
|
|
|
|
waitExpectation = XCTestExpectation(description: "\(self.description) waitExpectation")
|
2023-02-07 05:22:28 -08:00
|
|
|
|
2021-07-28 09:59:10 -07:00
|
|
|
let rustBackend = ZcashRustBackend.self
|
2023-02-07 05:22:28 -08:00
|
|
|
let birthday = Checkpoint.birthday(with: walletBirthday, network: network)
|
|
|
|
|
|
|
|
let pathProvider = DefaultResourceProvider(network: network)
|
|
|
|
processorConfig = CompactBlockProcessor.Configuration(
|
|
|
|
fsBlockCacheRoot: testTempDirectory,
|
|
|
|
dataDb: pathProvider.dataDbURL,
|
|
|
|
spendParamsURL: pathProvider.spendParamsURL,
|
|
|
|
outputParamsURL: pathProvider.outputParamsURL,
|
2023-02-16 08:27:49 -08:00
|
|
|
saplingParamsSourceURL: SaplingParamsSourceURL.tests,
|
2023-03-10 03:58:28 -08:00
|
|
|
walletBirthdayProvider: { birthday.height },
|
2023-02-07 05:22:28 -08:00
|
|
|
network: network
|
|
|
|
)
|
|
|
|
|
2023-02-02 08:58:12 -08:00
|
|
|
try? FileManager.default.removeItem(at: processorConfig.fsBlockCacheRoot)
|
2020-04-23 10:11:03 -07:00
|
|
|
try? FileManager.default.removeItem(at: processorConfig.dataDb)
|
2022-10-02 19:11:17 -07:00
|
|
|
|
2022-10-27 16:09:08 -07:00
|
|
|
let dbInit = try rustBackend.initDataDb(dbData: processorConfig.dataDb, seed: nil, networkType: network.networkType)
|
|
|
|
|
2022-10-02 19:11:17 -07:00
|
|
|
let ufvks = [
|
|
|
|
try DerivationTool(networkType: network.networkType)
|
2023-03-10 03:58:28 -08:00
|
|
|
.deriveUnifiedSpendingKey(seed: Environment.seedBytes, accountIndex: 0)
|
2023-01-18 08:09:04 -08:00
|
|
|
.map {
|
2022-10-02 19:11:17 -07:00
|
|
|
try DerivationTool(networkType: network.networkType)
|
|
|
|
.deriveUnifiedFullViewingKey(from: $0)
|
|
|
|
}
|
|
|
|
]
|
2022-11-01 09:57:42 -07:00
|
|
|
do {
|
|
|
|
try rustBackend.initAccountsTable(
|
|
|
|
dbData: processorConfig.dataDb,
|
|
|
|
ufvks: ufvks,
|
|
|
|
networkType: network.networkType
|
|
|
|
)
|
|
|
|
} catch {
|
2023-01-18 08:09:04 -08:00
|
|
|
XCTFail("Failed to init accounts table error: \(String(describing: rustBackend.getLastError()))")
|
2022-10-02 19:11:17 -07:00
|
|
|
return
|
|
|
|
}
|
2022-08-24 08:38:42 -07:00
|
|
|
|
|
|
|
guard case .success = dbInit else {
|
|
|
|
XCTFail("Failed to initDataDb. Expected `.success` got: \(String(describing: dbInit))")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-09-23 06:26:41 -07:00
|
|
|
_ = try rustBackend.initBlocksTable(
|
|
|
|
dbData: processorConfig.dataDb,
|
|
|
|
height: Int32(birthday.height),
|
|
|
|
hash: birthday.hash,
|
|
|
|
time: birthday.time,
|
2022-06-28 12:17:10 -07:00
|
|
|
saplingTree: birthday.saplingTree,
|
2021-09-23 06:26:41 -07:00
|
|
|
networkType: network.networkType
|
|
|
|
)
|
2021-07-28 09:59:10 -07:00
|
|
|
|
2020-04-23 10:11:03 -07:00
|
|
|
let service = DarksideWalletService()
|
|
|
|
darksideWalletService = service
|
2023-02-02 08:58:12 -08:00
|
|
|
|
|
|
|
let storage = FSCompactBlockRepository(
|
2023-02-09 04:58:49 -08:00
|
|
|
fsBlockDbRoot: testTempDirectory,
|
2023-02-02 08:58:12 -08:00
|
|
|
metadataStore: FSMetadataStore.live(
|
|
|
|
fsBlockDbRoot: testTempDirectory,
|
|
|
|
rustBackend: rustBackend
|
|
|
|
),
|
|
|
|
blockDescriptor: .live,
|
|
|
|
contentProvider: DirectoryListingProviders.defaultSorted
|
|
|
|
)
|
|
|
|
try! storage.create()
|
2020-04-23 10:11:03 -07:00
|
|
|
|
2023-01-31 02:11:00 -08:00
|
|
|
downloader = BlockDownloaderServiceImpl(service: service, storage: storage)
|
2021-09-23 06:26:41 -07:00
|
|
|
processor = CompactBlockProcessor(
|
|
|
|
service: service,
|
|
|
|
storage: storage,
|
|
|
|
backend: rustBackend,
|
|
|
|
config: processorConfig
|
|
|
|
)
|
2023-02-07 05:22:28 -08:00
|
|
|
|
|
|
|
var stream: AnyPublisher<CompactBlockProcessor.Event, Never>!
|
|
|
|
XCTestCase.wait { await stream = self.processor.eventStream }
|
|
|
|
stream
|
|
|
|
.sink { [weak self] event in
|
|
|
|
switch event {
|
|
|
|
case .failed: self?.processorFailed(event: event)
|
|
|
|
default: break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.store(in: &cancellables)
|
2020-04-23 10:11:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
override func tearDownWithError() throws {
|
2021-09-23 06:26:41 -07:00
|
|
|
try super.tearDownWithError()
|
2023-02-16 08:14:31 -08:00
|
|
|
XCTestCase.wait { await self.processor.stop() }
|
2023-02-02 08:58:12 -08:00
|
|
|
try? FileManager.default.removeItem(at: processorConfig.fsBlockCacheRoot)
|
2020-04-23 10:11:03 -07:00
|
|
|
try? FileManager.default.removeItem(at: processorConfig.dataDb)
|
|
|
|
NotificationCenter.default.removeObserver(self)
|
2023-02-16 08:14:31 -08:00
|
|
|
processorEventHandler = nil
|
|
|
|
initializer = nil
|
|
|
|
processorConfig = nil
|
|
|
|
processor = nil
|
|
|
|
darksideWalletService = nil
|
|
|
|
downloader = nil
|
2020-04-23 10:11:03 -07:00
|
|
|
}
|
|
|
|
|
2022-10-27 03:51:38 -07:00
|
|
|
private func startProcessing() async throws {
|
2020-04-23 10:11:03 -07:00
|
|
|
XCTAssertNotNil(processor)
|
|
|
|
|
2023-02-07 05:22:28 -08:00
|
|
|
let expectations: [CompactBlockProcessorEventHandler.EventIdentifier: XCTestExpectation] = [
|
|
|
|
.startedSyncing: syncStartedExpect,
|
|
|
|
.stopped: stopNotificationExpectation,
|
|
|
|
.progressUpdated: updatedNotificationExpectation,
|
|
|
|
.foundTransactions: txFoundNotificationExpectation,
|
|
|
|
.finished: finishedNotificationExpectation
|
|
|
|
]
|
|
|
|
processorEventHandler.subscribe(to: await processor.eventStream, expectations: expectations)
|
|
|
|
|
2022-10-31 05:57:10 -07:00
|
|
|
await processor.start()
|
2020-04-23 10:11:03 -07:00
|
|
|
}
|
|
|
|
|
2022-10-31 16:17:05 -07:00
|
|
|
func testBasicEnhancement() async throws {
|
2022-10-27 16:09:08 -07:00
|
|
|
let targetLatestHeight = BlockHeight(663200)
|
2020-04-23 10:11:03 -07:00
|
|
|
|
|
|
|
do {
|
2022-10-27 16:09:08 -07:00
|
|
|
try FakeChainBuilder.buildChain(darksideWallet: darksideWalletService, branchID: branchID, chainName: chainName)
|
|
|
|
|
|
|
|
try darksideWalletService.applyStaged(nextLatestHeight: targetLatestHeight)
|
2021-09-23 06:26:41 -07:00
|
|
|
} catch {
|
2020-04-23 10:11:03 -07:00
|
|
|
XCTFail("Error: \(error)")
|
|
|
|
return
|
|
|
|
}
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-07-28 09:59:10 -07:00
|
|
|
sleep(3)
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2020-04-23 10:11:03 -07:00
|
|
|
/**
|
2021-09-23 06:26:41 -07:00
|
|
|
connect to dLWD
|
|
|
|
request latest height -> receive firstLatestHeight
|
|
|
|
*/
|
2021-07-28 15:25:47 -07:00
|
|
|
do {
|
2021-09-23 06:26:41 -07:00
|
|
|
dump("first latest height: \(try darksideWalletService.latestBlockHeight())")
|
2021-07-28 15:25:47 -07:00
|
|
|
} catch {
|
|
|
|
XCTFail("Error: \(error)")
|
|
|
|
return
|
|
|
|
}
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2020-04-23 10:11:03 -07:00
|
|
|
/**
|
2021-09-23 06:26:41 -07:00
|
|
|
download and sync blocks from walletBirthday to firstLatestHeight
|
|
|
|
*/
|
2020-04-23 10:11:03 -07:00
|
|
|
do {
|
2022-10-27 03:51:38 -07:00
|
|
|
try await startProcessing()
|
2020-04-23 10:11:03 -07:00
|
|
|
} catch {
|
|
|
|
XCTFail("Error: \(error)")
|
|
|
|
}
|
|
|
|
|
2021-09-23 06:26:41 -07:00
|
|
|
wait(
|
|
|
|
for: [
|
2022-12-01 08:57:13 -08:00
|
|
|
syncStartedExpect,
|
2021-09-23 06:26:41 -07:00
|
|
|
txFoundNotificationExpectation,
|
2023-02-07 05:22:28 -08:00
|
|
|
finishedNotificationExpectation
|
2021-09-23 06:26:41 -07:00
|
|
|
],
|
|
|
|
timeout: 30
|
|
|
|
)
|
2020-04-23 10:11:03 -07:00
|
|
|
}
|
|
|
|
|
2023-02-07 05:22:28 -08:00
|
|
|
func processorFailed(event: CompactBlockProcessor.Event) {
|
|
|
|
if case let .failed(error) = event {
|
2020-04-23 10:11:03 -07:00
|
|
|
XCTFail("CompactBlockProcessor failed with Error: \(error)")
|
|
|
|
} else {
|
|
|
|
XCTFail("CompactBlockProcessor failed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|