209 lines
8.0 KiB
Swift
209 lines
8.0 KiB
Swift
//
|
|
// PendingTransactionUpdatesTest.swift
|
|
// ZcashLightClientKit-Unit-Tests
|
|
//
|
|
// Created by Francisco Gindre on 7/17/20.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import ZcashLightClientKit
|
|
class PendingTransactionUpdatesTest: XCTestCase {
|
|
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" //TODO: Parameterize this from environment?
|
|
|
|
let testRecipientAddress = "zs17mg40levjezevuhdp5pqrd52zere7r7vrjgdwn5sj4xsqtm20euwahv9anxmwr3y3kmwuz8k55a" //TODO: Parameterize this from environment
|
|
|
|
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 expectedReorgHeight: BlockHeight = 665188
|
|
var expectedRewindHeight: BlockHeight = 665188
|
|
var reorgExpectation: XCTestExpectation = XCTestExpectation(description: "reorg")
|
|
override func setUpWithError() throws {
|
|
|
|
coordinator = try TestCoordinator(
|
|
seed: seedPhrase,
|
|
walletBirthday: birthday,
|
|
channelProvider: ChannelProvider()
|
|
)
|
|
try coordinator.reset(saplingActivation: 663150)
|
|
}
|
|
|
|
override func tearDownWithError() throws {
|
|
NotificationCenter.default.removeObserver(self)
|
|
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)
|
|
}
|
|
|
|
@objc func handleReorg(_ notification: Notification) {
|
|
|
|
guard let reorgHeight = notification.userInfo?[CompactBlockProcessorNotificationKey.reorgHeight] as? BlockHeight
|
|
// let rewindHeight = notification.userInfo?[CompactBlockProcessorNotificationKey.rewindHeight] as? BlockHeight
|
|
else {
|
|
XCTFail("empty reorg notification")
|
|
return
|
|
}
|
|
|
|
// XCTAssertEqual(rewindHeight, expectedRewindHeight)
|
|
XCTAssertEqual(reorgHeight, expectedReorgHeight)
|
|
reorgExpectation.fulfill()
|
|
}
|
|
|
|
func testPendingTransactionMinedHeightUpdated() throws {
|
|
/*
|
|
1. create fake chain
|
|
*/
|
|
LoggerProxy.info("1. create fake chain")
|
|
|
|
try FakeChainBuilder.buildChain(darksideWallet: coordinator.service)
|
|
|
|
try coordinator.applyStaged(blockheight: 663188)
|
|
sleep(2)
|
|
|
|
let firstSyncExpectation = XCTestExpectation(description: "first sync")
|
|
/*
|
|
1a. sync to latest height
|
|
*/
|
|
|
|
LoggerProxy.info("1a. sync to latest height")
|
|
try coordinator.sync(completion: { (s) in
|
|
|
|
firstSyncExpectation.fulfill()
|
|
}, error: self.handleError)
|
|
|
|
wait(for: [firstSyncExpectation], timeout: 5)
|
|
|
|
sleep(1)
|
|
|
|
let sendExpectation = XCTestExpectation(description: "send expectation")
|
|
var p: PendingTransactionEntity? = nil
|
|
|
|
/*
|
|
2. send transaction to recipient address
|
|
*/
|
|
LoggerProxy.info("2. send transaction to recipient address")
|
|
coordinator.synchronizer.sendToAddress(spendingKey: self.coordinator.spendingKeys!.first!, zatoshi: 20000, toAddress: self.testRecipientAddress, memo: "this is a test", from: 0, resultBlock: { (result) in
|
|
switch result {
|
|
case .failure(let e):
|
|
self.handleError(e)
|
|
case .success(let pendingTx):
|
|
p = pendingTx
|
|
}
|
|
sendExpectation.fulfill()
|
|
})
|
|
|
|
wait(for: [sendExpectation], timeout: 11)
|
|
|
|
guard let pendingUnconfirmedTx = p else {
|
|
XCTFail("no pending transaction after sending")
|
|
try coordinator.stop()
|
|
return
|
|
}
|
|
|
|
XCTAssertFalse(pendingUnconfirmedTx.isConfirmed(currentHeight: 663188), "pending transaction evaluated as confirmed when it shouldn't")
|
|
XCTAssertFalse(pendingUnconfirmedTx.isMined, "pending transaction evaluated as mined when it shouldn't")
|
|
|
|
XCTAssertTrue(pendingUnconfirmedTx.isPending(currentHeight: 663188), "pending transaction evaluated as not pending when it should be")
|
|
/**
|
|
3. getIncomingTransaction
|
|
*/
|
|
LoggerProxy.info("3. getIncomingTransaction")
|
|
guard let incomingTx = try coordinator.getIncomingTransactions()?.first else {
|
|
XCTFail("no incoming transaction")
|
|
try coordinator.stop()
|
|
return
|
|
}
|
|
|
|
let sentTxHeight: BlockHeight = 663189
|
|
|
|
|
|
/*
|
|
4. stage transaction at sentTxHeight
|
|
*/
|
|
LoggerProxy.info("4. stage transaction at \(sentTxHeight)")
|
|
try coordinator.stageBlockCreate(height: sentTxHeight)
|
|
|
|
try coordinator.stageTransaction(incomingTx, at: sentTxHeight)
|
|
/*
|
|
5. applyHeight(sentTxHeight)
|
|
*/
|
|
LoggerProxy.info("5. applyHeight(\(sentTxHeight))")
|
|
try coordinator.applyStaged(blockheight: sentTxHeight)
|
|
|
|
sleep(2)
|
|
|
|
/*
|
|
6. sync to latest height
|
|
*/
|
|
LoggerProxy.info("6. sync to latest height")
|
|
let secondSyncExpectation = XCTestExpectation(description: "after send expectation")
|
|
|
|
try coordinator.sync(completion: { (s) in
|
|
secondSyncExpectation.fulfill()
|
|
}, error: self.handleError)
|
|
|
|
wait(for: [secondSyncExpectation], timeout: 5)
|
|
|
|
XCTAssertEqual(coordinator.synchronizer.pendingTransactions.count, 1)
|
|
guard let afterStagePendingTx = coordinator.synchronizer.pendingTransactions.first else {
|
|
return
|
|
}
|
|
|
|
/*
|
|
6a. verify that there's a pending transaction with a mined height of sentTxHeight
|
|
*/
|
|
LoggerProxy.info("6a. verify that there's a pending transaction with a mined height of \(sentTxHeight)")
|
|
XCTAssertEqual(afterStagePendingTx.minedHeight, sentTxHeight)
|
|
XCTAssertTrue(afterStagePendingTx.isMined, "pending transaction shown as unmined when it has been mined")
|
|
XCTAssertTrue(afterStagePendingTx.isPending(currentHeight: sentTxHeight))
|
|
|
|
/*
|
|
7. stage 15 blocks from sentTxHeight
|
|
*/
|
|
LoggerProxy.info("7. stage 15 blocks from \(sentTxHeight)")
|
|
try coordinator.stageBlockCreate(height: sentTxHeight + 1, count: 15)
|
|
sleep(2)
|
|
let lastStageHeight = sentTxHeight + 14
|
|
LoggerProxy.info("applyStaged(\(lastStageHeight))")
|
|
try coordinator.applyStaged(blockheight: lastStageHeight)
|
|
|
|
sleep(2)
|
|
let syncToConfirmExpectation = XCTestExpectation(description: "sync to confirm expectation")
|
|
|
|
/*
|
|
8. last sync to latest height
|
|
*/
|
|
LoggerProxy.info("last sync to latest height: \(lastStageHeight)")
|
|
|
|
try coordinator.sync(completion: { (s) in
|
|
syncToConfirmExpectation.fulfill()
|
|
}, error: self.handleError)
|
|
|
|
wait(for: [syncToConfirmExpectation], timeout: 6)
|
|
var supposedlyPendingUnexistingTransaction: PendingTransactionEntity? = nil
|
|
|
|
XCTAssertNoThrow(try { supposedlyPendingUnexistingTransaction = try coordinator.synchronizer.allPendingTransactions().first }())
|
|
|
|
XCTAssertNil(supposedlyPendingUnexistingTransaction)
|
|
}
|
|
|
|
|
|
|
|
func handleError(_ error: Error?) {
|
|
_ = try? coordinator.stop()
|
|
guard let testError = error else {
|
|
XCTFail("failed with nil error")
|
|
return
|
|
}
|
|
XCTFail("Failed with error: \(testError)")
|
|
}
|
|
|
|
func hookToReOrgNotification() {
|
|
NotificationCenter.default.addObserver(self, selector: #selector(handleReorg(_:)), name: .blockProcessorHandledReOrg, object: nil)
|
|
}
|
|
}
|