react-native-zcash 0.6.10 → 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 +4 -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/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
|
@@ -52,14 +52,6 @@ protocol BlockDownloader {
|
|
|
52
52
|
/// called before then nothing is downloaded.
|
|
53
53
|
/// - Parameter range: Wait until blocks from `range` are downloaded.
|
|
54
54
|
func waitUntilRequestedBlocksAreDownloaded(in range: CompactBlockRange) async throws
|
|
55
|
-
|
|
56
|
-
/// Updates the internal in memory value of latest downloaded block height. This way the `BlockDownloader` works with the current latest height and can
|
|
57
|
-
/// continue on parallel downloading of next batch.
|
|
58
|
-
func update(latestDownloadedBlockHeight: BlockHeight, force: Bool) async
|
|
59
|
-
/// Provides the value of latest downloaded height.
|
|
60
|
-
func latestDownloadedBlockHeight() async -> BlockHeight
|
|
61
|
-
/// In case rewind is needed, the latestDownloadedBlockHeight is rewritten forcefully.
|
|
62
|
-
func rewind(latestDownloadedBlockHeight: BlockHeight?) async
|
|
63
55
|
}
|
|
64
56
|
|
|
65
57
|
actor BlockDownloaderImpl {
|
|
@@ -70,9 +62,9 @@ actor BlockDownloaderImpl {
|
|
|
70
62
|
let service: LightWalletService
|
|
71
63
|
let downloaderService: BlockDownloaderService
|
|
72
64
|
let storage: CompactBlockRepository
|
|
65
|
+
let internalSyncProgress: InternalSyncProgress
|
|
73
66
|
let metrics: SDKMetrics
|
|
74
67
|
let logger: Logger
|
|
75
|
-
var latestDownloadedBlockHeight: BlockHeight = -1
|
|
76
68
|
|
|
77
69
|
private var downloadStreamCreatedAtRange: CompactBlockRange = 0...0
|
|
78
70
|
private var downloadStream: BlockDownloaderStream?
|
|
@@ -88,12 +80,14 @@ actor BlockDownloaderImpl {
|
|
|
88
80
|
service: LightWalletService,
|
|
89
81
|
downloaderService: BlockDownloaderService,
|
|
90
82
|
storage: CompactBlockRepository,
|
|
83
|
+
internalSyncProgress: InternalSyncProgress,
|
|
91
84
|
metrics: SDKMetrics,
|
|
92
85
|
logger: Logger
|
|
93
86
|
) {
|
|
94
87
|
self.service = service
|
|
95
88
|
self.downloaderService = downloaderService
|
|
96
89
|
self.storage = storage
|
|
90
|
+
self.internalSyncProgress = internalSyncProgress
|
|
97
91
|
self.metrics = metrics
|
|
98
92
|
self.logger = logger
|
|
99
93
|
}
|
|
@@ -106,6 +100,8 @@ actor BlockDownloaderImpl {
|
|
|
106
100
|
throw ZcashError.blockDownloadSyncRangeNotSet
|
|
107
101
|
}
|
|
108
102
|
|
|
103
|
+
let latestDownloadedBlockHeight = await internalSyncProgress.load(.latestDownloadedBlockHeight)
|
|
104
|
+
|
|
109
105
|
let downloadFrom = max(syncRange.lowerBound, latestDownloadedBlockHeight + 1)
|
|
110
106
|
let downloadTo = min(downloadToHeight, syncRange.upperBound)
|
|
111
107
|
|
|
@@ -199,8 +195,13 @@ actor BlockDownloaderImpl {
|
|
|
199
195
|
var counter = 0
|
|
200
196
|
var lastDownloadedBlockHeight = -1
|
|
201
197
|
|
|
202
|
-
let pushMetrics: (BlockHeight, Date, Date) -> Void = { [metrics]
|
|
198
|
+
let pushMetrics: (BlockHeight, Date, Date) -> Void = { [metrics] lastDownloadedBlockHeight, startTime, finishTime in
|
|
203
199
|
metrics.pushProgressReport(
|
|
200
|
+
progress: BlockProgress(
|
|
201
|
+
startHeight: totalProgressRange.lowerBound,
|
|
202
|
+
targetHeight: totalProgressRange.upperBound,
|
|
203
|
+
progressHeight: Int(lastDownloadedBlockHeight)
|
|
204
|
+
),
|
|
204
205
|
start: startTime,
|
|
205
206
|
end: finishTime,
|
|
206
207
|
batchSize: maxBlockBufferSize,
|
|
@@ -219,7 +220,7 @@ actor BlockDownloaderImpl {
|
|
|
219
220
|
if buffer.count >= maxBlockBufferSize {
|
|
220
221
|
let finishTime = Date()
|
|
221
222
|
try await storage.write(blocks: buffer)
|
|
222
|
-
|
|
223
|
+
await blocksBufferWritten(buffer)
|
|
223
224
|
buffer.removeAll(keepingCapacity: true)
|
|
224
225
|
|
|
225
226
|
pushMetrics(block.height, startTime, finishTime)
|
|
@@ -234,36 +235,21 @@ actor BlockDownloaderImpl {
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
try await storage.write(blocks: buffer)
|
|
237
|
-
|
|
238
|
+
await blocksBufferWritten(buffer)
|
|
238
239
|
}
|
|
239
240
|
|
|
240
|
-
private func blocksBufferWritten(_ buffer: [ZcashCompactBlock]) async
|
|
241
|
+
private func blocksBufferWritten(_ buffer: [ZcashCompactBlock]) async {
|
|
241
242
|
guard let lastBlock = buffer.last else { return }
|
|
242
|
-
|
|
243
|
+
await internalSyncProgress.set(lastBlock.height, .latestDownloadedBlockHeight)
|
|
243
244
|
}
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
extension BlockDownloaderImpl: BlockDownloader {
|
|
247
|
-
func rewind(latestDownloadedBlockHeight: BlockHeight?) async {
|
|
248
|
-
self.latestDownloadedBlockHeight = latestDownloadedBlockHeight ?? -1
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
func update(latestDownloadedBlockHeight: BlockHeight, force: Bool = false) async {
|
|
252
|
-
if latestDownloadedBlockHeight >= self.latestDownloadedBlockHeight || force {
|
|
253
|
-
self.latestDownloadedBlockHeight = latestDownloadedBlockHeight
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
func latestDownloadedBlockHeight() async -> BlockHeight {
|
|
258
|
-
latestDownloadedBlockHeight
|
|
259
|
-
}
|
|
260
|
-
|
|
261
248
|
func setDownloadLimit(_ limit: BlockHeight) async {
|
|
262
249
|
downloadToHeight = limit
|
|
263
250
|
}
|
|
264
251
|
|
|
265
252
|
func setSyncRange(_ range: CompactBlockRange, batchSize: Int) async throws {
|
|
266
|
-
guard range != syncRange else { return }
|
|
267
253
|
downloadStream = nil
|
|
268
254
|
self.batchSize = batchSize
|
|
269
255
|
syncRange = range
|
|
@@ -296,13 +282,13 @@ extension BlockDownloaderImpl: BlockDownloader {
|
|
|
296
282
|
|
|
297
283
|
func waitUntilRequestedBlocksAreDownloaded(in range: CompactBlockRange) async throws {
|
|
298
284
|
logger.debug("Waiting until requested blocks are downloaded at \(range)")
|
|
299
|
-
var latestDownloadedBlock = latestDownloadedBlockHeight
|
|
285
|
+
var latestDownloadedBlock = await internalSyncProgress.load(.latestDownloadedBlockHeight)
|
|
300
286
|
while latestDownloadedBlock < range.upperBound {
|
|
301
287
|
if let error = lastError {
|
|
302
288
|
throw error
|
|
303
289
|
}
|
|
304
290
|
try await Task.sleep(milliseconds: 10)
|
|
305
|
-
latestDownloadedBlock = latestDownloadedBlockHeight
|
|
291
|
+
latestDownloadedBlock = await internalSyncProgress.load(.latestDownloadedBlockHeight)
|
|
306
292
|
}
|
|
307
293
|
logger.debug("Waiting done. Blocks are downloaded at \(range)")
|
|
308
294
|
}
|
|
@@ -107,8 +107,8 @@ extension BlockDownloaderServiceImpl: BlockDownloaderService {
|
|
|
107
107
|
try await self.storage.rewind(to: height)
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
func lastDownloadedBlockHeight() async
|
|
111
|
-
|
|
110
|
+
func lastDownloadedBlockHeight() async -> BlockHeight {
|
|
111
|
+
await self.storage.latestHeight()
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
|
|
@@ -7,56 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
import Foundation
|
|
9
9
|
|
|
10
|
-
public struct EnhancementProgress: Equatable {
|
|
11
|
-
/// total transactions that were detected in the `range`
|
|
12
|
-
public let totalTransactions: Int
|
|
13
|
-
/// enhanced transactions so far
|
|
14
|
-
public let enhancedTransactions: Int
|
|
15
|
-
/// last found transaction
|
|
16
|
-
public let lastFoundTransaction: ZcashTransaction.Overview?
|
|
17
|
-
/// block range that's being enhanced
|
|
18
|
-
public let range: CompactBlockRange
|
|
19
|
-
/// whether this transaction can be considered `newly mined` and not part of the
|
|
20
|
-
/// wallet catching up to stale and uneventful blocks.
|
|
21
|
-
public let newlyMined: Bool
|
|
22
|
-
|
|
23
|
-
public init(
|
|
24
|
-
totalTransactions: Int,
|
|
25
|
-
enhancedTransactions: Int,
|
|
26
|
-
lastFoundTransaction: ZcashTransaction.Overview?,
|
|
27
|
-
range: CompactBlockRange,
|
|
28
|
-
newlyMined: Bool
|
|
29
|
-
) {
|
|
30
|
-
self.totalTransactions = totalTransactions
|
|
31
|
-
self.enhancedTransactions = enhancedTransactions
|
|
32
|
-
self.lastFoundTransaction = lastFoundTransaction
|
|
33
|
-
self.range = range
|
|
34
|
-
self.newlyMined = newlyMined
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public var progress: Float {
|
|
38
|
-
totalTransactions > 0 ? Float(enhancedTransactions) / Float(totalTransactions) : 0
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public static var zero: EnhancementProgress {
|
|
42
|
-
EnhancementProgress(totalTransactions: 0, enhancedTransactions: 0, lastFoundTransaction: nil, range: 0...0, newlyMined: false)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public static func == (lhs: EnhancementProgress, rhs: EnhancementProgress) -> Bool {
|
|
46
|
-
return
|
|
47
|
-
lhs.totalTransactions == rhs.totalTransactions &&
|
|
48
|
-
lhs.enhancedTransactions == rhs.enhancedTransactions &&
|
|
49
|
-
lhs.lastFoundTransaction?.rawID == rhs.lastFoundTransaction?.rawID &&
|
|
50
|
-
lhs.range == rhs.range
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
10
|
protocol BlockEnhancer {
|
|
55
|
-
func enhance(at range: CompactBlockRange, didEnhance:
|
|
11
|
+
func enhance(at range: CompactBlockRange, didEnhance: (EnhancementProgress) async -> Void) async throws -> [ZcashTransaction.Overview]?
|
|
56
12
|
}
|
|
57
13
|
|
|
58
14
|
struct BlockEnhancerImpl {
|
|
59
15
|
let blockDownloaderService: BlockDownloaderService
|
|
16
|
+
let internalSyncProgress: InternalSyncProgress
|
|
60
17
|
let rustBackend: ZcashRustBackendWelding
|
|
61
18
|
let transactionRepository: TransactionRepository
|
|
62
19
|
let metrics: SDKMetrics
|
|
@@ -81,7 +38,7 @@ struct BlockEnhancerImpl {
|
|
|
81
38
|
}
|
|
82
39
|
|
|
83
40
|
extension BlockEnhancerImpl: BlockEnhancer {
|
|
84
|
-
func enhance(at range: CompactBlockRange, didEnhance:
|
|
41
|
+
func enhance(at range: CompactBlockRange, didEnhance: (EnhancementProgress) async -> Void) async throws -> [ZcashTransaction.Overview]? {
|
|
85
42
|
try Task.checkCancellation()
|
|
86
43
|
|
|
87
44
|
logger.debug("Started Enhancing range: \(range)")
|
|
@@ -95,6 +52,7 @@ extension BlockEnhancerImpl: BlockEnhancer {
|
|
|
95
52
|
let transactions = try await transactionRepository.find(in: range, limit: Int.max, kind: .all)
|
|
96
53
|
|
|
97
54
|
guard !transactions.isEmpty else {
|
|
55
|
+
await internalSyncProgress.set(range.upperBound, .latestEnhancedHeight)
|
|
98
56
|
logger.debug("no transactions detected on range: \(range.lowerBound)...\(range.upperBound)")
|
|
99
57
|
return nil
|
|
100
58
|
}
|
|
@@ -124,6 +82,10 @@ extension BlockEnhancerImpl: BlockEnhancer {
|
|
|
124
82
|
)
|
|
125
83
|
|
|
126
84
|
await didEnhance(progress)
|
|
85
|
+
|
|
86
|
+
if let minedHeight = confirmedTx.minedHeight {
|
|
87
|
+
await internalSyncProgress.set(minedHeight, .latestEnhancedHeight)
|
|
88
|
+
}
|
|
127
89
|
} catch {
|
|
128
90
|
retries += 1
|
|
129
91
|
logger.error("could not enhance txId \(transaction.rawID.toHexStringTxId()) - Error: \(error)")
|
|
@@ -135,6 +97,11 @@ extension BlockEnhancerImpl: BlockEnhancer {
|
|
|
135
97
|
}
|
|
136
98
|
|
|
137
99
|
metrics.pushProgressReport(
|
|
100
|
+
progress: BlockProgress(
|
|
101
|
+
startHeight: range.lowerBound,
|
|
102
|
+
targetHeight: range.upperBound,
|
|
103
|
+
progressHeight: range.upperBound
|
|
104
|
+
),
|
|
138
105
|
start: startTime,
|
|
139
106
|
end: Date(),
|
|
140
107
|
batchSize: range.count,
|
|
@@ -144,6 +111,8 @@ extension BlockEnhancerImpl: BlockEnhancer {
|
|
|
144
111
|
logger.error("error enhancing transactions! \(error)")
|
|
145
112
|
throw error
|
|
146
113
|
}
|
|
114
|
+
|
|
115
|
+
await internalSyncProgress.set(range.upperBound, .latestEnhancedHeight)
|
|
147
116
|
|
|
148
117
|
if Task.isCancelled {
|
|
149
118
|
logger.debug("Warning: compactBlockEnhancement on range \(range) cancelled")
|
|
@@ -18,7 +18,8 @@ struct UTXOFetcherConfig {
|
|
|
18
18
|
|
|
19
19
|
protocol UTXOFetcher {
|
|
20
20
|
func fetch(
|
|
21
|
-
|
|
21
|
+
at range: CompactBlockRange,
|
|
22
|
+
didFetch: (Float) async -> Void
|
|
22
23
|
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity])
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -26,6 +27,7 @@ struct UTXOFetcherImpl {
|
|
|
26
27
|
let accountRepository: AccountRepository
|
|
27
28
|
let blockDownloaderService: BlockDownloaderService
|
|
28
29
|
let config: UTXOFetcherConfig
|
|
30
|
+
let internalSyncProgress: InternalSyncProgress
|
|
29
31
|
let rustBackend: ZcashRustBackendWelding
|
|
30
32
|
let metrics: SDKMetrics
|
|
31
33
|
let logger: Logger
|
|
@@ -33,7 +35,8 @@ struct UTXOFetcherImpl {
|
|
|
33
35
|
|
|
34
36
|
extension UTXOFetcherImpl: UTXOFetcher {
|
|
35
37
|
func fetch(
|
|
36
|
-
|
|
38
|
+
at range: CompactBlockRange,
|
|
39
|
+
didFetch: (Float) async -> Void
|
|
37
40
|
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
|
|
38
41
|
try Task.checkCancellation()
|
|
39
42
|
|
|
@@ -79,6 +82,7 @@ extension UTXOFetcherImpl: UTXOFetcher {
|
|
|
79
82
|
|
|
80
83
|
counter += 1
|
|
81
84
|
await didFetch(counter / all)
|
|
85
|
+
await internalSyncProgress.set(utxo.height, .latestUTXOFetchedHeight)
|
|
82
86
|
} catch {
|
|
83
87
|
logger.error("failed to put utxo - error: \(error)")
|
|
84
88
|
skipped.append(utxo)
|
|
@@ -86,16 +90,23 @@ extension UTXOFetcherImpl: UTXOFetcher {
|
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
metrics.pushProgressReport(
|
|
93
|
+
progress: BlockProgress(
|
|
94
|
+
startHeight: range.lowerBound,
|
|
95
|
+
targetHeight: range.upperBound,
|
|
96
|
+
progressHeight: range.upperBound
|
|
97
|
+
),
|
|
89
98
|
start: startTime,
|
|
90
99
|
end: Date(),
|
|
91
|
-
batchSize:
|
|
100
|
+
batchSize: range.count,
|
|
92
101
|
operation: .fetchUTXOs
|
|
93
102
|
)
|
|
94
103
|
|
|
95
104
|
let result = (inserted: refreshed, skipped: skipped)
|
|
96
105
|
|
|
106
|
+
await internalSyncProgress.set(range.upperBound, .latestUTXOFetchedHeight)
|
|
107
|
+
|
|
97
108
|
if Task.isCancelled {
|
|
98
|
-
logger.debug("Warning: fetchUnspentTxOutputs cancelled")
|
|
109
|
+
logger.debug("Warning: fetchUnspentTxOutputs on range \(range) cancelled")
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
return result
|
|
@@ -64,8 +64,8 @@ extension FSCompactBlockRepository: CompactBlockRepository {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
func latestHeight() async
|
|
68
|
-
|
|
67
|
+
func latestHeight() async -> BlockHeight {
|
|
68
|
+
await metadataStore.latestHeight()
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
func write(blocks: [ZcashCompactBlock]) async throws {
|
|
@@ -251,7 +251,7 @@ struct FSMetadataStore {
|
|
|
251
251
|
let saveBlocksMeta: ([ZcashCompactBlock]) async throws -> Void
|
|
252
252
|
let rewindToHeight: (BlockHeight) async throws -> Void
|
|
253
253
|
let initFsBlockDbRoot: () async throws -> Void
|
|
254
|
-
let latestHeight: () async
|
|
254
|
+
let latestHeight: () async -> BlockHeight
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
extension FSMetadataStore {
|
|
@@ -268,7 +268,7 @@ extension FSMetadataStore {
|
|
|
268
268
|
} initFsBlockDbRoot: {
|
|
269
269
|
try await rustBackend.initBlockMetadataDb()
|
|
270
270
|
} latestHeight: {
|
|
271
|
-
|
|
271
|
+
await rustBackend.latestCachedBlockHeight()
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
}
|
|
@@ -16,7 +16,8 @@ protocol BlockScanner {
|
|
|
16
16
|
@discardableResult
|
|
17
17
|
func scanBlocks(
|
|
18
18
|
at range: CompactBlockRange,
|
|
19
|
-
|
|
19
|
+
totalProgressRange: CompactBlockRange,
|
|
20
|
+
didScan: @escaping (BlockHeight) async -> Void
|
|
20
21
|
) async throws -> BlockHeight
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -26,18 +27,20 @@ struct BlockScannerImpl {
|
|
|
26
27
|
let transactionRepository: TransactionRepository
|
|
27
28
|
let metrics: SDKMetrics
|
|
28
29
|
let logger: Logger
|
|
30
|
+
let latestBlocksDataProvider: LatestBlocksDataProvider
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
extension BlockScannerImpl: BlockScanner {
|
|
32
34
|
@discardableResult
|
|
33
35
|
func scanBlocks(
|
|
34
36
|
at range: CompactBlockRange,
|
|
35
|
-
|
|
37
|
+
totalProgressRange: CompactBlockRange,
|
|
38
|
+
didScan: @escaping (BlockHeight) async -> Void
|
|
36
39
|
) async throws -> BlockHeight {
|
|
37
40
|
logger.debug("Going to scan blocks in range: \(range)")
|
|
38
41
|
try Task.checkCancellation()
|
|
39
42
|
|
|
40
|
-
let scanStartHeight =
|
|
43
|
+
let scanStartHeight = try await transactionRepository.lastScannedHeight()
|
|
41
44
|
let targetScanHeight = range.upperBound
|
|
42
45
|
|
|
43
46
|
var scannedNewBlocks = false
|
|
@@ -47,13 +50,13 @@ extension BlockScannerImpl: BlockScanner {
|
|
|
47
50
|
try Task.checkCancellation()
|
|
48
51
|
|
|
49
52
|
let previousScannedHeight = lastScannedHeight
|
|
50
|
-
let startHeight = previousScannedHeight + 1
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
// TODO: [#576] remove this arbitrary batch size https://github.com/zcash/ZcashLightClientKit/issues/576
|
|
55
|
+
let batchSize = scanBatchSize(startScanHeight: previousScannedHeight + 1, network: config.networkType)
|
|
53
56
|
|
|
54
57
|
let scanStartTime = Date()
|
|
55
58
|
do {
|
|
56
|
-
try await self.rustBackend.scanBlocks(
|
|
59
|
+
try await self.rustBackend.scanBlocks(limit: batchSize)
|
|
57
60
|
} catch {
|
|
58
61
|
logger.debug("block scanning failed with error: \(String(describing: error))")
|
|
59
62
|
throw error
|
|
@@ -61,15 +64,24 @@ extension BlockScannerImpl: BlockScanner {
|
|
|
61
64
|
|
|
62
65
|
let scanFinishTime = Date()
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
if let lastScannedBlock = try await transactionRepository.lastScannedBlock() {
|
|
68
|
+
lastScannedHeight = lastScannedBlock.height
|
|
69
|
+
await latestBlocksDataProvider.updateLatestScannedHeight(lastScannedHeight)
|
|
70
|
+
await latestBlocksDataProvider.updateLatestScannedTime(TimeInterval(lastScannedBlock.time))
|
|
71
|
+
}
|
|
67
72
|
|
|
68
73
|
scannedNewBlocks = previousScannedHeight != lastScannedHeight
|
|
69
74
|
if scannedNewBlocks {
|
|
70
|
-
|
|
75
|
+
await didScan(lastScannedHeight)
|
|
76
|
+
|
|
77
|
+
let progress = BlockProgress(
|
|
78
|
+
startHeight: totalProgressRange.lowerBound,
|
|
79
|
+
targetHeight: totalProgressRange.upperBound,
|
|
80
|
+
progressHeight: lastScannedHeight
|
|
81
|
+
)
|
|
71
82
|
|
|
72
83
|
metrics.pushProgressReport(
|
|
84
|
+
progress: progress,
|
|
73
85
|
start: scanStartTime,
|
|
74
86
|
end: scanFinishTime,
|
|
75
87
|
batchSize: Int(batchSize),
|
|
@@ -86,4 +98,17 @@ extension BlockScannerImpl: BlockScanner {
|
|
|
86
98
|
|
|
87
99
|
return lastScannedHeight
|
|
88
100
|
}
|
|
101
|
+
|
|
102
|
+
private func scanBatchSize(startScanHeight height: BlockHeight, network: NetworkType) -> UInt32 {
|
|
103
|
+
assert(config.scanningBatchSize > 0, "ZcashSDK.DefaultScanningBatch must be larger than 0!")
|
|
104
|
+
guard network == .mainnet else { return UInt32(config.scanningBatchSize) }
|
|
105
|
+
|
|
106
|
+
if height > 1_650_000 {
|
|
107
|
+
// librustzcash thread saturation at a number of blocks
|
|
108
|
+
// that contains 100 * num_cores Sapling outputs.
|
|
109
|
+
return UInt32(max(ProcessInfo().activeProcessorCount, 10))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return UInt32(config.scanningBatchSize)
|
|
113
|
+
}
|
|
89
114
|
}
|
|
@@ -0,0 +1,200 @@
|
|
|
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
|
+
}
|