Swiftlint (#5)

* Swiftlint + tests

* Added Swiftlint to README.md
This commit is contained in:
Francisco Gindre 2019-10-18 17:09:13 -03:00 committed by GitHub
parent 60ea9d6737
commit 3e2050d0f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 131 additions and 134 deletions

45
.swiftlint.yml Normal file
View File

@ -0,0 +1,45 @@
whitelist_rules:
- closure_spacing
- colon
- empty_enum_arguments
- fatal_error_message
- force_cast
- force_try
- force_unwrapping
- implicitly_unwrapped_optional
- legacy_cggeometry_functions
- legacy_constant
- legacy_constructor
- legacy_nsgeometry_functions
- operator_usage_whitespace
- redundant_string_enum_value
- redundant_void_return
- return_arrow_whitespace
- trailing_newline
- type_name
- unused_closure_parameter
- unused_optional_binding
- vertical_whitespace
- void_return
- custom_rules
excluded:
- Carthage
- Pods
- ZcashLightClientKit/Service/ProtoBuf/compact_formats.pb.swift
- ZcashLightClientKit/Service/ProtoBuf/service.grpc.swift
- ZcashLightClientKit/Service/ProtoBuf/service.pb.swift
- Example
- ZcashLightClientKitTests
colon:
apply_to_dictionaries: false
indentation: 2
custom_rules:
no_objcMembers:
name: "@objcMembers"
regex: "@objcMembers"
message: "Explicitly use @objc on each member you want to expose to Objective-C"
severity: error

View File

@ -43,6 +43,8 @@ The ```LIGHTWALLETD_ADDRESS``` environment variable can also be added to your sh
We advice setting this value as a secret variable on your CD/CI environment when possible We advice setting this value as a secret variable on your CD/CI environment when possible
# Swiftlint
We don't like reinveing the wheel, so be gently borrowed swift lint rules from AirBnB which we find pretty cool and reasonable.
## Troubleshooting ## Troubleshooting

View File

@ -401,6 +401,7 @@
buildPhases = ( buildPhases = (
103AFE80228312A30074BC98 /* Headers */, 103AFE80228312A30074BC98 /* Headers */,
103AFE9F2283152F0074BC98 /* ShellScript */, 103AFE9F2283152F0074BC98 /* ShellScript */,
0D3BA6B1235A420B00E0E0F4 /* ShellScript */,
103AFE81228312A30074BC98 /* Sources */, 103AFE81228312A30074BC98 /* Sources */,
103AFE82228312A30074BC98 /* Frameworks */, 103AFE82228312A30074BC98 /* Frameworks */,
103AFE83228312A30074BC98 /* Resources */, 103AFE83228312A30074BC98 /* Resources */,
@ -512,6 +513,23 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/usr/local/bin/carthage copy-frameworks\n"; shellScript = "/usr/local/bin/carthage copy-frameworks\n";
}; };
0D3BA6B1235A420B00E0E0F4 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\n swiftlint lint --config .swiftlint.yml\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
0DC64E65232848F10053EFAC /* ShellScript */ = { 0DC64E65232848F10053EFAC /* ShellScript */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;

View File

@ -9,7 +9,6 @@
import Foundation import Foundation
import SQLite import SQLite
struct CompactBlockStorage: CompactBlockDAO { struct CompactBlockStorage: CompactBlockDAO {
var db: Connection var db: Connection
@ -120,5 +119,4 @@ extension CompactBlockStorage: CompactBlockStoring {
} }
} }
} }

View File

@ -19,7 +19,6 @@ class SQLiteStorage: Storage {
self.connection = connection self.connection = connection
} }
func open(at path: String) throws { func open(at path: String) throws {
do { do {
connection = try Connection(path) connection = try Connection(path)
@ -35,15 +34,13 @@ class SQLiteStorage: Storage {
func closeDatabase() {} func closeDatabase() {}
} }
/** /**
Set schema version Set schema version
*/ */
// TODO: define a better way to do this // TODO: define a better way to do this
extension Connection { //extension Connection {
public var userVersion: Int32 { // public var userVersion: Int32 {
get { return Int32(try! scalar("PRAGMA user_version") as! Int64)} // get { return Int32(try scalar("PRAGMA user_version") as Int64)}
set { try! run("PRAGMA user_version = \(newValue)")} // set { try! run("PRAGMA user_version = \(newValue)")}
} // }
} //}

View File

@ -57,7 +57,6 @@ class CompactBlockDownloader {
extension CompactBlockDownloader: CompactBlockDownloading { extension CompactBlockDownloader: CompactBlockDownloading {
/** /**
Downloads and stores the given block range. Downloads and stores the given block range.
Non-Blocking Non-Blocking
@ -89,7 +88,6 @@ extension CompactBlockDownloader: CompactBlockDownloading {
try storage.write(blocks: blocks) try storage.write(blocks: blocks)
} }
func rewind(to height: BlockHeight, completion: @escaping (Error?) -> Void){ func rewind(to height: BlockHeight, completion: @escaping (Error?) -> Void){
storage.rewind(to: height) { (e) in storage.rewind(to: height) { (e) in
@ -121,6 +119,4 @@ extension CompactBlockDownloader: CompactBlockDownloading {
try self.storage.latestHeight() try self.storage.latestHeight()
} }
} }

View File

@ -18,7 +18,7 @@ class CompactBlockScanningOperation: ZcashOperation {
private var cacheDb: URL private var cacheDb: URL
private var dataDb: URL private var dataDb: URL
init(rustWelding: ZcashRustBackendWelding.Type, cacheDb: URL, dataDb:URL) { init(rustWelding: ZcashRustBackendWelding.Type, cacheDb: URL, dataDb: URL) {
rustBackend = rustWelding rustBackend = rustWelding
self.cacheDb = cacheDb self.cacheDb = cacheDb
self.dataDb = dataDb self.dataDb = dataDb

View File

@ -8,7 +8,6 @@
import Foundation import Foundation
enum CompactBlockProcessorError: Error { enum CompactBlockProcessorError: Error {
case invalidConfiguration case invalidConfiguration
case missingDbPath(path: String) case missingDbPath(path: String)
@ -16,16 +15,14 @@ enum CompactBlockProcessorError: Error {
extension Notification.Name { extension Notification.Name {
static let blockProcessorUpdated = Notification.Name(rawValue: "CompactBlockProcessorUpdated") static let blockProcessorUpdated = Notification.Name(rawValue: "CompactBlockProcessorUpdated")
static let blockProcessorStarted = Notification.Name(rawValue:"CompactBlockProcessorStarted") static let blockProcessorStarted = Notification.Name(rawValue: "CompactBlockProcessorStarted")
static let blockProcessorStopped = Notification.Name(rawValue:"CompactBlockProcessorStopped") static let blockProcessorStopped = Notification.Name(rawValue: "CompactBlockProcessorStopped")
static let blockProcessorFinished = Notification.Name(rawValue:"CompactBlockProcessorFinished") static let blockProcessorFinished = Notification.Name(rawValue: "CompactBlockProcessorFinished")
static let blockProcessorFailed = Notification.Name(rawValue:"CompactBlockProcessorFinished") static let blockProcessorFailed = Notification.Name(rawValue: "CompactBlockProcessorFinished")
} }
class CompactBlockProcessor { class CompactBlockProcessor {
enum State { enum State {
/** /**
@ -66,12 +63,10 @@ class CompactBlockProcessor {
config.retries config.retries
} }
private var batchSize: BlockHeight { private var batchSize: BlockHeight {
BlockHeight(self.config.downloadBatchSize) BlockHeight(self.config.downloadBatchSize)
} }
private var processingError: Error? private var processingError: Error?
init(downloader: CompactBlockDownloading, backend: ZcashRustBackendWelding.Type, config: Configuration, service: LightWalletService) { init(downloader: CompactBlockDownloading, backend: ZcashRustBackendWelding.Type, config: Configuration, service: LightWalletService) {
@ -91,7 +86,6 @@ class CompactBlockProcessor {
} }
deinit { deinit {
self.queue.suspend() self.queue.suspend()
self.unsuscribeToSystemNotifications() self.unsuscribeToSystemNotifications()
@ -180,14 +174,12 @@ class CompactBlockProcessor {
self.processNewBlocks(latestHeight: latestBlockHeight, latestDownloadedHeight: latestDownloadedBlockHeight) self.processNewBlocks(latestHeight: latestBlockHeight, latestDownloadedHeight: latestDownloadedBlockHeight)
} }
} }
func processNewBlocks(latestHeight: BlockHeight, latestDownloadedHeight: BlockHeight) { func processNewBlocks(latestHeight: BlockHeight, latestDownloadedHeight: BlockHeight) {
let dispatchGroup = DispatchGroup() let dispatchGroup = DispatchGroup()
let validateBlocksTask = DispatchWorkItem { let validateBlocksTask = DispatchWorkItem {
dispatchGroup.enter() dispatchGroup.enter()
self.state = .scanning self.state = .scanning
@ -252,7 +244,6 @@ class CompactBlockProcessor {
self.state = .stopped self.state = .stopped
} }
func fail(_ error: Error) { func fail(_ error: Error) {
// todo specify: failure // todo specify: failure
print(error.localizedDescription) print(error.localizedDescription)
@ -264,7 +255,6 @@ class CompactBlockProcessor {
} }
extension CompactBlockProcessor.Configuration { extension CompactBlockProcessor.Configuration {
static var standard: CompactBlockProcessor.Configuration { static var standard: CompactBlockProcessor.Configuration {

View File

@ -8,7 +8,6 @@
import Foundation import Foundation
protocol BlockRepository { protocol BlockRepository {
func lastScannedBlockHeight() -> BlockHeight func lastScannedBlockHeight() -> BlockHeight
} }

View File

@ -33,7 +33,7 @@ protocol CompactBlockStoring {
/** /**
Write the given blocks to this store, which may be anything from an in-memory cache to a DB. Write the given blocks to this store, which may be anything from an in-memory cache to a DB.
*/ */
func write(blocks: [ZcashCompactBlock]) throws -> Void func write(blocks: [ZcashCompactBlock]) throws
/** /**
Write the given blocks to this store, which may be anything from an in-memory cache to a DB. Write the given blocks to this store, which may be anything from an in-memory cache to a DB.
@ -49,7 +49,7 @@ protocol CompactBlockStoring {
Meaning, if max height is 100 block and rewindTo(50) is called, then the highest block remaining will be 49. Meaning, if max height is 100 block and rewindTo(50) is called, then the highest block remaining will be 49.
*/ */
func rewind(to height: BlockHeight) throws -> Void func rewind(to height: BlockHeight) throws
/** /**
Remove every block above and including the given height. Remove every block above and including the given height.
@ -60,4 +60,3 @@ protocol CompactBlockStoring {
*/ */
func rewind(to height: BlockHeight, completion: ((Error?) -> Void)?) func rewind(to height: BlockHeight, completion: ((Error?) -> Void)?)
} }

View File

@ -8,7 +8,6 @@
import Foundation import Foundation
protocol Storage { protocol Storage {
func createDatabase(at path: String) throws func createDatabase(at path: String) throws
@ -24,5 +23,3 @@ enum StorageError: Error {
case closeFailed case closeFailed
case operationFailed case operationFailed
} }

View File

@ -18,7 +18,6 @@ public protocol ResourceProvider {
} }
public struct DefaultResourceProvider: ResourceProvider { public struct DefaultResourceProvider: ResourceProvider {
public var dataDbPath: String { public var dataDbPath: String {

View File

@ -24,7 +24,7 @@ class ZcashRustBackend: ZcashRustBackendWelding {
let error = UnsafeMutablePointer<Int8>.allocate(capacity: Int(errorLen)) let error = UnsafeMutablePointer<Int8>.allocate(capacity: Int(errorLen))
zcashlc_error_message_utf8(error, errorLen) zcashlc_error_message_utf8(error, errorLen)
zcashlc_clear_last_error() zcashlc_clear_last_error()
return String(validatingUTF8: error)! return String(validatingUTF8: error)
} else { } else {
return nil return nil
} }
@ -45,9 +45,10 @@ class ZcashRustBackend: ZcashRustBackendWelding {
return nil return nil
} }
let extsks = UnsafeBufferPointer(start: extsksCStr, count: Int(accounts)).map { let extsks = UnsafeBufferPointer(start: extsksCStr, count: Int(accounts)).compactMap({ (cStr) -> String? in
String(cString: $0!) guard let str = cStr else { return nil }
} return String(cString: str)
})
zcashlc_vec_string_free(extsksCStr, UInt(accounts)) zcashlc_vec_string_free(extsksCStr, UInt(accounts))
return extsks return extsks
} }
@ -60,12 +61,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
static func getAddress(dbData: URL, account: Int32) -> String? { static func getAddress(dbData: URL, account: Int32) -> String? {
let dbData = dbData.osStr() let dbData = dbData.osStr()
let addressCStr = zcashlc_get_address(dbData.0, dbData.1, account) guard let addressCStr = zcashlc_get_address(dbData.0, dbData.1, account) else { return nil }
if addressCStr == nil {
return nil
}
let address = String(validatingUTF8: addressCStr!) let address = String(validatingUTF8: addressCStr)
zcashlc_string_free(addressCStr) zcashlc_string_free(addressCStr)
return address return address
} }
@ -83,12 +81,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64) -> String? { static func getReceivedMemoAsUTF8(dbData: URL, idNote: Int64) -> String? {
let dbData = dbData.osStr() let dbData = dbData.osStr()
let memoCStr = zcashlc_get_received_memo_as_utf8(dbData.0, dbData.1, idNote) guard let memoCStr = zcashlc_get_received_memo_as_utf8(dbData.0, dbData.1, idNote) else { return nil }
if memoCStr == nil {
return nil let memo = String(validatingUTF8: memoCStr)
}
let memo = String(validatingUTF8: memoCStr!)
zcashlc_string_free(memoCStr) zcashlc_string_free(memoCStr)
return memo return memo
} }
@ -96,12 +91,9 @@ class ZcashRustBackend: ZcashRustBackendWelding {
static func getSentMemoAsUTF8(dbData: URL, idNote: Int64) -> String? { static func getSentMemoAsUTF8(dbData: URL, idNote: Int64) -> String? {
let dbData = dbData.osStr() let dbData = dbData.osStr()
let memoCStr = zcashlc_get_sent_memo_as_utf8(dbData.0, dbData.1, idNote) guard let memoCStr = zcashlc_get_sent_memo_as_utf8(dbData.0, dbData.1, idNote) else { return nil }
if memoCStr == nil {
return nil
}
let memo = String(validatingUTF8: memoCStr!) let memo = String(validatingUTF8: memoCStr)
zcashlc_string_free(memoCStr) zcashlc_string_free(memoCStr)
return memo return memo
} }

View File

@ -21,7 +21,7 @@ class LightWalletGRPCService {
compactTxStreamer = CompactTxStreamerServiceClient(channel: self.channel) compactTxStreamer = CompactTxStreamerServiceClient(channel: self.channel)
} }
func blockRange(startHeight: BlockHeight, endHeight: BlockHeight? = nil, result: @escaping (CallResult)->()) throws -> CompactTxStreamerGetBlockRangeCall { func blockRange(startHeight: BlockHeight, endHeight: BlockHeight? = nil, result: @escaping (CallResult) -> Void) throws -> CompactTxStreamerGetBlockRangeCall {
try compactTxStreamer.getBlockRange(BlockRange(startHeight: startHeight, endHeight: endHeight)) { result($0) } try compactTxStreamer.getBlockRange(BlockRange(startHeight: startHeight, endHeight: endHeight)) { result($0) }
} }
@ -29,17 +29,16 @@ class LightWalletGRPCService {
try compactTxStreamer.getLatestBlock(ChainSpec()) try compactTxStreamer.getLatestBlock(ChainSpec())
} }
func getTx(hash:String) throws -> RawTransaction { func getTx(hash: String) throws -> RawTransaction {
var filter = TxFilter() var filter = TxFilter()
filter.hash = Data(hash.utf8) filter.hash = Data(hash.utf8)
return try compactTxStreamer.getTransaction(filter) return try compactTxStreamer.getTransaction(filter)
} }
func getAllBlocksSinceSaplingLaunch(_ result: @escaping (CallResult)->()) throws -> CompactTxStreamerGetBlockRangeCall { func getAllBlocksSinceSaplingLaunch(_ result: @escaping (CallResult) -> Void) throws -> CompactTxStreamerGetBlockRangeCall {
try compactTxStreamer.getBlockRange(BlockRange.sinceSaplingActivation(), completion: result) try compactTxStreamer.getBlockRange(BlockRange.sinceSaplingActivation(), completion: result)
} }
} }
extension LightWalletGRPCService: LightWalletService { extension LightWalletGRPCService: LightWalletService {
@ -63,9 +62,9 @@ extension LightWalletGRPCService: LightWalletService {
return blocks return blocks
} }
func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> ()) { func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
do { do {
try compactTxStreamer.getLatestBlock(ChainSpec()) { (blockID, callResult) in try compactTxStreamer.getLatestBlock(ChainSpec()) { (blockID, _) in
guard let rawHeight = blockID?.height, let blockHeight = Int(exactly: rawHeight) else { guard let rawHeight = blockID?.height, let blockHeight = Int(exactly: rawHeight) else {
result(.failure(LightWalletServiceError.generalError)) result(.failure(LightWalletServiceError.generalError))
return return
@ -82,7 +81,6 @@ extension LightWalletGRPCService: LightWalletService {
// TODO: Make cancellable // TODO: Make cancellable
func blockRange(_ range: CompactBlockRange, result: @escaping (Result<[ZcashCompactBlock], LightWalletServiceError>) -> Void) { func blockRange(_ range: CompactBlockRange, result: @escaping (Result<[ZcashCompactBlock], LightWalletServiceError>) -> Void) {
queue.async { queue.async {
var blocks = [CompactBlock]() var blocks = [CompactBlock]()
var isSyncing = true var isSyncing = true
@ -101,7 +99,6 @@ extension LightWalletGRPCService: LightWalletService {
result(.failure(LightWalletServiceError.failed(statusCode: code))) result(.failure(LightWalletServiceError.failed(statusCode: code)))
} }
} else { } else {
result(.failure(LightWalletServiceError.generalError)) result(.failure(LightWalletServiceError.generalError))
return return
@ -129,7 +126,7 @@ extension LightWalletGRPCService: LightWalletService {
func latestBlockHeight() throws -> BlockHeight { func latestBlockHeight() throws -> BlockHeight {
guard let height = try? latestBlock().compactBlockHeight() else { guard let height = try? latestBlock().compactBlockHeight() else {
throw LightWalletServiceError.invalidBlock throw LightWalletServiceError.invalidBlock
} }
return height return height

View File

@ -51,8 +51,7 @@ public protocol LightWalletService {
- Parameter result: a result containing the height or an Error - Parameter result: a result containing the height or an Error
*/ */
func latestBlockHeight(result: @escaping (Result<BlockHeight,LightWalletServiceError>) -> ()) func latestBlockHeight(result: @escaping (Result<BlockHeight,LightWalletServiceError>) -> Void)
/** /**
Return the latest block height known to the service. Return the latest block height known to the service.
@ -81,5 +80,3 @@ public protocol LightWalletService {
func blockRange(_ range: CompactBlockRange) throws -> [ZcashCompactBlock] func blockRange(_ range: CompactBlockRange) throws -> [ZcashCompactBlock]
} }

View File

@ -11,8 +11,6 @@ import Foundation
public typealias BlockHeight = Int public typealias BlockHeight = Int
public typealias CompactBlockRange = Range<BlockHeight> public typealias CompactBlockRange = Range<BlockHeight>
enum ZcashCompactBlockError: Error { enum ZcashCompactBlockError: Error {
case unreadableBlock(compactBlock: CompactBlock) case unreadableBlock(compactBlock: CompactBlock)
} }
@ -52,5 +50,3 @@ extension ZcashCompactBlock: Hashable {
hasher.combine(data) hasher.combine(data)
} }
} }

View File

@ -14,7 +14,6 @@ extension CompactBlockRange {
} }
} }
extension BlockID { extension BlockID {
static let saplingActivationHeight: UInt64 = 280_000 static let saplingActivationHeight: UInt64 = 280_000
@ -41,7 +40,7 @@ extension BlockRange {
init(startHeight: Int, endHeight: Int? = nil) { init(startHeight: Int, endHeight: Int? = nil) {
self = BlockRange() self = BlockRange()
self.start = BlockID(height: UInt64(startHeight)) self.start = BlockID(height: UInt64(startHeight))
if let endHeight = endHeight { if let endHeight = endHeight {
self.end = BlockID(height: UInt64(endHeight)) self.end = BlockID(height: UInt64(endHeight))
} }
@ -59,7 +58,6 @@ extension BlockRange {
} }
extension Array where Element == CompactBlock { extension Array where Element == CompactBlock {
func asZcashCompactBlocks() throws -> [ZcashCompactBlock] { func asZcashCompactBlocks() throws -> [ZcashCompactBlock] {
var result = [ZcashCompactBlock]() var result = [ZcashCompactBlock]()

View File

@ -12,7 +12,6 @@ import Foundation
capabilities and the supporting data required to exercise those abilities. capabilities and the supporting data required to exercise those abilities.
*/ */
public enum WalletError: Error { public enum WalletError: Error {
case cacheDbInitFailed case cacheDbInitFailed
case dataDbInitFailed case dataDbInitFailed
@ -29,7 +28,7 @@ public class Wallet {
private var walletBirthday: WalletBirthday private var walletBirthday: WalletBirthday
private var storage: Storage? private var storage: Storage?
init(rustWelding: ZcashRustBackendWelding.Type, cacheDbURL:URL, dataDbURL: URL, paramDestination: URL, seedProvider: SeedProvider, walletBirthday: WalletBirthday, accountIDs: [Int] = [0]) { init(rustWelding: ZcashRustBackendWelding.Type, cacheDbURL: URL, dataDbURL: URL, paramDestination: URL, seedProvider: SeedProvider, walletBirthday: WalletBirthday, accountIDs: [Int] = [0]) {
self.rustBackend = rustWelding.self self.rustBackend = rustWelding.self
self.dataDbURL = dataDbURL self.dataDbURL = dataDbURL
@ -41,8 +40,7 @@ public class Wallet {
} }
public func initalize(firstRunStartHeight: BlockHeight = SAPLING_ACTIVATION_HEIGHT) throws {
public func initalize(firstRunStartHeight: BlockHeight = SAPLING_ACTIVATION_HEIGHT) throws {
guard let storage = StorageBuilder.cacheDb(at: cacheDbURL) else { guard let storage = StorageBuilder.cacheDb(at: cacheDbURL) else {
throw WalletError.cacheDbInitFailed throw WalletError.cacheDbInitFailed
@ -54,7 +52,6 @@ public class Wallet {
self.storage = storage self.storage = storage
} }
public func latestBlockHeight() -> Int? { public func latestBlockHeight() -> Int? {
@ -62,27 +59,25 @@ public class Wallet {
} }
} }
/** /**
Represents the wallet's birthday which can be thought of as a checkpoint at the earliest moment in history where Represents the wallet's birthday which can be thought of as a checkpoint at the earliest moment in history where
transactions related to this wallet could exist. Ideally, this would correspond to the latest block height at the transactions related to this wallet could exist. Ideally, this would correspond to the latest block height at the
time the wallet key was created. Worst case, the height of Sapling activation could be used (280000). time the wallet key was created. Worst case, the height of Sapling activation could be used (280000).
Knowing a wallet's birthday can significantly reduce the amount of data that it needs to download because none of Knowing a wallet's birthday can significantly reduce the amount of data that it needs to download because none of
the data before that height needs to be scanned for transactions. However, we do need the Sapling tree data in the data before that height needs to be scanned for transactions. However, we do need the Sapling tree data in
order to construct valid transactions from that point forward. This birthday contains that tree data, allowing us order to construct valid transactions from that point forward. This birthday contains that tree data, allowing us
to avoid downloading all the compact blocks required in order to generate it. to avoid downloading all the compact blocks required in order to generate it.
New wallets can ignore any blocks created before their birthday. New wallets can ignore any blocks created before their birthday.
- Parameter height the height at the time the wallet was born - Parameter height the height at the time the wallet was born
- Parameter hash the block hash corresponding to the given height - Parameter hash the block hash corresponding to the given height
- Parameter time the time the wallet was born, in seconds - Parameter time the time the wallet was born, in seconds
- Parameter tree the sapling tree corresponding to the given height. This takes around 15 minutes of processing to - Parameter tree the sapling tree corresponding to the given height. This takes around 15 minutes of processing to
generate from scratch because all blocks since activation need to be considered. So when it is calculated in generate from scratch because all blocks since activation need to be considered. So when it is calculated in
advance it can save the user a lot of time. advance it can save the user a lot of time.
*/ */
public struct WalletBirthday { public struct WalletBirthday {
var height: BlockHeight = -1 var height: BlockHeight = -1
var hash: String = "" var hash: String = ""

View File

@ -15,7 +15,7 @@ class BlockDownloaderTests: XCTestCase {
var storage: CompactBlockStoring! var storage: CompactBlockStoring!
override func setUp() { override func setUp() {
service = LightWalletGRPCService(channel: ChannelProvider().channel()) service = LightWalletGRPCService(channel: ChannelProvider().channel())
storage = try! TestDbBuilder.inMemoryCompactBlockStorage() storage = try! TestDbBuilder.inMemoryCompactBlockStorage()
downloader = CompactBlockDownloader(service: service, storage: storage) downloader = CompactBlockDownloader(service: service, storage: storage)
} }
@ -26,7 +26,6 @@ class BlockDownloaderTests: XCTestCase {
downloader = nil downloader = nil
} }
func testSmallDownloadAsync() { func testSmallDownloadAsync() {
let expect = XCTestExpectation(description: self.description) let expect = XCTestExpectation(description: self.description)
@ -55,17 +54,14 @@ class BlockDownloaderTests: XCTestCase {
wait(for: [expect], timeout: 2) wait(for: [expect], timeout: 2)
} }
func testSmallDownload() { func testSmallDownload() {
let lowerRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT let lowerRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT
let upperRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT + 99 let upperRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT + 99
let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange)) let range = CompactBlockRange(uncheckedBounds: (lowerRange,upperRange))
var latest: BlockHeight = 0 var latest: BlockHeight = 0
do { do {
latest = try downloader.latestBlockHeight() latest = try downloader.latestBlockHeight()
} catch { } catch {
@ -105,7 +101,6 @@ class BlockDownloaderTests: XCTestCase {
} }
} }
/// Helper functions /// Helper functions
extension BlockDownloaderTests { extension BlockDownloaderTests {

View File

@ -28,7 +28,7 @@ class BlockScanOperationTests: XCTestCase {
operationQueue.cancelAllOperations() operationQueue.cancelAllOperations()
// try! FileManager.default.removeItem(at: cacheDbURL) // try! FileManager.default.removeItem(at: cacheDbURL)
try! FileManager.default.removeItem(at: dataDbURL) try? FileManager.default.removeItem(at: dataDbURL)
} }
func testSingleDownloadAndScanOperation() { func testSingleDownloadAndScanOperation() {

View File

@ -20,8 +20,6 @@ class CompactBlockProcessorTests: XCTestCase {
XCTAssertTrue(MockDbInit.emptyFile(at: processorConfig.cacheDbPath)) XCTAssertTrue(MockDbInit.emptyFile(at: processorConfig.cacheDbPath))
XCTAssertTrue(MockDbInit.emptyFile(at: processorConfig.dataDbPath)) XCTAssertTrue(MockDbInit.emptyFile(at: processorConfig.dataDbPath))
let service = LightWalletGRPCService(channel: ChannelProvider().channel()) let service = LightWalletGRPCService(channel: ChannelProvider().channel())
let storage = ZcashConsoleFakeStorage() let storage = ZcashConsoleFakeStorage()
let downloader = CompactBlockDownloader(service: service, storage: storage) let downloader = CompactBlockDownloader(service: service, storage: storage)
@ -43,13 +41,10 @@ class CompactBlockProcessorTests: XCTestCase {
expect.unsuscribeFromNotifications() expect.unsuscribeFromNotifications()
} }
func testStartNotifiesSuscriptors() { func testStartNotifiesSuscriptors() {
XCTAssertNotNil(processor) XCTAssertNotNil(processor)
expect.suscribe(to: Notification.Name.blockProcessorStarted, object: processor) expect.suscribe(to: Notification.Name.blockProcessorStarted, object: processor)

View File

@ -11,7 +11,6 @@ import XCTest
@testable import ZcashLightClientKit @testable import ZcashLightClientKit
class CompactBlockStorageTests: XCTestCase { class CompactBlockStorageTests: XCTestCase {
var storage: Storage = try! TestDbBuilder.inMemory() var storage: Storage = try! TestDbBuilder.inMemory()
func testEmptyStorage() { func testEmptyStorage() {
@ -61,7 +60,6 @@ class CompactBlockStorageTests: XCTestCase {
} }
} }
func testRewindTo() { func testRewindTo() {
let startHeight = SAPLING_ACTIVATION_HEIGHT let startHeight = SAPLING_ACTIVATION_HEIGHT

View File

@ -12,7 +12,6 @@ import SQLite
class DownloadOperationTests: XCTestCase { class DownloadOperationTests: XCTestCase {
var operationQueue = OperationQueue() var operationQueue = OperationQueue()
override func tearDown() { override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class. // Put teardown code here. This method is called after the invocation of each test method in the class.

View File

@ -59,7 +59,6 @@ class LightWalletServiceTests: XCTestCase {
wait(for: [expect], timeout: 5) wait(for: [expect], timeout: 5)
} }
func testSyncBlockRange() { func testSyncBlockRange() {
let lowerRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT let lowerRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT
let upperRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT + 99 let upperRange: BlockHeight = SAPLING_ACTIVATION_HEIGHT + 99

View File

@ -62,7 +62,6 @@ class ZcashLightClientKitTests: XCTestCase {
func testBlockRangeServiceTilLastest() { func testBlockRangeServiceTilLastest() {
let expectedCount: BlockHeight = 99 let expectedCount: BlockHeight = 99
var count: BlockHeight = 0 var count: BlockHeight = 0
let startHeight = latestBlockHeight - expectedCount let startHeight = latestBlockHeight - expectedCount
let endHeight = latestBlockHeight! let endHeight = latestBlockHeight!
@ -75,7 +74,6 @@ class ZcashLightClientKitTests: XCTestCase {
XCTFail("failed to create getBlockRange( \(startHeight) ..<= \(endHeight)") XCTFail("failed to create getBlockRange( \(startHeight) ..<= \(endHeight)")
return return
} }
var blocks = [CompactBlock]() var blocks = [CompactBlock]()
while true { while true {

View File

@ -60,6 +60,5 @@ class ZcashRustBackendTests: XCTestCase {
XCTAssertTrue(ZcashRustBackend.scanBlocks(dbCache: cacheDb, dbData: dbData)) XCTAssertTrue(ZcashRustBackend.scanBlocks(dbCache: cacheDb, dbData: dbData))
} }
} }

View File

@ -22,7 +22,6 @@ class ZcashConsoleFakeStorage: CompactBlockStoring {
fakeRewind(to: height) fakeRewind(to: height)
} }
var latestBlockHeight: BlockHeight = 0 var latestBlockHeight: BlockHeight = 0
var delay = DispatchTimeInterval.milliseconds(300) var delay = DispatchTimeInterval.milliseconds(300)
@ -62,6 +61,4 @@ class ZcashConsoleFakeStorage: CompactBlockStoring {
self.latestBlockHeight = min(self.latestBlockHeight, height) self.latestBlockHeight = min(self.latestBlockHeight, height)
} }
} }

View File

@ -18,7 +18,7 @@ class AwfulLightWalletService: LightWalletService {
throw LightWalletServiceError.invalidBlock throw LightWalletServiceError.invalidBlock
} }
func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> ()) { func latestBlockHeight(result: @escaping (Result<BlockHeight, LightWalletServiceError>) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
result(.failure(LightWalletServiceError.generalError)) result(.failure(LightWalletServiceError.generalError))
} }
@ -31,5 +31,4 @@ class AwfulLightWalletService: LightWalletService {
} }
} }
} }

View File

@ -33,14 +33,13 @@ struct TestDbBuilder {
return compactBlockDao return compactBlockDao
} }
static func diskCompactBlockStorage(at url:URL) throws -> CompactBlockStorage { static func diskCompactBlockStorage(at url: URL) throws -> CompactBlockStorage {
let connection = try Connection(url.absoluteString) let connection = try Connection(url.absoluteString)
let compactBlockDao = CompactBlockStorage(connection: connection) let compactBlockDao = CompactBlockStorage(connection: connection)
try compactBlockDao.createTable() try compactBlockDao.createTable()
return compactBlockDao return compactBlockDao
} }
static func seed(db: Storage, with blockRange: CompactBlockRange) throws { static func seed(db: Storage, with blockRange: CompactBlockRange) throws {
guard let blocks = StubBlockCreator.createBlockRange(blockRange) else { guard let blocks = StubBlockCreator.createBlockRange(blockRange) else {

View File

@ -16,14 +16,11 @@ class ChannelProvider {
} }
} }
struct MockDbInit { struct MockDbInit {
@discardableResult static func emptyFile(at path: String) -> Bool { @discardableResult static func emptyFile(at path: String) -> Bool {
FileManager.default.createFile(atPath: path, contents: Data("".utf8), attributes: nil) FileManager.default.createFile(atPath: path, contents: Data("".utf8), attributes: nil)
} }
static func destroy(at path: String) throws { static func destroy(at path: String) throws {
@ -46,7 +43,6 @@ extension XCTestExpectation {
} }
} }
func __documentsDirectory() throws -> URL { func __documentsDirectory() throws -> URL {
try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
} }

8
zcash.swiftformat Normal file
View File

@ -0,0 +1,8 @@
# options
--self remove # redundantSelf
--importgrouping testable-bottom # sortedImports
--commas always # trailingCommas
--trimwhitespace always # trailingSpace
# rules
--rules redundantParens,redundantSelf,sortedImports,trailingCommas,trailingSpace