ZcashLightClientKit/ZcashLightClientKitTests/BlockBatchValidationTests.s...

507 lines
19 KiB
Swift
Raw Normal View History

2021-06-17 16:58:30 -07:00
//
// BlockBatchValidationTests.swift
// ZcashLightClientKit-Unit-Tests
//
// Created by Francisco Gindre on 6/17/21.
//
import XCTest
@testable import ZcashLightClientKit
2021-09-23 06:26:41 -07:00
// swiftlint:disable force_try type_body_length
2021-06-17 16:58:30 -07:00
class BlockBatchValidationTests: XCTestCase {
var queue: OperationQueue = {
2021-09-23 06:26:41 -07:00
let queue = OperationQueue()
queue.name = "Test Queue"
queue.maxConcurrentOperationCount = 1
return queue
2021-06-17 16:58:30 -07:00
}()
2021-09-23 06:26:41 -07:00
override func setUp() {
2021-06-17 16:58:30 -07:00
// Put setup code here. This method is called before the invocation of each test method in the class.
2021-09-23 06:26:41 -07:00
super.setUp()
2021-06-17 16:58:30 -07:00
}
2021-09-23 06:26:41 -07:00
override func tearDown() {
2021-06-17 16:58:30 -07:00
// Put teardown code here. This method is called after the invocation of each test method in the class.
2021-09-23 06:26:41 -07:00
super.tearDown()
2021-06-17 16:58:30 -07:00
}
func testBranchIdFailure() throws {
2021-07-28 09:59:10 -07:00
let network = ZcashNetworkBuilder.network(for: .mainnet)
2021-09-23 06:26:41 -07:00
let service = MockLightWalletService(
latestBlockHeight: 1210000,
service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
)
2021-06-17 16:58:30 -07:00
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
let downloader = CompactBlockDownloader(service: service, storage: repository)
2021-09-23 06:26:41 -07:00
let config = CompactBlockProcessor.Configuration(
cacheDb: try! __cacheDbURL(),
dataDb: try! __dataDbURL(),
downloadBatchSize: 100,
retries: 5,
maxBackoffInterval: 10,
rewindDistance: 100,
walletBirthday: 1210000,
saplingActivation: network.constants.saplingActivationHeight,
network: network
)
2021-06-17 16:58:30 -07:00
var info = LightdInfo()
info.blockHeight = 130000
info.branch = "d34db33f"
info.chainName = "main"
info.buildUser = "test user"
info.consensusBranchID = "d34db33f"
2021-09-15 05:21:29 -07:00
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
2021-06-17 16:58:30 -07:00
service.mockLightDInfo = info
let mockRust = MockRustBackend.self
mockRust.consensusBranchID = Int32(0xd34d)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
let operation = FigureNextBatchOperation(downloader: downloader, service: service, config: config, rustBackend: mockRust)
let expectation = XCTestExpectation(description: "failure expectation")
let startedExpectation = XCTestExpectation(description: "start Expectation")
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.startedHandler = {
startedExpectation.fulfill()
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.errorHandler = { error in
expectation.fulfill()
switch error {
case CompactBlockProcessorError.wrongConsensusBranchId:
break
default:
XCTFail("Expected CompactBlockProcessorError.wrongConsensusBranchId but found \(error)")
}
}
queue.addOperations([operation], waitUntilFinished: false)
2021-09-23 06:26:41 -07:00
wait(for: [startedExpectation, expectation], timeout: 1, enforceOrder: true)
2021-06-17 16:58:30 -07:00
XCTAssertNotNil(operation.error)
XCTAssertTrue(operation.isCancelled)
}
func testBranchNetworkMismatchFailure() throws {
2021-07-28 09:59:10 -07:00
let network = ZcashNetworkBuilder.network(for: .mainnet)
2021-09-23 06:26:41 -07:00
let service = MockLightWalletService(
latestBlockHeight: 1210000,
service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
)
2021-06-17 16:58:30 -07:00
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
let downloader = CompactBlockDownloader(service: service, storage: repository)
2021-09-23 06:26:41 -07:00
let config = CompactBlockProcessor.Configuration(
cacheDb: try! __cacheDbURL(),
dataDb: try! __dataDbURL(),
downloadBatchSize: 100,
retries: 5,
maxBackoffInterval: 10,
rewindDistance: 100,
walletBirthday: 1210000,
saplingActivation: network.constants.saplingActivationHeight,
network: network
)
2021-06-17 16:58:30 -07:00
var info = LightdInfo()
info.blockHeight = 130000
info.branch = "d34db33f"
info.chainName = "test"
info.buildUser = "test user"
info.consensusBranchID = "d34db4d"
2021-09-15 05:21:29 -07:00
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
service.mockLightDInfo = info
let mockRust = MockRustBackend.self
mockRust.consensusBranchID = 0xd34db4d
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
let operation = FigureNextBatchOperation(downloader: downloader, service: service, config: config, rustBackend: mockRust)
let expectation = XCTestExpectation(description: "failure expectation")
let startedExpectation = XCTestExpectation(description: "start Expectation")
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.startedHandler = {
startedExpectation.fulfill()
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.errorHandler = { error in
expectation.fulfill()
switch error {
case CompactBlockProcessorError.networkMismatch(expected: .mainnet, found: .testnet):
break
default:
XCTFail("Expected CompactBlockProcessorError.networkMismatch but found \(error)")
}
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
queue.addOperations([operation], waitUntilFinished: false)
2021-09-23 06:26:41 -07:00
wait(for: [startedExpectation, expectation], timeout: 1, enforceOrder: true)
2021-06-17 16:58:30 -07:00
XCTAssertNotNil(operation.error)
XCTAssertTrue(operation.isCancelled)
}
func testBranchNetworkTypeWrongFailure() throws {
2021-07-28 09:59:10 -07:00
let network = ZcashNetworkBuilder.network(for: .testnet)
2021-09-23 06:26:41 -07:00
let service = MockLightWalletService(
latestBlockHeight: 1210000,
service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
)
2021-06-17 16:58:30 -07:00
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
let downloader = CompactBlockDownloader(service: service, storage: repository)
2021-09-23 06:26:41 -07:00
let config = CompactBlockProcessor.Configuration(
cacheDb: try! __cacheDbURL(),
dataDb: try! __dataDbURL(),
downloadBatchSize: 100,
retries: 5,
maxBackoffInterval: 10,
rewindDistance: 100,
walletBirthday: 1210000,
saplingActivation: network.constants.saplingActivationHeight,
network: network
)
2021-06-17 16:58:30 -07:00
var info = LightdInfo()
info.blockHeight = 130000
info.branch = "d34db33f"
info.chainName = "another"
info.buildUser = "test user"
info.consensusBranchID = "d34db4d"
2021-09-15 05:21:29 -07:00
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
service.mockLightDInfo = info
let mockRust = MockRustBackend.self
mockRust.consensusBranchID = 0xd34db4d
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
let operation = FigureNextBatchOperation(downloader: downloader, service: service, config: config, rustBackend: mockRust)
let expectation = XCTestExpectation(description: "failure expectation")
let startedExpectation = XCTestExpectation(description: "start Expectation")
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.startedHandler = {
startedExpectation.fulfill()
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.errorHandler = { error in
expectation.fulfill()
switch error {
case CompactBlockProcessorError.generalError:
break
default:
XCTFail("Expected CompactBlockProcessorError.generalError but found \(error)")
}
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
queue.addOperations([operation], waitUntilFinished: false)
2021-09-23 06:26:41 -07:00
wait(for: [startedExpectation, expectation], timeout: 1, enforceOrder: true)
2021-06-17 16:58:30 -07:00
XCTAssertNotNil(operation.error)
XCTAssertTrue(operation.isCancelled)
}
func testSaplingActivationHeightMismatch() throws {
2021-07-28 09:59:10 -07:00
let network = ZcashNetworkBuilder.network(for: .mainnet)
2021-09-23 06:26:41 -07:00
let service = MockLightWalletService(
latestBlockHeight: 1210000,
service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
)
2021-06-17 16:58:30 -07:00
let repository = ZcashConsoleFakeStorage(latestBlockHeight: 1220000)
let downloader = CompactBlockDownloader(service: service, storage: repository)
2021-09-23 06:26:41 -07:00
let config = CompactBlockProcessor.Configuration(
cacheDb: try! __cacheDbURL(),
dataDb: try! __dataDbURL(),
downloadBatchSize: 100,
retries: 5,
maxBackoffInterval: 10,
rewindDistance: 100,
walletBirthday: 1210000,
saplingActivation: network.constants.saplingActivationHeight,
network: network
)
2021-06-17 16:58:30 -07:00
var info = LightdInfo()
info.blockHeight = 130000
info.branch = "d34db33f"
info.chainName = "main"
info.buildUser = "test user"
info.consensusBranchID = "d34db4d"
info.saplingActivationHeight = UInt64(3434343)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
service.mockLightDInfo = info
let mockRust = MockRustBackend.self
mockRust.consensusBranchID = 0xd34db4d
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
let operation = FigureNextBatchOperation(downloader: downloader, service: service, config: config, rustBackend: mockRust)
let expectation = XCTestExpectation(description: "failure expectation")
let startedExpectation = XCTestExpectation(description: "start Expectation")
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.startedHandler = {
startedExpectation.fulfill()
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.errorHandler = { error in
expectation.fulfill()
switch error {
2021-09-23 06:26:41 -07:00
case CompactBlockProcessorError.saplingActivationMismatch(
expected: network.constants.saplingActivationHeight,
found: BlockHeight(info.saplingActivationHeight)
):
2021-06-17 16:58:30 -07:00
break
default:
XCTFail("Expected CompactBlockProcessorError.saplingActivationMismatch but found \(error)")
}
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
queue.addOperations([operation], waitUntilFinished: false)
2021-09-23 06:26:41 -07:00
wait(for: [startedExpectation, expectation], timeout: 1, enforceOrder: true)
2021-06-17 16:58:30 -07:00
XCTAssertNotNil(operation.error)
XCTAssertTrue(operation.isCancelled)
}
func testResultIsWait() throws {
2021-07-28 09:59:10 -07:00
let network = ZcashNetworkBuilder.network(for: .mainnet)
2021-06-17 16:58:30 -07:00
let expectedLatestHeight = BlockHeight(1210000)
2021-09-23 06:26:41 -07:00
let service = MockLightWalletService(
latestBlockHeight: expectedLatestHeight,
service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
)
2021-06-17 16:58:30 -07:00
let expectedStoreLatestHeight = BlockHeight(1220000)
2021-09-23 06:26:41 -07:00
let expectedResult = FigureNextBatchOperation.NextState.wait(
latestHeight: expectedLatestHeight,
latestDownloadHeight: expectedLatestHeight
)
2021-06-17 16:58:30 -07:00
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
let downloader = CompactBlockDownloader(service: service, storage: repository)
2021-09-23 06:26:41 -07:00
let config = CompactBlockProcessor.Configuration(
cacheDb: try! __cacheDbURL(),
dataDb: try! __dataDbURL(),
downloadBatchSize: 100,
retries: 5,
maxBackoffInterval: 10,
rewindDistance: 100,
walletBirthday: 1210000,
saplingActivation: network.constants.saplingActivationHeight,
network: network
)
2021-06-17 16:58:30 -07:00
var info = LightdInfo()
info.blockHeight = UInt64(expectedLatestHeight)
info.branch = "d34db33f"
info.chainName = "main"
info.buildUser = "test user"
info.consensusBranchID = "d34db4d"
2021-09-15 05:21:29 -07:00
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
service.mockLightDInfo = info
let mockRust = MockRustBackend.self
mockRust.consensusBranchID = 0xd34db4d
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
let operation = FigureNextBatchOperation(downloader: downloader, service: service, config: config, rustBackend: mockRust)
let completedExpectation = XCTestExpectation(description: "completed expectation")
let startedExpectation = XCTestExpectation(description: "start Expectation")
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.startedHandler = {
startedExpectation.fulfill()
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.errorHandler = { error in
2021-07-28 09:59:10 -07:00
XCTFail("this shouldn't happen: \(error)")
2021-06-17 16:58:30 -07:00
}
2021-09-23 06:26:41 -07:00
operation.completionHandler = { finished, cancelled in
2021-06-17 16:58:30 -07:00
completedExpectation.fulfill()
XCTAssertTrue(finished)
XCTAssertFalse(cancelled)
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
queue.addOperations([operation], waitUntilFinished: false)
2021-09-23 06:26:41 -07:00
wait(for: [startedExpectation, completedExpectation], timeout: 1, enforceOrder: true)
2021-06-17 16:58:30 -07:00
XCTAssertNil(operation.error)
XCTAssertFalse(operation.isCancelled)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
guard let result = operation.result else {
XCTFail("result should not be nil")
return
}
2021-09-23 06:26:41 -07:00
XCTAssertTrue(
{
switch result {
case .wait(latestHeight: expectedLatestHeight, latestDownloadHeight: expectedLatestHeight):
return true
default:
return false
}
}(),
"Expected \(expectedResult) got: \(result)"
)
2021-06-17 16:58:30 -07:00
}
func testResultProcessNew() throws {
2021-07-28 09:59:10 -07:00
let network = ZcashNetworkBuilder.network(for: .mainnet)
2021-06-17 16:58:30 -07:00
let expectedLatestHeight = BlockHeight(1230000)
2021-09-23 06:26:41 -07:00
let service = MockLightWalletService(
latestBlockHeight: expectedLatestHeight,
service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
)
2021-06-17 16:58:30 -07:00
let expectedStoreLatestHeight = BlockHeight(1220000)
let walletBirthday = BlockHeight(1210000)
2021-09-23 06:26:41 -07:00
let expectedResult = FigureNextBatchOperation.NextState.processNewBlocks(
range: CompactBlockProcessor.nextBatchBlockRange(
latestHeight: expectedLatestHeight,
latestDownloadedHeight: expectedStoreLatestHeight,
walletBirthday: walletBirthday
)
)
2021-06-17 16:58:30 -07:00
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
let downloader = CompactBlockDownloader(service: service, storage: repository)
2021-09-23 06:26:41 -07:00
let config = CompactBlockProcessor.Configuration(
cacheDb: try! __cacheDbURL(),
dataDb: try! __dataDbURL(),
downloadBatchSize: 100,
retries: 5,
maxBackoffInterval: 10,
rewindDistance: 100,
walletBirthday: walletBirthday,
saplingActivation: network.constants.saplingActivationHeight,
network: network
)
2021-06-17 16:58:30 -07:00
var info = LightdInfo()
info.blockHeight = UInt64(expectedLatestHeight)
info.branch = "d34db33f"
info.chainName = "main"
info.buildUser = "test user"
info.consensusBranchID = "d34db4d"
2021-09-15 05:21:29 -07:00
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
service.mockLightDInfo = info
let mockRust = MockRustBackend.self
mockRust.consensusBranchID = 0xd34db4d
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
let operation = FigureNextBatchOperation(downloader: downloader, service: service, config: config, rustBackend: mockRust)
let completedExpectation = XCTestExpectation(description: "completed expectation")
let startedExpectation = XCTestExpectation(description: "start Expectation")
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.startedHandler = {
startedExpectation.fulfill()
}
2021-09-23 06:26:41 -07:00
operation.errorHandler = { _ in
2021-06-17 16:58:30 -07:00
XCTFail("this shouldn't happen")
}
2021-09-23 06:26:41 -07:00
operation.completionHandler = { finished, cancelled in
2021-06-17 16:58:30 -07:00
completedExpectation.fulfill()
XCTAssertTrue(finished)
XCTAssertFalse(cancelled)
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
queue.addOperations([operation], waitUntilFinished: false)
2021-09-23 06:26:41 -07:00
wait(for: [startedExpectation, completedExpectation], timeout: 1, enforceOrder: true)
2021-06-17 16:58:30 -07:00
XCTAssertNil(operation.error)
XCTAssertFalse(operation.isCancelled)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
guard let result = operation.result else {
XCTFail("result should not be nil")
return
}
2021-09-23 06:26:41 -07:00
XCTAssertTrue(
{
switch result {
case .processNewBlocks(range: CompactBlockRange(uncheckedBounds: (expectedStoreLatestHeight + 1, expectedLatestHeight))):
return true
default:
return false
}
}(),
"Expected \(expectedResult) got: \(result)"
)
2021-06-17 16:58:30 -07:00
}
func testResultProcessorFinished() throws {
2021-07-28 09:59:10 -07:00
let network = ZcashNetworkBuilder.network(for: .mainnet)
2021-06-17 16:58:30 -07:00
let expectedLatestHeight = BlockHeight(1230000)
2021-09-23 06:26:41 -07:00
let service = MockLightWalletService(
latestBlockHeight: expectedLatestHeight,
service: LightWalletGRPCService(endpoint: LightWalletEndpointBuilder.default)
)
2021-06-17 16:58:30 -07:00
let expectedStoreLatestHeight = BlockHeight(1230000)
let walletBirthday = BlockHeight(1210000)
let expectedResult = FigureNextBatchOperation.NextState.finishProcessing(height: expectedStoreLatestHeight)
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
let downloader = CompactBlockDownloader(service: service, storage: repository)
2021-09-23 06:26:41 -07:00
let config = CompactBlockProcessor.Configuration(
cacheDb: try! __cacheDbURL(),
dataDb: try! __dataDbURL(),
downloadBatchSize: 100,
retries: 5,
maxBackoffInterval: 10,
rewindDistance: 100,
walletBirthday: walletBirthday,
saplingActivation: network.constants.saplingActivationHeight,
network: network
)
2021-06-17 16:58:30 -07:00
var info = LightdInfo()
info.blockHeight = UInt64(expectedLatestHeight)
info.branch = "d34db33f"
info.chainName = "main"
info.buildUser = "test user"
info.consensusBranchID = "d34db4d"
2021-09-15 05:21:29 -07:00
info.saplingActivationHeight = UInt64(network.constants.saplingActivationHeight)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
service.mockLightDInfo = info
let mockRust = MockRustBackend.self
mockRust.consensusBranchID = 0xd34db4d
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
let operation = FigureNextBatchOperation(downloader: downloader, service: service, config: config, rustBackend: mockRust)
let completedExpectation = XCTestExpectation(description: "completed expectation")
let startedExpectation = XCTestExpectation(description: "start Expectation")
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
operation.startedHandler = {
startedExpectation.fulfill()
}
2021-09-23 06:26:41 -07:00
operation.errorHandler = { _ in
2021-06-17 16:58:30 -07:00
XCTFail("this shouldn't happen")
}
2021-09-23 06:26:41 -07:00
operation.completionHandler = { finished, cancelled in
2021-06-17 16:58:30 -07:00
completedExpectation.fulfill()
XCTAssertTrue(finished)
XCTAssertFalse(cancelled)
}
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
queue.addOperations([operation], waitUntilFinished: false)
2021-09-23 06:26:41 -07:00
wait(for: [startedExpectation, completedExpectation], timeout: 1, enforceOrder: true)
2021-06-17 16:58:30 -07:00
XCTAssertNil(operation.error)
XCTAssertFalse(operation.isCancelled)
2021-09-23 06:26:41 -07:00
2021-06-17 16:58:30 -07:00
guard let result = operation.result else {
XCTFail("result should not be nil")
return
}
2021-09-23 06:26:41 -07:00
XCTAssertTrue(
{
switch result {
case .finishProcessing(height: expectedLatestHeight):
return true
default:
return false
}
}(),
"Expected \(expectedResult) got: \(result)"
)
2021-06-17 16:58:30 -07:00
}
}