react-native-zcash 0.6.12 → 0.6.14
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 +9 -0
- package/ios/libzcashlc.xcframework/Info.plist +5 -5
- package/package.json +2 -2
- package/ios/ZCashLightClientKit/Block/Utils/InternalSyncProgress.swift +0 -200
- package/ios/ZCashLightClientKit/Block/Validate/BlockValidator.swift +0 -51
- package/ios/ZCashLightClientKit/DAO/BlockDao.swift +0 -112
- package/ios/ZCashLightClientKit/Entity/BlockProgress.swift +0 -24
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.6.14 (2024-04-12)
|
|
6
|
+
|
|
7
|
+
- fixed: Include missing Rust header file.
|
|
8
|
+
|
|
9
|
+
## 0.6.13 (2024-04-12)
|
|
10
|
+
|
|
11
|
+
- fixed: Update the packaging scripts to clean leftover files.
|
|
12
|
+
- fixed: Update the packaging scripts to correctly report errors, so we don't send failed packages to NPM.
|
|
13
|
+
|
|
5
14
|
## 0.6.12 (2024-04-10)
|
|
6
15
|
|
|
7
16
|
- fixed: Correct packaging mistake the previous release
|
|
@@ -8,32 +8,32 @@
|
|
|
8
8
|
<key>BinaryPath</key>
|
|
9
9
|
<string>libzcashlc.a</string>
|
|
10
10
|
<key>LibraryIdentifier</key>
|
|
11
|
-
<string>ios-
|
|
11
|
+
<string>ios-arm64</string>
|
|
12
12
|
<key>LibraryPath</key>
|
|
13
13
|
<string>libzcashlc.a</string>
|
|
14
14
|
<key>SupportedArchitectures</key>
|
|
15
15
|
<array>
|
|
16
16
|
<string>arm64</string>
|
|
17
|
-
<string>x86_64</string>
|
|
18
17
|
</array>
|
|
19
18
|
<key>SupportedPlatform</key>
|
|
20
19
|
<string>ios</string>
|
|
21
|
-
<key>SupportedPlatformVariant</key>
|
|
22
|
-
<string>simulator</string>
|
|
23
20
|
</dict>
|
|
24
21
|
<dict>
|
|
25
22
|
<key>BinaryPath</key>
|
|
26
23
|
<string>libzcashlc.a</string>
|
|
27
24
|
<key>LibraryIdentifier</key>
|
|
28
|
-
<string>ios-
|
|
25
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
29
26
|
<key>LibraryPath</key>
|
|
30
27
|
<string>libzcashlc.a</string>
|
|
31
28
|
<key>SupportedArchitectures</key>
|
|
32
29
|
<array>
|
|
33
30
|
<string>arm64</string>
|
|
31
|
+
<string>x86_64</string>
|
|
34
32
|
</array>
|
|
35
33
|
<key>SupportedPlatform</key>
|
|
36
34
|
<string>ios</string>
|
|
35
|
+
<key>SupportedPlatformVariant</key>
|
|
36
|
+
<string>simulator</string>
|
|
37
37
|
</dict>
|
|
38
38
|
</array>
|
|
39
39
|
<key>CFBundlePackageType</key>
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-zcash",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.14",
|
|
4
4
|
"description": "Zcash library for React Native",
|
|
5
5
|
"homepage": "https://github.com/EdgeApp/react-native-zcash",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git@github.com
|
|
8
|
+
"url": "git+ssh://git@github.com/EdgeApp/react-native-zcash.git"
|
|
9
9
|
},
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"author": "Airbitz, Inc.",
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// InternalSyncProgress.swift
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Created by Michal Fousek on 23.11.2022.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import Foundation
|
|
9
|
-
|
|
10
|
-
struct SyncRanges: Equatable {
|
|
11
|
-
let latestBlockHeight: BlockHeight
|
|
12
|
-
/// The sync process can be interrupted in any phase. It may happen that it's interrupted while downloading blocks. In that case in next sync
|
|
13
|
-
/// process already downloaded blocks needs to be scanned before the sync process starts to download new blocks. And the range of blocks that are
|
|
14
|
-
/// already downloaded but not scanned is stored in this variable.
|
|
15
|
-
let downloadedButUnscannedRange: CompactBlockRange?
|
|
16
|
-
/// Range of blocks that are not yet downloaded and not yet scanned.
|
|
17
|
-
let downloadAndScanRange: CompactBlockRange?
|
|
18
|
-
/// Range of blocks that are not enhanced yet.
|
|
19
|
-
let enhanceRange: CompactBlockRange?
|
|
20
|
-
/// Range of blocks for which no UTXOs are fetched yet.
|
|
21
|
-
let fetchUTXORange: CompactBlockRange?
|
|
22
|
-
|
|
23
|
-
let latestScannedHeight: BlockHeight?
|
|
24
|
-
|
|
25
|
-
let latestDownloadedBlockHeight: BlockHeight?
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
protocol InternalSyncProgressStorage {
|
|
29
|
-
func bool(forKey defaultName: String) -> Bool
|
|
30
|
-
func integer(forKey defaultName: String) -> Int
|
|
31
|
-
func set(_ value: Int, forKey defaultName: String)
|
|
32
|
-
func set(_ value: Bool, forKey defaultName: String)
|
|
33
|
-
@discardableResult
|
|
34
|
-
func synchronize() -> Bool
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
extension UserDefaults: InternalSyncProgressStorage { }
|
|
38
|
-
|
|
39
|
-
actor InternalSyncProgress {
|
|
40
|
-
enum Key: String, CaseIterable {
|
|
41
|
-
case latestDownloadedBlockHeight
|
|
42
|
-
case latestEnhancedHeight
|
|
43
|
-
case latestUTXOFetchedHeight
|
|
44
|
-
|
|
45
|
-
func with(_ alias: ZcashSynchronizerAlias) -> String {
|
|
46
|
-
switch alias {
|
|
47
|
-
case .`default`:
|
|
48
|
-
return self.rawValue
|
|
49
|
-
case let .custom(rawAlias):
|
|
50
|
-
return "\(self.rawValue)_\(rawAlias)"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private let alias: ZcashSynchronizerAlias
|
|
56
|
-
private let storage: InternalSyncProgressStorage
|
|
57
|
-
let logger: Logger
|
|
58
|
-
|
|
59
|
-
var latestDownloadedBlockHeight: BlockHeight { load(.latestDownloadedBlockHeight) }
|
|
60
|
-
var latestEnhancedHeight: BlockHeight { load(.latestEnhancedHeight) }
|
|
61
|
-
var latestUTXOFetchedHeight: BlockHeight { load(.latestUTXOFetchedHeight) }
|
|
62
|
-
|
|
63
|
-
init(alias: ZcashSynchronizerAlias, storage: InternalSyncProgressStorage, logger: Logger) {
|
|
64
|
-
self.alias = alias
|
|
65
|
-
self.storage = storage
|
|
66
|
-
self.logger = logger
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
func load(_ key: Key) -> BlockHeight {
|
|
70
|
-
storage.integer(forKey: key.with(alias))
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
func set(_ value: BlockHeight, _ key: Key) {
|
|
74
|
-
storage.set(value, forKey: key.with(alias))
|
|
75
|
-
storage.synchronize()
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
func rewind(to: BlockHeight) {
|
|
79
|
-
Key.allCases.forEach { key in
|
|
80
|
-
let finalRewindHeight = min(load(key), to)
|
|
81
|
-
self.set(finalRewindHeight, key)
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/// `InternalSyncProgress` is from now on used to track which block were already downloaded. Previous versions of the SDK were using cache DB to
|
|
86
|
-
/// track this. Because of this we have to migrate height of latest downloaded block from cache DB to here.
|
|
87
|
-
///
|
|
88
|
-
/// - Parameter latestDownloadedBlockHeight: Height of latest downloaded block from cache DB.
|
|
89
|
-
func migrateIfNeeded(latestDownloadedBlockHeightFromCacheDB latestDownloadedBlockHeight: BlockHeight) {
|
|
90
|
-
let key = "InternalSyncProgressMigrated"
|
|
91
|
-
if !storage.bool(forKey: key) {
|
|
92
|
-
set(latestDownloadedBlockHeight, .latestDownloadedBlockHeight)
|
|
93
|
-
}
|
|
94
|
-
storage.set(true, forKey: key)
|
|
95
|
-
storage.synchronize()
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/// Computes the next state for the sync process. Thanks to this it's possible to interrupt the sync process at any phase and then it can be safely
|
|
99
|
-
/// resumed.
|
|
100
|
-
///
|
|
101
|
-
/// The sync process has 4 phases (download, scan, enhance, fetch UTXO). `InternalSyncProgress` tracks independently which blocks were already
|
|
102
|
-
/// processed in each phase. To compute the next state these 4 numbers are compared with `latestBlockHeight`.
|
|
103
|
-
///
|
|
104
|
-
/// - If any of these numbers are larger than `latestBlockHeight` then `wait` is used as the next state. We have locally higher block heights than
|
|
105
|
-
/// are currently available at LightWalletd.
|
|
106
|
-
/// - If any of these numbers are lower than `latestBlockHeight` then `processNewBlocks` is used as the next state. The sync process should run.
|
|
107
|
-
/// - Otherwise `finishProcessing` is used as the next state. It means that local data are synced with what is available at LightWalletd.
|
|
108
|
-
///
|
|
109
|
-
/// - Parameters:
|
|
110
|
-
/// - latestBlockHeight: Latest height fetched from LightWalletd API.
|
|
111
|
-
/// - latestScannedHeight: Latest height of latest block scanned.
|
|
112
|
-
/// - walletBirthday: Wallet birthday.
|
|
113
|
-
/// - Returns: Computed state.
|
|
114
|
-
func computeNextState(
|
|
115
|
-
latestBlockHeight: BlockHeight,
|
|
116
|
-
latestScannedHeight: BlockHeight,
|
|
117
|
-
walletBirthday: BlockHeight
|
|
118
|
-
) -> CompactBlockProcessor.NextState {
|
|
119
|
-
logger.debug("""
|
|
120
|
-
Init numbers:
|
|
121
|
-
latestBlockHeight: \(latestBlockHeight)
|
|
122
|
-
latestDownloadedHeight: \(latestDownloadedBlockHeight)
|
|
123
|
-
latestScannedHeight: \(latestScannedHeight)
|
|
124
|
-
latestEnhancedHeight: \(latestEnhancedHeight)
|
|
125
|
-
latestUTXOFetchedHeight: \(latestUTXOFetchedHeight)
|
|
126
|
-
""")
|
|
127
|
-
|
|
128
|
-
if latestDownloadedBlockHeight > latestBlockHeight ||
|
|
129
|
-
latestScannedHeight > latestBlockHeight ||
|
|
130
|
-
latestEnhancedHeight > latestBlockHeight ||
|
|
131
|
-
latestUTXOFetchedHeight > latestBlockHeight {
|
|
132
|
-
return .wait(latestHeight: latestBlockHeight, latestDownloadHeight: latestDownloadedBlockHeight)
|
|
133
|
-
} else if latestDownloadedBlockHeight < latestBlockHeight ||
|
|
134
|
-
latestScannedHeight < latestBlockHeight ||
|
|
135
|
-
latestEnhancedHeight < latestEnhancedHeight ||
|
|
136
|
-
latestUTXOFetchedHeight < latestBlockHeight {
|
|
137
|
-
let ranges = computeSyncRanges(
|
|
138
|
-
birthday: walletBirthday,
|
|
139
|
-
latestBlockHeight: latestBlockHeight,
|
|
140
|
-
latestScannedHeight: latestScannedHeight
|
|
141
|
-
)
|
|
142
|
-
return .processNewBlocks(ranges: ranges)
|
|
143
|
-
} else {
|
|
144
|
-
return .finishProcessing(height: latestBlockHeight)
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
func computeSyncRanges(
|
|
149
|
-
birthday: BlockHeight,
|
|
150
|
-
latestBlockHeight: BlockHeight,
|
|
151
|
-
latestScannedHeight: BlockHeight
|
|
152
|
-
) -> SyncRanges {
|
|
153
|
-
// If there is more downloaded then scanned blocks we have to range for these blocks. The sync process will then start with scanning these
|
|
154
|
-
// blocks instead of downloading new ones.
|
|
155
|
-
let downloadedButUnscannedRange: CompactBlockRange?
|
|
156
|
-
if latestScannedHeight < latestDownloadedBlockHeight {
|
|
157
|
-
downloadedButUnscannedRange = latestScannedHeight + 1...latestDownloadedBlockHeight
|
|
158
|
-
} else {
|
|
159
|
-
downloadedButUnscannedRange = nil
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if latestScannedHeight > latestDownloadedBlockHeight {
|
|
163
|
-
logger.warn("""
|
|
164
|
-
InternalSyncProgress found inconsistent state.
|
|
165
|
-
latestBlockHeight: \(latestBlockHeight)
|
|
166
|
-
--> latestDownloadedHeight: \(latestDownloadedBlockHeight)
|
|
167
|
-
latestScannedHeight: \(latestScannedHeight)
|
|
168
|
-
latestEnhancedHeight: \(latestEnhancedHeight)
|
|
169
|
-
latestUTXOFetchedHeight: \(latestUTXOFetchedHeight)
|
|
170
|
-
|
|
171
|
-
latest downloaded height
|
|
172
|
-
""")
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// compute the range that must be downloaded and scanned based on
|
|
176
|
-
// birthday, `latestDownloadedBlockHeight`, `latestScannedHeight` and
|
|
177
|
-
// latest block height fetched from the chain.
|
|
178
|
-
let downloadAndScanRange = computeRange(
|
|
179
|
-
latestHeight: max(latestDownloadedBlockHeight, latestScannedHeight),
|
|
180
|
-
birthday: birthday,
|
|
181
|
-
latestBlockHeight: latestBlockHeight
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
return SyncRanges(
|
|
185
|
-
latestBlockHeight: latestBlockHeight,
|
|
186
|
-
downloadedButUnscannedRange: downloadedButUnscannedRange,
|
|
187
|
-
downloadAndScanRange: downloadAndScanRange,
|
|
188
|
-
enhanceRange: computeRange(latestHeight: latestEnhancedHeight, birthday: birthday, latestBlockHeight: latestBlockHeight),
|
|
189
|
-
fetchUTXORange: computeRange(latestHeight: latestUTXOFetchedHeight, birthday: birthday, latestBlockHeight: latestBlockHeight),
|
|
190
|
-
latestScannedHeight: latestScannedHeight,
|
|
191
|
-
latestDownloadedBlockHeight: latestDownloadedBlockHeight
|
|
192
|
-
)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
private func computeRange(latestHeight: BlockHeight, birthday: BlockHeight, latestBlockHeight: BlockHeight) -> CompactBlockRange? {
|
|
196
|
-
guard latestHeight < latestBlockHeight else { return nil }
|
|
197
|
-
let lowerBound = latestHeight <= birthday ? birthday : latestHeight + 1
|
|
198
|
-
return lowerBound...latestBlockHeight
|
|
199
|
-
}
|
|
200
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
}
|