From b6bb17ab8beccc61a8eee90e09a04ecf34fe7bde Mon Sep 17 00:00:00 2001 From: Francisco Gindre Date: Mon, 11 Jul 2022 09:17:22 -0300 Subject: [PATCH] [#406] some BirthdayTests fail for MacOS target (#410) Closes #406 This commits differences how Checkpoints are retrieved from the resource bundle depending on the target platform. --- .../Constants/WalletBirthday+Constants.swift | 131 +++++++++++++----- .../Constants/WalletBirthday+mainnet.swift | 15 +- 2 files changed, 100 insertions(+), 46 deletions(-) diff --git a/Sources/ZcashLightClientKit/Constants/WalletBirthday+Constants.swift b/Sources/ZcashLightClientKit/Constants/WalletBirthday+Constants.swift index 99fc23eb..f1510e5b 100644 --- a/Sources/ZcashLightClientKit/Constants/WalletBirthday+Constants.swift +++ b/Sources/ZcashLightClientKit/Constants/WalletBirthday+Constants.swift @@ -8,51 +8,106 @@ import Foundation public extension WalletBirthday { - static func birthday(with height: BlockHeight, network: ZcashNetwork) -> WalletBirthday { - switch network.networkType { - case .mainnet: - return birthday(with: height, checkpointDirectory: Self.mainnetCheckpointDirectory) ?? .mainnetMin - case .testnet: - return birthday(with: height, checkpointDirectory: Self.testnetCheckpointDirectory) ?? .testnetMin + static func birthday(with height: BlockHeight, network: ZcashNetwork) -> WalletBirthday { + let checkpointDirectoryURL = BundleCheckpointURLProvider.default.url(network.networkType) + + switch network.networkType { + case .mainnet: + return birthday(with: height, checkpointDirectory: checkpointDirectoryURL) ?? .mainnetMin + case .testnet: + return birthday(with: height, checkpointDirectory: checkpointDirectoryURL) ?? .testnetMin + } } - } } extension WalletBirthday { - static func birthday(with height: BlockHeight, checkpointDirectory: URL) -> WalletBirthday? { - return bestCheckpointHeight(for: height, checkpointDirectory: checkpointDirectory) - .flatMap { checkpoint(height: $0, directory: checkpointDirectory) } - } - - private static func bestCheckpointHeight(for height: BlockHeight, checkpointDirectory: URL) -> Int? { - guard let checkPointURLs = try? FileManager.default.contentsOfDirectory( - at: checkpointDirectory, - includingPropertiesForKeys: nil, - options: .skipsHiddenFiles - ) else { - return nil + static func birthday(with height: BlockHeight, checkpointDirectory: URL) -> WalletBirthday? { + return bestCheckpointHeight(for: height, checkpointDirectory: checkpointDirectory) + .flatMap { checkpoint(height: $0, directory: checkpointDirectory) } } - return checkPointURLs - .map { $0.deletingPathExtension() } - .map(\.lastPathComponent) - .compactMap(Int.init) - .filter { $0 <= height } - .sorted() - .last - } + private static func bestCheckpointHeight(for height: BlockHeight, checkpointDirectory: URL) -> Int? { + guard let checkPointURLs = try? FileManager.default.contentsOfDirectory( + at: checkpointDirectory, + includingPropertiesForKeys: nil, + options: .skipsHiddenFiles + ) else { + return nil + } - private static func checkpoint(height: BlockHeight, directory checkpointDirectory: URL) -> WalletBirthday? { - let url = checkpointDirectory - .appendingPathComponent(String(height)) - .appendingPathExtension("json") + return checkPointURLs + .map { $0.deletingPathExtension() } + .map(\.lastPathComponent) + .compactMap(Int.init) + .filter { $0 <= height } + .sorted() + .last + } - return try? checkpoint(at: url) - } + private static func checkpoint(height: BlockHeight, directory checkpointDirectory: URL) -> WalletBirthday? { + let url = checkpointDirectory + .appendingPathComponent(String(height)) + .appendingPathExtension("json") - private static func checkpoint(at url: URL) throws -> WalletBirthday { - let data = try Data(contentsOf: url) - let checkpoint = try JSONDecoder().decode(WalletBirthday.self, from: data) - return checkpoint - } + return try? checkpoint(at: url) + } + + private static func checkpoint(at url: URL) throws -> WalletBirthday { + let data = try Data(contentsOf: url) + let checkpoint = try JSONDecoder().decode(WalletBirthday.self, from: data) + return checkpoint + } +} + +struct BundleCheckpointURLProvider { + var url: (NetworkType) -> URL +} + + +extension BundleCheckpointURLProvider { + + /// Attempts to resolve the platform by checking `#if os(macOS)` build corresponds to a MacOS target + /// `#else` branch of that condition will assume iOS is the target platform + static var `default` = BundleCheckpointURLProvider { networkType in + #if os(macOS) + Self.macOS.url(networkType) + #else + Self.iOS.url(networkType) + #endif + } + + static var iOS = BundleCheckpointURLProvider(url: { networkType in + switch networkType { + case .mainnet: + return WalletBirthday.mainnetCheckpointDirectory + case .testnet: + return WalletBirthday.testnetCheckpointDirectory + } + }) + + /// This variant attempts to retrieve the saplingActivation checkpoint for the given network type + /// using `Bundle.module.url(forResource:withExtension:subdirectory:localization)` + /// if not found it will return `WalletBirthday.mainnetCheckpointDirectory` or + /// `WalletBirthday.testnetCheckpointDirectory`. This responds to tests + /// failing on MacOS target because the checkpoint resources would fail. + static var macOS = BundleCheckpointURLProvider(url: { networkType in + switch networkType { + case .mainnet: + return Bundle.module.url( + forResource: "419200", + withExtension: "json", + subdirectory: "checkpoints/mainnet/", + localization: nil + )? + .deletingLastPathComponent() ?? WalletBirthday.mainnetCheckpointDirectory + case .testnet: + return Bundle.module.url( + forResource: "280000", + withExtension: "json", + subdirectory: "checkpoints/testnet/", + localization: nil + )? + .deletingLastPathComponent() ?? WalletBirthday.testnetCheckpointDirectory + } + }) } diff --git a/Sources/ZcashLightClientKit/Constants/WalletBirthday+mainnet.swift b/Sources/ZcashLightClientKit/Constants/WalletBirthday+mainnet.swift index 638ff006..dfe8c055 100644 --- a/Sources/ZcashLightClientKit/Constants/WalletBirthday+mainnet.swift +++ b/Sources/ZcashLightClientKit/Constants/WalletBirthday+mainnet.swift @@ -7,13 +7,12 @@ import Foundation extension WalletBirthday { - static let mainnetMin = WalletBirthday( - height: 419_200, - hash: "00000000025a57200d898ac7f21e26bf29028bbe96ec46e05b2c17cc9db9e4f3", - time: 1540779337, - saplingTree: "000000" - ) - - static let mainnetCheckpointDirectory = Bundle.module.bundleURL.appendingPathComponent("checkpoints/mainnet/") + static let mainnetMin = WalletBirthday( + height: 419_200, + hash: "00000000025a57200d898ac7f21e26bf29028bbe96ec46e05b2c17cc9db9e4f3", + time: 1540779337, + saplingTree: "000000" + ) + static let mainnetCheckpointDirectory = Bundle.module.bundleURL.appendingPathComponent("checkpoints/mainnet/") }