react-native-zcash 0.6.9 → 0.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2440000.json +8 -0
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2450000.json +8 -0
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2460000.json +8 -0
- package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +937 -425
- package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +17 -31
- package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +2 -2
- package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +15 -46
- package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +15 -4
- package/ios/ZCashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift +4 -4
- package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +35 -10
- package/ios/ZCashLightClientKit/Block/Utils/InternalSyncProgress.swift +200 -0
- package/ios/ZCashLightClientKit/Block/Validate/BlockValidator.swift +51 -0
- package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +2 -1
- package/ios/ZCashLightClientKit/CombineSynchronizer.swift +5 -2
- package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +26 -13
- package/ios/ZCashLightClientKit/DAO/BlockDao.swift +112 -0
- package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +42 -40
- package/ios/ZCashLightClientKit/DAO/UnspentTransactionOutputDao.swift +4 -13
- package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +0 -9
- package/ios/ZCashLightClientKit/Entity/BlockProgress.swift +24 -0
- package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +10 -7
- package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
- package/ios/ZCashLightClientKit/Error/ZcashError.swift +12 -121
- package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +5 -43
- package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +6 -72
- package/ios/ZCashLightClientKit/Initializer.swift +26 -47
- package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +12 -0
- package/ios/ZCashLightClientKit/Model/Checkpoint.swift +0 -12
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +0 -15
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/compact_formats.pb.swift +46 -150
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/compact_formats.proto +16 -30
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/service.proto +6 -32
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.grpc.swift +22 -259
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.pb.swift +7 -193
- package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +0 -8
- package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +28 -18
- package/ios/ZCashLightClientKit/Repository/CompactBlockRepository.swift +1 -1
- package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +6 -2
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2440000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2450000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2460000.json +8 -0
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +158 -293
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +64 -58
- package/ios/ZCashLightClientKit/Rust/zcashlc.h +513 -619
- package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +8 -2
- package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +15 -3
- package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +30 -11
- package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +50 -41
- package/ios/ZCashLightClientKit/Synchronizer.swift +65 -51
- package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +2 -2
- package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +7 -7
- package/ios/ZCashLightClientKit/Utils/OSLogger.swift +3 -3
- package/ios/libzcashlc.xcframework/Info.plist +0 -4
- package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
- package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
- package/package.json +1 -1
- package/ios/ZCashLightClientKit/Block/Actions/Action.swift +0 -98
- package/ios/ZCashLightClientKit/Block/Actions/ClearAlreadyScannedBlocksAction.swift +0 -35
- package/ios/ZCashLightClientKit/Block/Actions/ClearCacheAction.swift +0 -30
- package/ios/ZCashLightClientKit/Block/Actions/DownloadAction.swift +0 -67
- package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +0 -97
- package/ios/ZCashLightClientKit/Block/Actions/FetchUTXOsAction.swift +0 -33
- package/ios/ZCashLightClientKit/Block/Actions/MigrateLegacyCacheDBAction.swift +0 -70
- package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +0 -60
- package/ios/ZCashLightClientKit/Block/Actions/RewindAction.swift +0 -48
- package/ios/ZCashLightClientKit/Block/Actions/SaplingParamsAction.swift +0 -33
- package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +0 -95
- package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +0 -55
- package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +0 -58
- package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +0 -60
- package/ios/ZCashLightClientKit/Block/Utils/CompactBlockProgress.swift +0 -24
- package/ios/ZCashLightClientKit/Block/Utils/SyncControlData.swift +0 -25
- package/ios/ZCashLightClientKit/Extensions/Bool+ToData.swift +0 -15
- package/ios/ZCashLightClientKit/Extensions/Data+ToOtherTypes.swift +0 -18
- package/ios/ZCashLightClientKit/Extensions/Int+ToData.swift +0 -15
- package/ios/ZCashLightClientKit/Model/ScanProgress.swift +0 -29
- package/ios/ZCashLightClientKit/Model/ScanRange.swift +0 -31
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2092500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2095000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2097500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2102500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2105000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2107500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2112500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2115000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2117500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2122500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2125000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2127500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2132500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2135000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2137500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2142500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2145000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2147500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2152500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2155000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2157500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2162500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2165000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2167500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2172500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2175000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2177500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2182500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2185000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2187500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2192500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2195000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2197500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2202500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2205000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2207500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2212500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2215000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2217500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2222500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2225000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2227500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2232500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2235000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2237500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2242500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2245000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2247500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2252500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2255000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2257500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2262500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2265000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2267500.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2350000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2360000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2370000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2380000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2390000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2400000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2410000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2420000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2430000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2440000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2450000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2460000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2470000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2480000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2490000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2500000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2510000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2520000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2530000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2540000.json +0 -8
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2550000.json +0 -8
- package/ios/ZCashLightClientKit/Utils/ZcashFileManager.swift +0 -16
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//
|
|
2
|
+
// CompactBlockValidationInformation.swift
|
|
3
|
+
// ZcashLightClientKit
|
|
4
|
+
//
|
|
5
|
+
// Created by Francisco Gindre on 10/30/19.
|
|
6
|
+
// Copyright © 2019 Electric Coin Company. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
protocol BlockValidator {
|
|
12
|
+
/// Validate all the downloaded blocks that haven't been yet validated.
|
|
13
|
+
func validate() async throws
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
struct BlockValidatorImpl {
|
|
17
|
+
let rustBackend: ZcashRustBackendWelding
|
|
18
|
+
let metrics: SDKMetrics
|
|
19
|
+
let logger: Logger
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
extension BlockValidatorImpl: BlockValidator {
|
|
23
|
+
/// - Throws:
|
|
24
|
+
/// - `rustValidateCombinedChainValidationFailed` if there was an error during validation unrelated to chain validity.
|
|
25
|
+
/// - `rustValidateCombinedChainInvalidChain(upperBound)` if the combined chain is invalid. `upperBound` is the height of the highest invalid
|
|
26
|
+
/// block(on the assumption that the highest block in the cache database is correct).
|
|
27
|
+
func validate() async throws {
|
|
28
|
+
try Task.checkCancellation()
|
|
29
|
+
|
|
30
|
+
let startTime = Date()
|
|
31
|
+
do {
|
|
32
|
+
try await rustBackend.validateCombinedChain(limit: 0)
|
|
33
|
+
pushProgressReport(startTime: startTime, finishTime: Date())
|
|
34
|
+
logger.debug("validateChainFinished")
|
|
35
|
+
} catch {
|
|
36
|
+
logger.debug("Validate chain failed with \(error)")
|
|
37
|
+
pushProgressReport(startTime: startTime, finishTime: Date())
|
|
38
|
+
throw error
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private func pushProgressReport(startTime: Date, finishTime: Date) {
|
|
43
|
+
metrics.pushProgressReport(
|
|
44
|
+
progress: BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0),
|
|
45
|
+
start: startTime,
|
|
46
|
+
end: finishTime,
|
|
47
|
+
batchSize: 0,
|
|
48
|
+
operation: .validateBlocks
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -24,8 +24,8 @@ public protocol ClosureSynchronizer {
|
|
|
24
24
|
|
|
25
25
|
func prepare(
|
|
26
26
|
with seed: [UInt8]?,
|
|
27
|
+
viewingKeys: [UnifiedFullViewingKey],
|
|
27
28
|
walletBirthday: BlockHeight,
|
|
28
|
-
for walletMode: WalletInitMode,
|
|
29
29
|
completion: @escaping (Result<Initializer.InitializationResult, Error>) -> Void
|
|
30
30
|
)
|
|
31
31
|
|
|
@@ -51,6 +51,7 @@ public protocol ClosureSynchronizer {
|
|
|
51
51
|
completion: @escaping (Result<ZcashTransaction.Overview, Error>) -> Void
|
|
52
52
|
)
|
|
53
53
|
|
|
54
|
+
func pendingTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
|
|
54
55
|
func clearedTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
|
|
55
56
|
func sentTranscations(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
|
|
56
57
|
func receivedTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
|
|
@@ -24,8 +24,8 @@ public protocol CombineSynchronizer {
|
|
|
24
24
|
|
|
25
25
|
func prepare(
|
|
26
26
|
with seed: [UInt8]?,
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
viewingKeys: [UnifiedFullViewingKey],
|
|
28
|
+
walletBirthday: BlockHeight
|
|
29
29
|
) -> SinglePublisher<Initializer.InitializationResult, Error>
|
|
30
30
|
|
|
31
31
|
func start(retry: Bool) -> CompletablePublisher<Error>
|
|
@@ -49,6 +49,7 @@ public protocol CombineSynchronizer {
|
|
|
49
49
|
) -> SinglePublisher<ZcashTransaction.Overview, Error>
|
|
50
50
|
|
|
51
51
|
var allTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
|
|
52
|
+
var pendingTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
|
|
52
53
|
var sentTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
|
|
53
54
|
var receivedTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
|
|
54
55
|
|
|
@@ -58,6 +59,8 @@ public protocol CombineSynchronizer {
|
|
|
58
59
|
|
|
59
60
|
func getRecipients(for transaction: ZcashTransaction.Overview) -> SinglePublisher<[TransactionRecipient], Never>
|
|
60
61
|
|
|
62
|
+
func allPendingTransactions() -> SinglePublisher<[ZcashTransaction.Overview], Error>
|
|
63
|
+
|
|
61
64
|
func allTransactions(from transaction: ZcashTransaction.Overview, limit: Int) -> SinglePublisher<[ZcashTransaction.Overview], Error>
|
|
62
65
|
|
|
63
66
|
func latestHeight() -> SinglePublisher<BlockHeight, Error>
|
|
@@ -88,22 +88,24 @@ public enum ZcashSDK {
|
|
|
88
88
|
// MARK: Defaults
|
|
89
89
|
|
|
90
90
|
/// Default size of batches of blocks to request from the compact block service. Which was used both for scanning and downloading.
|
|
91
|
+
/// consider basing your code assumptions on `DefaultDownloadBatch` and `DefaultScanningBatch` instead.
|
|
92
|
+
@available(*, deprecated, message: "this value is being deprecated in favor of `DefaultDownloadBatch` and `DefaultScanningBatch`")
|
|
91
93
|
public static let DefaultBatchSize = 100
|
|
92
|
-
|
|
93
|
-
/// Default batch size for
|
|
94
|
-
|
|
94
|
+
|
|
95
|
+
/// Default batch size for downloading blocks for the compact block processor. Be careful with this number. This amount of blocks is held in
|
|
96
|
+
/// memory at some point of the sync process.
|
|
97
|
+
/// This values can't be smaller than `DefaultScanningBatch`. Otherwise bad things will happen.
|
|
98
|
+
public static let DefaultDownloadBatch = 100
|
|
99
|
+
|
|
100
|
+
/// Default batch size for scanning blocks for the compact block processor
|
|
101
|
+
public static let DefaultScanningBatch = 100
|
|
95
102
|
|
|
96
103
|
/// Default amount of time, in in seconds, to poll for new blocks. Typically, this should be about half the average
|
|
97
104
|
/// block time.
|
|
98
105
|
public static let defaultPollInterval: TimeInterval = 20
|
|
99
106
|
|
|
100
107
|
/// Default attempts at retrying.
|
|
101
|
-
|
|
102
|
-
// There are many places that rely on hasRetryAttempt() that reads and compares this value.
|
|
103
|
-
// Better solution is to think about retry logic and potentially either remove completely
|
|
104
|
-
// or implement more sophisticated solutuion. Until that time, Int.max solves our UX issues
|
|
105
|
-
// TODO: [#1304] smart retry logic, https://github.com/zcash/ZcashLightClientKit/issues/1304
|
|
106
|
-
public static let defaultRetries = Int.max
|
|
108
|
+
public static let defaultRetries: Int = 5
|
|
107
109
|
|
|
108
110
|
/// The default maximum amount of time to wait during retry backoff intervals. Failed loops will never wait longer than
|
|
109
111
|
/// this before retrying.
|
|
@@ -159,13 +161,19 @@ public protocol NetworkConstants {
|
|
|
159
161
|
/// Default prefix for db filenames
|
|
160
162
|
static var defaultDbNamePrefix: String { get }
|
|
161
163
|
|
|
162
|
-
///
|
|
163
|
-
|
|
164
|
+
/// fixed height where the SDK considers that the ZIP-321 was deployed. This is a workaround
|
|
165
|
+
/// for librustzcash not figuring out the tx fee from the tx itself.
|
|
166
|
+
static var feeChangeHeight: BlockHeight { get }
|
|
167
|
+
|
|
168
|
+
/// Returns the default fee according to the blockheight. see [ZIP-313](https://zips.z.cash/zip-0313)
|
|
169
|
+
static func defaultFee(for height: BlockHeight) -> Zatoshi
|
|
164
170
|
}
|
|
165
171
|
|
|
166
172
|
public extension NetworkConstants {
|
|
167
|
-
static func defaultFee() -> Zatoshi {
|
|
168
|
-
Zatoshi(10_000)
|
|
173
|
+
static func defaultFee(for height: BlockHeight = BlockHeight.max) -> Zatoshi {
|
|
174
|
+
guard height >= feeChangeHeight else { return Zatoshi(10_000) }
|
|
175
|
+
|
|
176
|
+
return Zatoshi(1_000)
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
|
|
@@ -183,6 +191,8 @@ public enum ZcashSDKMainnetConstants: NetworkConstants {
|
|
|
183
191
|
public static let defaultCacheDbName = "caches.db"
|
|
184
192
|
|
|
185
193
|
public static let defaultDbNamePrefix = "ZcashSdk_mainnet_"
|
|
194
|
+
|
|
195
|
+
public static let feeChangeHeight: BlockHeight = 1_077_550
|
|
186
196
|
}
|
|
187
197
|
|
|
188
198
|
public enum ZcashSDKTestnetConstants: NetworkConstants {
|
|
@@ -199,4 +209,7 @@ public enum ZcashSDKTestnetConstants: NetworkConstants {
|
|
|
199
209
|
public static let defaultFsBlockDbRootName = "fs_cache"
|
|
200
210
|
|
|
201
211
|
public static let defaultDbNamePrefix = "ZcashSdk_testnet_"
|
|
212
|
+
|
|
213
|
+
/// Estimated height where wallets are supposed to change the fee
|
|
214
|
+
public static let feeChangeHeight: BlockHeight = 1_028_500
|
|
202
215
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BlockDao.swift
|
|
3
|
+
// ZcashLightClientKit
|
|
4
|
+
//
|
|
5
|
+
// Created by Francisco Gindre on 10/16/19.
|
|
6
|
+
// Copyright © 2019 Electric Coin Company. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
import SQLite
|
|
11
|
+
|
|
12
|
+
protocol BlockDao {
|
|
13
|
+
func latestBlockHeight() throws -> BlockHeight
|
|
14
|
+
func latestBlock() throws -> Block?
|
|
15
|
+
func block(at height: BlockHeight) throws -> Block?
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
struct Block: Codable {
|
|
19
|
+
enum CodingKeys: String, CodingKey {
|
|
20
|
+
case height
|
|
21
|
+
case hash
|
|
22
|
+
case time
|
|
23
|
+
case saplingTree = "sapling_tree"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
enum TableStructure {
|
|
27
|
+
static let height = Expression<Int>(Block.CodingKeys.height.rawValue)
|
|
28
|
+
static let hash = Expression<Blob>(Block.CodingKeys.hash.rawValue)
|
|
29
|
+
static let time = Expression<Int>(Block.CodingKeys.time.rawValue)
|
|
30
|
+
static let saplingTree = Expression<Blob>(Block.CodingKeys.saplingTree.rawValue)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let height: BlockHeight
|
|
34
|
+
let hash: Data
|
|
35
|
+
let time: Int
|
|
36
|
+
let saplingTree: Data
|
|
37
|
+
|
|
38
|
+
static let table = Table("blocks")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class BlockSQLDAO: BlockDao {
|
|
42
|
+
let dbProvider: ConnectionProvider
|
|
43
|
+
let table: Table
|
|
44
|
+
let height = Expression<Int>("height")
|
|
45
|
+
|
|
46
|
+
init(dbProvider: ConnectionProvider) {
|
|
47
|
+
self.dbProvider = dbProvider
|
|
48
|
+
self.table = Table("Blocks")
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// - Throws:
|
|
52
|
+
/// - `blockDAOCantDecode` if block data loaded from DB can't be decoded to `Block` object.
|
|
53
|
+
/// - `blockDAOBlock` if sqlite query to load block metadata failed.
|
|
54
|
+
func block(at height: BlockHeight) throws -> Block? {
|
|
55
|
+
do {
|
|
56
|
+
return try dbProvider
|
|
57
|
+
.connection()
|
|
58
|
+
.prepare(Block.table.filter(Block.TableStructure.height == height).limit(1))
|
|
59
|
+
.map {
|
|
60
|
+
do {
|
|
61
|
+
return try $0.decode()
|
|
62
|
+
} catch {
|
|
63
|
+
throw ZcashError.blockDAOCantDecode(error)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
.first
|
|
67
|
+
} catch {
|
|
68
|
+
if let error = error as? ZcashError {
|
|
69
|
+
throw error
|
|
70
|
+
} else {
|
|
71
|
+
throw ZcashError.blockDAOBlock(error)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// - Throws: `blockDAOLatestBlockHeight` if sqlite to fetch height fails.
|
|
77
|
+
func latestBlockHeight() throws -> BlockHeight {
|
|
78
|
+
do {
|
|
79
|
+
return try dbProvider.connection().scalar(table.select(height.max)) ?? BlockHeight.empty()
|
|
80
|
+
} catch {
|
|
81
|
+
throw ZcashError.blockDAOLatestBlockHeight(error)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func latestBlock() throws -> Block? {
|
|
86
|
+
do {
|
|
87
|
+
return try dbProvider
|
|
88
|
+
.connection()
|
|
89
|
+
.prepare(Block.table.order(height.desc).limit(1))
|
|
90
|
+
.map {
|
|
91
|
+
do {
|
|
92
|
+
return try $0.decode()
|
|
93
|
+
} catch {
|
|
94
|
+
throw ZcashError.blockDAOLatestBlockCantDecode(error)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
.first
|
|
98
|
+
} catch {
|
|
99
|
+
if let error = error as? ZcashError {
|
|
100
|
+
throw error
|
|
101
|
+
} else {
|
|
102
|
+
throw ZcashError.blockDAOLatestBlock(error)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
extension BlockSQLDAO: BlockRepository {
|
|
109
|
+
func lastScannedBlockHeight() -> BlockHeight {
|
|
110
|
+
(try? self.latestBlockHeight()) ?? BlockHeight.empty()
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -8,22 +8,6 @@
|
|
|
8
8
|
import Foundation
|
|
9
9
|
import SQLite
|
|
10
10
|
|
|
11
|
-
extension Connection {
|
|
12
|
-
public func scalarLocked<V: Value>(_ query: ScalarQuery<V?>) throws -> V.ValueType? {
|
|
13
|
-
globalDBLock.lock()
|
|
14
|
-
defer { globalDBLock.unlock() }
|
|
15
|
-
|
|
16
|
-
return try scalar(query)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public func scalarLocked<V: Value>(_ query: ScalarQuery<V>) throws -> V {
|
|
20
|
-
globalDBLock.lock()
|
|
21
|
-
defer { globalDBLock.unlock() }
|
|
22
|
-
|
|
23
|
-
return try scalar(query)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
11
|
class TransactionSQLDAO: TransactionRepository {
|
|
28
12
|
enum NotesTableStructure {
|
|
29
13
|
static let transactionID = Expression<Int>("tx")
|
|
@@ -32,12 +16,14 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
32
16
|
|
|
33
17
|
let dbProvider: ConnectionProvider
|
|
34
18
|
|
|
19
|
+
private let blockDao: BlockSQLDAO
|
|
35
20
|
private let transactionsView = View("v_transactions")
|
|
36
21
|
private let txOutputsView = View("v_tx_outputs")
|
|
37
22
|
private let traceClosure: ((String) -> Void)?
|
|
38
23
|
|
|
39
24
|
init(dbProvider: ConnectionProvider, traceClosure: ((String) -> Void)? = nil) {
|
|
40
25
|
self.dbProvider = dbProvider
|
|
26
|
+
self.blockDao = BlockSQLDAO(dbProvider: dbProvider)
|
|
41
27
|
self.traceClosure = traceClosure
|
|
42
28
|
}
|
|
43
29
|
|
|
@@ -51,13 +37,25 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
51
37
|
dbProvider.close()
|
|
52
38
|
}
|
|
53
39
|
|
|
40
|
+
func blockForHeight(_ height: BlockHeight) async throws -> Block? {
|
|
41
|
+
try blockDao.block(at: height)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func lastScannedHeight() async throws -> BlockHeight {
|
|
45
|
+
try blockDao.latestBlockHeight()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
func lastScannedBlock() async throws -> Block? {
|
|
49
|
+
try blockDao.latestBlock()
|
|
50
|
+
}
|
|
51
|
+
|
|
54
52
|
func isInitialized() async throws -> Bool {
|
|
55
53
|
true
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
func countAll() async throws -> Int {
|
|
59
57
|
do {
|
|
60
|
-
return try connection().
|
|
58
|
+
return try connection().scalar(transactionsView.count)
|
|
61
59
|
} catch {
|
|
62
60
|
throw ZcashError.transactionRepositoryCountAll(error)
|
|
63
61
|
}
|
|
@@ -65,12 +63,20 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
65
63
|
|
|
66
64
|
func countUnmined() async throws -> Int {
|
|
67
65
|
do {
|
|
68
|
-
return try connection().
|
|
66
|
+
return try connection().scalar(transactionsView.filter(ZcashTransaction.Overview.Column.minedHeight == nil).count)
|
|
69
67
|
} catch {
|
|
70
68
|
throw ZcashError.transactionRepositoryCountUnmined(error)
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
|
|
72
|
+
func find(id: Int) async throws -> ZcashTransaction.Overview {
|
|
73
|
+
let query = transactionsView
|
|
74
|
+
.filter(ZcashTransaction.Overview.Column.id == id)
|
|
75
|
+
.limit(1)
|
|
76
|
+
|
|
77
|
+
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
|
78
|
+
}
|
|
79
|
+
|
|
74
80
|
func find(rawID: Data) async throws -> ZcashTransaction.Overview {
|
|
75
81
|
let query = transactionsView
|
|
76
82
|
.filter(ZcashTransaction.Overview.Column.rawID == Blob(bytes: rawID.bytes))
|
|
@@ -81,7 +87,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
81
87
|
|
|
82
88
|
func find(offset: Int, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
|
|
83
89
|
let query = transactionsView
|
|
84
|
-
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
|
90
|
+
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc, ZcashTransaction.Overview.Column.id.desc)
|
|
85
91
|
.filterQueryFor(kind: kind)
|
|
86
92
|
.limit(limit, offset: offset)
|
|
87
93
|
|
|
@@ -90,7 +96,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
90
96
|
|
|
91
97
|
func find(in range: CompactBlockRange, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
|
|
92
98
|
let query = transactionsView
|
|
93
|
-
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
|
99
|
+
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc, ZcashTransaction.Overview.Column.id.desc)
|
|
94
100
|
.filter(
|
|
95
101
|
ZcashTransaction.Overview.Column.minedHeight >= BlockHeight(range.lowerBound) &&
|
|
96
102
|
ZcashTransaction.Overview.Column.minedHeight <= BlockHeight(range.upperBound)
|
|
@@ -103,18 +109,17 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
103
109
|
|
|
104
110
|
func find(from transaction: ZcashTransaction.Overview, limit: Int, kind: TransactionKind) async throws -> [ZcashTransaction.Overview] {
|
|
105
111
|
guard
|
|
106
|
-
let
|
|
112
|
+
let transactionIndex = transaction.index,
|
|
113
|
+
let transactionBlockTime = transaction.blockTime
|
|
107
114
|
else { throw ZcashError.transactionRepositoryTransactionMissingRequiredFields }
|
|
108
115
|
|
|
109
|
-
let transactionIndex = transaction.index ?? Int.max
|
|
110
116
|
let query = transactionsView
|
|
111
|
-
.order(
|
|
117
|
+
.order(
|
|
118
|
+
(ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc, ZcashTransaction.Overview.Column.id.desc
|
|
119
|
+
)
|
|
112
120
|
.filter(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
transactionBlockHeight == ZcashTransaction.Overview.Column.minedHeight &&
|
|
116
|
-
transactionIndex > (ZcashTransaction.Overview.Column.index ?? -1)
|
|
117
|
-
)
|
|
121
|
+
Int64(transactionBlockTime) > ZcashTransaction.Overview.Column.blockTime
|
|
122
|
+
&& transactionIndex > ZcashTransaction.Overview.Column.index
|
|
118
123
|
)
|
|
119
124
|
.filterQueryFor(kind: kind)
|
|
120
125
|
.limit(limit)
|
|
@@ -125,7 +130,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
125
130
|
func findReceived(offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
|
|
126
131
|
let query = transactionsView
|
|
127
132
|
.filterQueryFor(kind: .received)
|
|
128
|
-
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
|
133
|
+
.order(ZcashTransaction.Overview.Column.id.desc, (ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
|
129
134
|
.limit(limit, offset: offset)
|
|
130
135
|
|
|
131
136
|
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
|
@@ -134,7 +139,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
134
139
|
func findSent(offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
|
|
135
140
|
let query = transactionsView
|
|
136
141
|
.filterQueryFor(kind: .sent)
|
|
137
|
-
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
|
142
|
+
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc, ZcashTransaction.Overview.Column.id.desc)
|
|
138
143
|
.limit(limit, offset: offset)
|
|
139
144
|
|
|
140
145
|
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
|
@@ -143,7 +148,7 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
143
148
|
func findPendingTransactions(latestHeight: BlockHeight, offset: Int, limit: Int) async throws -> [ZcashTransaction.Overview] {
|
|
144
149
|
let query = transactionsView
|
|
145
150
|
.filterPendingFrom(latestHeight)
|
|
146
|
-
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc)
|
|
151
|
+
.order((ZcashTransaction.Overview.Column.minedHeight ?? BlockHeight.max).desc, ZcashTransaction.Overview.Column.id.desc)
|
|
147
152
|
.limit(limit, offset: offset)
|
|
148
153
|
|
|
149
154
|
return try execute(query) { try ZcashTransaction.Overview(row: $0) }
|
|
@@ -151,22 +156,22 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
151
156
|
|
|
152
157
|
func findMemos(for transaction: ZcashTransaction.Overview) async throws -> [Memo] {
|
|
153
158
|
do {
|
|
154
|
-
return try await getTransactionOutputs(for: transaction.
|
|
159
|
+
return try await getTransactionOutputs(for: transaction.id)
|
|
155
160
|
.compactMap { $0.memo }
|
|
156
161
|
} catch {
|
|
157
162
|
throw ZcashError.transactionRepositoryFindMemos(error)
|
|
158
163
|
}
|
|
159
164
|
}
|
|
160
165
|
|
|
161
|
-
func getTransactionOutputs(for
|
|
166
|
+
func getTransactionOutputs(for id: Int) async throws -> [ZcashTransaction.Output] {
|
|
162
167
|
let query = self.txOutputsView
|
|
163
|
-
.filter(ZcashTransaction.Output.Column.
|
|
168
|
+
.filter(ZcashTransaction.Output.Column.idTx == id)
|
|
164
169
|
|
|
165
170
|
return try execute(query) { try ZcashTransaction.Output(row: $0) }
|
|
166
171
|
}
|
|
167
172
|
|
|
168
|
-
func getRecipients(for
|
|
169
|
-
try await getTransactionOutputs(for:
|
|
173
|
+
func getRecipients(for id: Int) async throws -> [TransactionRecipient] {
|
|
174
|
+
try await getTransactionOutputs(for: id).map { $0.recipient }
|
|
170
175
|
}
|
|
171
176
|
|
|
172
177
|
private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) throws -> Entity {
|
|
@@ -176,14 +181,11 @@ class TransactionSQLDAO: TransactionRepository {
|
|
|
176
181
|
}
|
|
177
182
|
|
|
178
183
|
private func execute<Entity>(_ query: View, createEntity: (Row) throws -> Entity) throws -> [Entity] {
|
|
179
|
-
globalDBLock.lock()
|
|
180
|
-
defer { globalDBLock.unlock() }
|
|
181
|
-
|
|
182
184
|
do {
|
|
183
185
|
let entities = try connection()
|
|
184
186
|
.prepare(query)
|
|
185
187
|
.map(createEntity)
|
|
186
|
-
|
|
188
|
+
|
|
187
189
|
return entities
|
|
188
190
|
} catch {
|
|
189
191
|
if let error = error as? ZcashError {
|
|
@@ -109,9 +109,6 @@ class UnspentTransactionOutputSQLDAO: UnspentTransactionOutputRepository {
|
|
|
109
109
|
)
|
|
110
110
|
"""
|
|
111
111
|
do {
|
|
112
|
-
globalDBLock.lock()
|
|
113
|
-
defer { globalDBLock.unlock() }
|
|
114
|
-
|
|
115
112
|
try dbProvider.connection().run(stringStatement)
|
|
116
113
|
} catch {
|
|
117
114
|
throw ZcashError.unspentTransactionOutputDAOCreateTable(error)
|
|
@@ -121,11 +118,8 @@ class UnspentTransactionOutputSQLDAO: UnspentTransactionOutputRepository {
|
|
|
121
118
|
/// - Throws: `unspentTransactionOutputDAOStore` if sqlite query fails.
|
|
122
119
|
func store(utxos: [UnspentTransactionOutputEntity]) async throws {
|
|
123
120
|
do {
|
|
124
|
-
globalDBLock.lock()
|
|
125
|
-
defer { globalDBLock.unlock() }
|
|
126
|
-
|
|
127
121
|
let db = try dbProvider.connection()
|
|
128
|
-
try
|
|
122
|
+
try dbProvider.connection().transaction {
|
|
129
123
|
for utxo in utxos.map({ $0 as? UTXO ?? $0.asUTXO() }) {
|
|
130
124
|
try db.run(table.insert(utxo))
|
|
131
125
|
}
|
|
@@ -138,9 +132,6 @@ class UnspentTransactionOutputSQLDAO: UnspentTransactionOutputRepository {
|
|
|
138
132
|
/// - Throws: `unspentTransactionOutputDAOClearAll` if sqlite query fails.
|
|
139
133
|
func clearAll(address: String?) async throws {
|
|
140
134
|
do {
|
|
141
|
-
globalDBLock.lock()
|
|
142
|
-
defer { globalDBLock.unlock() }
|
|
143
|
-
|
|
144
135
|
if let tAddr = address {
|
|
145
136
|
try dbProvider.connection().run(table.filter(TableColumns.address == tAddr).delete())
|
|
146
137
|
} else {
|
|
@@ -187,16 +178,16 @@ class UnspentTransactionOutputSQLDAO: UnspentTransactionOutputRepository {
|
|
|
187
178
|
/// - Throws: `unspentTransactionOutputDAOBalance` if sqlite query fails.
|
|
188
179
|
func balance(address: String, latestHeight: BlockHeight) async throws -> WalletBalance {
|
|
189
180
|
do {
|
|
190
|
-
let verified = try dbProvider.connection().
|
|
181
|
+
let verified = try dbProvider.connection().scalar(
|
|
191
182
|
table.select(TableColumns.valueZat.sum)
|
|
192
183
|
.filter(TableColumns.address == address)
|
|
193
184
|
.filter(TableColumns.height <= latestHeight - ZcashSDK.defaultStaleTolerance)
|
|
194
185
|
) ?? 0
|
|
195
|
-
let total = try dbProvider.connection().
|
|
186
|
+
let total = try dbProvider.connection().scalar(
|
|
196
187
|
table.select(TableColumns.valueZat.sum)
|
|
197
188
|
.filter(TableColumns.address == address)
|
|
198
189
|
) ?? 0
|
|
199
|
-
|
|
190
|
+
|
|
200
191
|
return WalletBalance(
|
|
201
192
|
verified: Zatoshi(Int64(verified)),
|
|
202
193
|
total: Zatoshi(Int64(total))
|
|
@@ -66,9 +66,6 @@ class AccountSQDAO: AccountRepository {
|
|
|
66
66
|
/// - `accountDAOGetAll` if sqlite query fetching account data failed.
|
|
67
67
|
func getAll() throws -> [AccountEntity] {
|
|
68
68
|
do {
|
|
69
|
-
globalDBLock.lock()
|
|
70
|
-
defer { globalDBLock.unlock() }
|
|
71
|
-
|
|
72
69
|
return try dbProvider.connection()
|
|
73
70
|
.prepare(table)
|
|
74
71
|
.map { row -> DbAccount in
|
|
@@ -93,9 +90,6 @@ class AccountSQDAO: AccountRepository {
|
|
|
93
90
|
func findBy(account: Int) throws -> AccountEntity? {
|
|
94
91
|
let query = table.filter(TableColums.account == account).limit(1)
|
|
95
92
|
do {
|
|
96
|
-
globalDBLock.lock()
|
|
97
|
-
defer { globalDBLock.unlock() }
|
|
98
|
-
|
|
99
93
|
return try dbProvider.connection()
|
|
100
94
|
.prepare(query)
|
|
101
95
|
.map {
|
|
@@ -125,9 +119,6 @@ class AccountSQDAO: AccountRepository {
|
|
|
125
119
|
|
|
126
120
|
let updatedRows: Int
|
|
127
121
|
do {
|
|
128
|
-
globalDBLock.lock()
|
|
129
|
-
defer { globalDBLock.unlock() }
|
|
130
|
-
|
|
131
122
|
updatedRows = try dbProvider.connection().run(table.filter(TableColums.account == acc.account).update(acc))
|
|
132
123
|
} catch {
|
|
133
124
|
throw ZcashError.accountDAOUpdate(error)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BlockProgress.swift
|
|
3
|
+
//
|
|
4
|
+
//
|
|
5
|
+
// Created by Michal Fousek on 03.02.2023.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
public struct BlockProgress: Equatable {
|
|
11
|
+
public let startHeight: BlockHeight
|
|
12
|
+
public let targetHeight: BlockHeight
|
|
13
|
+
public let progressHeight: BlockHeight
|
|
14
|
+
|
|
15
|
+
public var progress: Float {
|
|
16
|
+
let overall = self.targetHeight - self.startHeight
|
|
17
|
+
|
|
18
|
+
return overall > 0 ? Float((self.progressHeight - self.startHeight)) / Float(overall) : 0
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public extension BlockProgress {
|
|
23
|
+
static let nullProgress = BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)
|
|
24
|
+
}
|
|
@@ -25,9 +25,9 @@ public enum ZcashTransaction {
|
|
|
25
25
|
init(
|
|
26
26
|
currentHeight: BlockHeight,
|
|
27
27
|
minedHeight: BlockHeight?,
|
|
28
|
-
expiredUnmined: Bool
|
|
28
|
+
expiredUnmined: Bool
|
|
29
29
|
) {
|
|
30
|
-
guard
|
|
30
|
+
guard !expiredUnmined else {
|
|
31
31
|
self = .expired
|
|
32
32
|
return
|
|
33
33
|
}
|
|
@@ -48,6 +48,7 @@ public enum ZcashTransaction {
|
|
|
48
48
|
public let blockTime: TimeInterval?
|
|
49
49
|
public let expiryHeight: BlockHeight?
|
|
50
50
|
public let fee: Zatoshi?
|
|
51
|
+
public let id: Int
|
|
51
52
|
public let index: Int?
|
|
52
53
|
public var isSentTransaction: Bool { value < Zatoshi(0) }
|
|
53
54
|
public let hasChange: Bool
|
|
@@ -58,7 +59,7 @@ public enum ZcashTransaction {
|
|
|
58
59
|
public let receivedNoteCount: Int
|
|
59
60
|
public let sentNoteCount: Int
|
|
60
61
|
public let value: Zatoshi
|
|
61
|
-
public let isExpiredUmined: Bool
|
|
62
|
+
public let isExpiredUmined: Bool
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
public struct Output {
|
|
@@ -78,7 +79,7 @@ public enum ZcashTransaction {
|
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
public let
|
|
82
|
+
public let idTx: Int
|
|
82
83
|
public let pool: Pool
|
|
83
84
|
public let index: Int
|
|
84
85
|
public let fromAccount: Int?
|
|
@@ -98,7 +99,7 @@ public enum ZcashTransaction {
|
|
|
98
99
|
|
|
99
100
|
extension ZcashTransaction.Output {
|
|
100
101
|
enum Column {
|
|
101
|
-
static let
|
|
102
|
+
static let idTx = Expression<Int>("id_tx")
|
|
102
103
|
static let pool = Expression<Int>("output_pool")
|
|
103
104
|
static let index = Expression<Int>("output_index")
|
|
104
105
|
static let toAccount = Expression<Int?>("to_account")
|
|
@@ -111,7 +112,7 @@ extension ZcashTransaction.Output {
|
|
|
111
112
|
|
|
112
113
|
init(row: Row) throws {
|
|
113
114
|
do {
|
|
114
|
-
|
|
115
|
+
idTx = try row.get(Column.idTx)
|
|
115
116
|
pool = .init(rawValue: try row.get(Column.pool))
|
|
116
117
|
index = try row.get(Column.index)
|
|
117
118
|
fromAccount = try row.get(Column.fromAccount)
|
|
@@ -143,6 +144,7 @@ extension ZcashTransaction.Output {
|
|
|
143
144
|
extension ZcashTransaction.Overview {
|
|
144
145
|
enum Column {
|
|
145
146
|
static let accountId = Expression<Int>("account_id")
|
|
147
|
+
static let id = Expression<Int>("id_tx")
|
|
146
148
|
static let minedHeight = Expression<BlockHeight?>("mined_height")
|
|
147
149
|
static let index = Expression<Int?>("tx_index")
|
|
148
150
|
static let rawID = Expression<Blob>("txid")
|
|
@@ -155,13 +157,14 @@ extension ZcashTransaction.Overview {
|
|
|
155
157
|
static let receivedNoteCount = Expression<Int>("received_note_count")
|
|
156
158
|
static let memoCount = Expression<Int>("memo_count")
|
|
157
159
|
static let blockTime = Expression<Int64?>("block_time")
|
|
158
|
-
static let expiredUnmined = Expression<Bool
|
|
160
|
+
static let expiredUnmined = Expression<Bool>("expired_unmined")
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
init(row: Row) throws {
|
|
162
164
|
do {
|
|
163
165
|
self.accountId = try row.get(Column.accountId)
|
|
164
166
|
self.expiryHeight = try row.get(Column.expiryHeight)
|
|
167
|
+
self.id = try row.get(Column.id)
|
|
165
168
|
self.index = try row.get(Column.index)
|
|
166
169
|
self.hasChange = try row.get(Column.hasChange)
|
|
167
170
|
self.memoCount = try row.get(Column.memoCount)
|