2021-08-04 10:14:15 -07:00
|
|
|
//
|
|
|
|
// Z2TReceiveTests.swift
|
|
|
|
// ZcashLightClientKit-Unit-Tests
|
|
|
|
//
|
|
|
|
// Created by Francisco Gindre on 8/4/21.
|
|
|
|
//
|
|
|
|
|
|
|
|
import XCTest
|
2022-02-28 09:03:20 -08:00
|
|
|
@testable import TestUtils
|
2021-08-04 10:14:15 -07:00
|
|
|
@testable import ZcashLightClientKit
|
|
|
|
|
2023-01-18 08:09:04 -08:00
|
|
|
// swiftlint:disable force_unwrapping implicitly_unwrapped_optional force_try
|
2021-09-23 06:26:41 -07:00
|
|
|
class Z2TReceiveTests: XCTestCase {
|
2023-01-18 08:09:04 -08:00
|
|
|
// TODO: [#715] Parameterize this from environment, https://github.com/zcash/ZcashLightClientKit/issues/715?
|
2021-09-23 06:26:41 -07:00
|
|
|
// swiftlint:disable:next line_length
|
2023-01-18 08:09:04 -08:00
|
|
|
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"
|
2021-08-04 10:14:15 -07:00
|
|
|
|
2023-01-18 08:09:04 -08:00
|
|
|
// TODO: [#715] Parameterize this from environment, https://github.com/zcash/ZcashLightClientKit/issues/715
|
|
|
|
let testRecipientAddress = "t1dRJRY7GmyeykJnMH38mdQoaZtFhn1QmGz"
|
2021-08-04 10:14:15 -07:00
|
|
|
|
|
|
|
let sendAmount: Int64 = 1000
|
|
|
|
var birthday: BlockHeight = 663150
|
|
|
|
let defaultLatestHeight: BlockHeight = 663175
|
|
|
|
var coordinator: TestCoordinator!
|
|
|
|
var syncedExpectation = XCTestExpectation(description: "synced")
|
|
|
|
var sentTransactionExpectation = XCTestExpectation(description: "sent")
|
|
|
|
var foundTransactionsExpectation = XCTestExpectation(description: "found transactions")
|
|
|
|
let branchID = "2bb40e60"
|
|
|
|
let chainName = "main"
|
|
|
|
|
|
|
|
let network = DarksideWalletDNetwork()
|
|
|
|
|
|
|
|
override func setUpWithError() throws {
|
2021-09-23 06:26:41 -07:00
|
|
|
try super.setUpWithError()
|
2022-11-28 22:40:45 -08:00
|
|
|
self.coordinator = try TestCoordinator(
|
|
|
|
seed: self.seedPhrase,
|
|
|
|
walletBirthday: self.birthday,
|
|
|
|
channelProvider: ChannelProvider(),
|
|
|
|
network: self.network
|
|
|
|
)
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2022-11-28 22:40:45 -08:00
|
|
|
try coordinator.reset(saplingActivation: 663150, branchID: self.branchID, chainName: self.chainName)
|
2021-08-04 10:14:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
override func tearDownWithError() throws {
|
2021-09-23 06:26:41 -07:00
|
|
|
try super.tearDownWithError()
|
2021-08-04 10:14:15 -07:00
|
|
|
NotificationCenter.default.removeObserver(self)
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
try coordinator.stop()
|
|
|
|
try? FileManager.default.removeItem(at: coordinator.databases.cacheDB)
|
|
|
|
try? FileManager.default.removeItem(at: coordinator.databases.dataDB)
|
|
|
|
try? FileManager.default.removeItem(at: coordinator.databases.pendingDB)
|
|
|
|
}
|
|
|
|
|
|
|
|
func subscribeToFoundTransactions() {
|
2021-09-23 06:26:41 -07:00
|
|
|
NotificationCenter.default.addObserver(
|
|
|
|
self,
|
|
|
|
selector: #selector(foundTransactions(_:)),
|
|
|
|
name: .synchronizerFoundTransactions,
|
|
|
|
object: nil
|
|
|
|
)
|
2021-08-04 10:14:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@objc func foundTransactions(_ notification: Notification) {
|
2021-09-23 06:26:41 -07:00
|
|
|
guard notification.userInfo?[SDKSynchronizer.NotificationKeys.foundTransactions] != nil else {
|
2021-08-04 10:14:15 -07:00
|
|
|
XCTFail("found transactions notification is empty")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
self.foundTransactionsExpectation.fulfill()
|
|
|
|
}
|
|
|
|
|
2022-10-27 16:09:08 -07:00
|
|
|
func testSendingZ2TWithMemoFails() async throws {
|
2021-08-04 10:14:15 -07:00
|
|
|
subscribeToFoundTransactions()
|
|
|
|
try FakeChainBuilder.buildChain(darksideWallet: self.coordinator.service, branchID: branchID, chainName: chainName)
|
|
|
|
let receivedTxHeight: BlockHeight = 663188
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
/*
|
2021-09-23 06:26:41 -07:00
|
|
|
2. applyStaged(received_Tx_height)
|
|
|
|
*/
|
2021-08-04 10:14:15 -07:00
|
|
|
try coordinator.applyStaged(blockheight: receivedTxHeight)
|
|
|
|
|
|
|
|
sleep(2)
|
|
|
|
let preTxExpectation = XCTestExpectation(description: "pre receive")
|
|
|
|
|
|
|
|
/*
|
2021-09-23 06:26:41 -07:00
|
|
|
3. sync up to received_Tx_height
|
|
|
|
*/
|
2022-09-13 03:19:56 -07:00
|
|
|
try await withCheckedThrowingContinuation { continuation in
|
|
|
|
do {
|
2023-01-18 08:09:04 -08:00
|
|
|
try coordinator.sync(completion: { _ in
|
2022-09-13 03:19:56 -07:00
|
|
|
preTxExpectation.fulfill()
|
|
|
|
continuation.resume()
|
|
|
|
}, error: self.handleError)
|
|
|
|
} catch {
|
|
|
|
continuation.resume(throwing: error)
|
|
|
|
}
|
|
|
|
}
|
2021-08-04 10:14:15 -07:00
|
|
|
wait(for: [preTxExpectation, foundTransactionsExpectation], timeout: 5)
|
|
|
|
|
2022-10-27 16:09:08 -07:00
|
|
|
let sendExpectation = XCTestExpectation(description: "sendToAddress")
|
|
|
|
let sendAmount = Zatoshi(10000)
|
|
|
|
/*
|
|
|
|
4. create transaction
|
|
|
|
*/
|
|
|
|
do {
|
2023-01-18 08:09:04 -08:00
|
|
|
_ = try await coordinator.synchronizer.sendToAddress(
|
2022-10-27 16:09:08 -07:00
|
|
|
spendingKey: coordinator.spendingKeys!.first!,
|
|
|
|
zatoshi: sendAmount,
|
|
|
|
toAddress: try! Recipient(testRecipientAddress, network: self.network.networkType),
|
|
|
|
memo: try Memo(string: "test transaction")
|
|
|
|
)
|
|
|
|
|
|
|
|
XCTFail("Should have thrown error")
|
|
|
|
} catch {
|
|
|
|
sendExpectation.fulfill()
|
|
|
|
if case let SynchronizerError.generalError(message) = error {
|
|
|
|
XCTAssertEqual(message, "Memos can't be sent to transparent addresses.")
|
|
|
|
} else {
|
2023-01-18 08:09:04 -08:00
|
|
|
// swiftlint:disable:next line_length
|
2022-10-27 16:09:08 -07:00
|
|
|
XCTFail("expected SynchronizerError.genericError(\"Memos can't be sent to transparent addresses.\") but received \(error.localizedDescription)")
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testFoundTransactions() async throws {
|
|
|
|
subscribeToFoundTransactions()
|
|
|
|
try FakeChainBuilder.buildChain(darksideWallet: self.coordinator.service, branchID: branchID, chainName: chainName)
|
|
|
|
let receivedTxHeight: BlockHeight = 663188
|
|
|
|
|
|
|
|
/*
|
|
|
|
2. applyStaged(received_Tx_height)
|
|
|
|
*/
|
|
|
|
try coordinator.applyStaged(blockheight: receivedTxHeight)
|
|
|
|
|
|
|
|
sleep(2)
|
|
|
|
let preTxExpectation = XCTestExpectation(description: "pre receive")
|
|
|
|
|
|
|
|
/*
|
|
|
|
3. sync up to received_Tx_height
|
|
|
|
*/
|
|
|
|
try await withCheckedThrowingContinuation { continuation in
|
|
|
|
do {
|
2023-01-18 08:09:04 -08:00
|
|
|
try coordinator.sync(completion: { _ in
|
2022-10-27 16:09:08 -07:00
|
|
|
preTxExpectation.fulfill()
|
|
|
|
continuation.resume()
|
|
|
|
}, error: self.handleError)
|
|
|
|
} catch {
|
|
|
|
continuation.resume(throwing: error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wait(for: [preTxExpectation, foundTransactionsExpectation], timeout: 5)
|
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
let sendExpectation = XCTestExpectation(description: "sendToAddress")
|
2021-09-23 06:26:41 -07:00
|
|
|
var pendingEntity: PendingTransactionEntity?
|
2022-09-13 03:19:56 -07:00
|
|
|
var testError: Error?
|
2022-06-22 12:45:37 -07:00
|
|
|
let sendAmount = Zatoshi(10000)
|
2021-08-04 10:14:15 -07:00
|
|
|
/*
|
2021-09-23 06:26:41 -07:00
|
|
|
4. create transaction
|
|
|
|
*/
|
2022-09-13 03:19:56 -07:00
|
|
|
do {
|
|
|
|
let pending = try await coordinator.synchronizer.sendToAddress(
|
|
|
|
spendingKey: coordinator.spendingKeys!.first!,
|
|
|
|
zatoshi: sendAmount,
|
2022-09-30 05:53:34 -07:00
|
|
|
toAddress: try! Recipient(testRecipientAddress, network: self.network.networkType),
|
2022-10-27 16:09:08 -07:00
|
|
|
memo: nil
|
2022-10-02 19:11:17 -07:00
|
|
|
)
|
2022-09-13 03:19:56 -07:00
|
|
|
pendingEntity = pending
|
2021-08-04 10:14:15 -07:00
|
|
|
sendExpectation.fulfill()
|
2022-09-13 03:19:56 -07:00
|
|
|
} catch {
|
|
|
|
testError = error
|
2021-08-04 10:14:15 -07:00
|
|
|
}
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
wait(for: [sendExpectation], timeout: 12)
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-09-23 06:26:41 -07:00
|
|
|
guard pendingEntity != nil else {
|
2022-09-13 03:19:56 -07:00
|
|
|
XCTFail("error sending to address. Error: \(String(describing: testError))")
|
2021-08-04 10:14:15 -07:00
|
|
|
return
|
|
|
|
}
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
/*
|
2021-09-23 06:26:41 -07:00
|
|
|
5. stage 10 empty blocks
|
|
|
|
*/
|
2021-08-04 10:14:15 -07:00
|
|
|
try coordinator.stageBlockCreate(height: receivedTxHeight + 1, count: 10)
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
let sentTxHeight = receivedTxHeight + 1
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
/*
|
2021-09-23 06:26:41 -07:00
|
|
|
6. stage sent tx at sentTxHeight
|
|
|
|
*/
|
2021-08-04 10:14:15 -07:00
|
|
|
guard let sentTx = try coordinator.getIncomingTransactions()?.first else {
|
|
|
|
XCTFail("sent transaction not present on Darksidewalletd")
|
|
|
|
return
|
|
|
|
}
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
try coordinator.stageTransaction(sentTx, at: sentTxHeight)
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
/*
|
2021-09-23 06:26:41 -07:00
|
|
|
6a. applyheight(sentTxHeight + 1 )
|
|
|
|
*/
|
2021-08-04 10:14:15 -07:00
|
|
|
try coordinator.applyStaged(blockheight: sentTxHeight + 1)
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
sleep(2)
|
|
|
|
self.foundTransactionsExpectation = XCTestExpectation(description: "inbound expectation")
|
2021-09-23 06:26:41 -07:00
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
/*
|
2021-09-23 06:26:41 -07:00
|
|
|
7. sync to sentTxHeight + 1
|
|
|
|
*/
|
2021-08-04 10:14:15 -07:00
|
|
|
let sentTxSyncExpectation = XCTestExpectation(description: "sent tx sync expectation")
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2022-09-13 03:19:56 -07:00
|
|
|
try await withCheckedThrowingContinuation { continuation in
|
|
|
|
do {
|
|
|
|
try coordinator.sync(completion: { synchronizer in
|
|
|
|
let pMinedHeight = synchronizer.pendingTransactions.first?.minedHeight
|
|
|
|
XCTAssertEqual(pMinedHeight, sentTxHeight)
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2022-09-13 03:19:56 -07:00
|
|
|
sentTxSyncExpectation.fulfill()
|
|
|
|
continuation.resume()
|
|
|
|
}, error: self.handleError)
|
|
|
|
} catch {
|
|
|
|
continuation.resume(throwing: error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-04 10:14:15 -07:00
|
|
|
wait(for: [sentTxSyncExpectation, foundTransactionsExpectation], timeout: 5)
|
|
|
|
}
|
2022-10-27 16:09:08 -07:00
|
|
|
|
2021-08-04 10:14:15 -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)")
|
|
|
|
}
|
|
|
|
}
|