react-native-zcash 0.6.14 → 0.7.0
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/build.gradle +4 -4
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2470000.json +8 -0
- package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2480000.json +8 -0
- package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +51 -9
- package/ios/RNZcash.m +8 -0
- package/ios/RNZcash.swift +66 -16
- package/ios/ZCashLightClientKit/Block/Actions/DownloadAction.swift +1 -1
- package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +3 -1
- package/ios/ZCashLightClientKit/Block/Actions/FetchUTXOsAction.swift +1 -1
- package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +11 -2
- package/ios/ZCashLightClientKit/Block/Actions/RewindAction.swift +2 -2
- package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +28 -11
- package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +4 -4
- package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +36 -7
- package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +1 -1
- package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +93 -51
- package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +0 -26
- package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +5 -6
- package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +1 -11
- package/ios/ZCashLightClientKit/Block/SaplingParameters/SaplingParametersHandler.swift +6 -4
- package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +10 -12
- package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointSource.swift +38 -0
- package/ios/ZCashLightClientKit/Checkpoint/BundleCheckpointURLProvider.swift +40 -0
- package/ios/ZCashLightClientKit/{Constants/Checkpoint+Constants.swift → Checkpoint/Checkpoint+helpers.swift} +1 -33
- package/ios/ZCashLightClientKit/Checkpoint/CheckpointSource.swift +34 -0
- package/ios/ZCashLightClientKit/Checkpoint/CheckpointSourceFactory.swift +14 -0
- package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +61 -6
- package/ios/ZCashLightClientKit/CombineSynchronizer.swift +63 -4
- package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +4 -0
- package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +21 -33
- package/ios/ZCashLightClientKit/DAO/UnspentTransactionOutputDao.swift +0 -182
- package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +0 -173
- package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +5 -2
- package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
- package/ios/ZCashLightClientKit/Error/ZcashError.swift +53 -1
- package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +19 -1
- package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +32 -0
- package/ios/ZCashLightClientKit/Initializer.swift +8 -17
- package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +103 -217
- package/ios/ZCashLightClientKit/Model/Proposal.swift +45 -0
- package/ios/ZCashLightClientKit/Model/ScanSummary.swift +14 -0
- package/ios/ZCashLightClientKit/Model/WalletSummary.swift +58 -0
- package/ios/ZCashLightClientKit/Model/WalletTypes.swift +0 -16
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +5 -3
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proposal.pb.swift +934 -0
- package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/proposal.proto +138 -0
- package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +2 -4
- package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +9 -1
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2272500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2275000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2277500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2282500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2285000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2287500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2292500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2295000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2297500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2302500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2305000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2307500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2312500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2315000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2317500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2322500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2325000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2327500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2332500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2335000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2337500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2342500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2345000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2347500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2352500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2355000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2357500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2362500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2365000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2367500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2372500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2375000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2377500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2382500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2385000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2387500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2392500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2395000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2397500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2402500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2405000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2407500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2412500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2415000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2417500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2422500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2425000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2427500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2432500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2435000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2437500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2442500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2445000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2447500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2452500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2455000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2457500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2462500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2465000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2467500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2470000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2472500.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2480000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2560000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2570000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2580000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2590000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2600000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2610000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2620000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2630000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2640000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2650000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2660000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2670000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2680000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2690000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2700000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2710000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2720000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2730000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2740000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2750000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2760000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2770000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2780000.json +8 -0
- package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2790000.json +8 -0
- package/ios/ZCashLightClientKit/Rust/ZcashKeyDerivationBackend.swift +1 -5
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +327 -153
- package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +78 -36
- package/ios/ZCashLightClientKit/Rust/zcashlc.h +402 -118
- package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +43 -14
- package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +52 -14
- package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +10 -6
- package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +220 -70
- package/ios/ZCashLightClientKit/Synchronizer.swift +105 -29
- package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +61 -32
- package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +52 -61
- package/ios/ZCashLightClientKit/Utils/DBActor.swift +21 -0
- package/ios/ZCashLightClientKit/Utils/LoggingProxy.swift +5 -0
- package/ios/ZCashLightClientKit/Utils/OSLogger.swift +71 -14
- package/ios/libzcashlc.xcframework/Info.plist +5 -5
- package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
- package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
- package/lib/rnzcash.rn.js +21 -6
- package/lib/rnzcash.rn.js.map +1 -1
- package/lib/src/react-native.d.ts +2 -1
- package/lib/src/types.d.ts +9 -1
- package/package.json +1 -1
- package/src/react-native.ts +23 -4
- package/src/types.ts +10 -1
- package/ios/ZCashLightClientKit/Model/ScanProgress.swift +0 -29
- package/ios/ZCashLightClientKit/Repository/UnspentTransactionOutputRepository.swift +0 -16
- /package/ios/ZCashLightClientKit/{Model → Checkpoint}/Checkpoint.swift +0 -0
|
@@ -28,18 +28,18 @@ actor CompactBlockProcessor {
|
|
|
28
28
|
private let configProvider: ConfigProvider
|
|
29
29
|
private var afterSyncHooksManager = AfterSyncHooksManager()
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
private let latestBlocksDataProvider: LatestBlocksDataProvider
|
|
31
|
+
var blockDownloaderService: BlockDownloaderService
|
|
32
|
+
private var latestBlocksDataProvider: LatestBlocksDataProvider
|
|
34
33
|
private let logger: Logger
|
|
35
34
|
private let metrics: SDKMetrics
|
|
36
35
|
private let rustBackend: ZcashRustBackendWelding
|
|
37
|
-
|
|
36
|
+
var service: LightWalletService
|
|
38
37
|
let storage: CompactBlockRepository
|
|
39
38
|
private let transactionRepository: TransactionRepository
|
|
40
39
|
private let fileManager: ZcashFileManager
|
|
41
40
|
|
|
42
41
|
private var retryAttempts: Int = 0
|
|
42
|
+
private var serviceFailureRetryAttempts: Int = 0
|
|
43
43
|
private var backoffTimer: Timer?
|
|
44
44
|
private var consecutiveChainValidationErrors: Int = 0
|
|
45
45
|
|
|
@@ -141,20 +141,6 @@ actor CompactBlockProcessor {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
/// Initializes a CompactBlockProcessor instance
|
|
145
|
-
/// - Parameters:
|
|
146
|
-
/// - service: concrete implementation of `LightWalletService` protocol
|
|
147
|
-
/// - storage: concrete implementation of `CompactBlockRepository` protocol
|
|
148
|
-
/// - backend: a class that complies to `ZcashRustBackendWelding`
|
|
149
|
-
/// - config: `Configuration` struct for this processor
|
|
150
|
-
init(container: DIContainer, config: Configuration) {
|
|
151
|
-
self.init(
|
|
152
|
-
container: container,
|
|
153
|
-
config: config,
|
|
154
|
-
accountRepository: AccountRepositoryBuilder.build(dataDbURL: config.dataDb, readOnly: true, logger: container.resolve(Logger.self))
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
144
|
/// Initializes a CompactBlockProcessor instance from an Initialized object
|
|
159
145
|
/// - Parameters:
|
|
160
146
|
/// - initializer: an instance that complies to CompactBlockDownloading protocol
|
|
@@ -170,20 +156,23 @@ actor CompactBlockProcessor {
|
|
|
170
156
|
saplingParamsSourceURL: initializer.saplingParamsSourceURL,
|
|
171
157
|
walletBirthdayProvider: walletBirthdayProvider,
|
|
172
158
|
network: initializer.network
|
|
173
|
-
)
|
|
174
|
-
accountRepository: initializer.accountRepository
|
|
159
|
+
)
|
|
175
160
|
)
|
|
176
161
|
}
|
|
177
162
|
|
|
163
|
+
/// Initializes a CompactBlockProcessor instance
|
|
164
|
+
/// - Parameters:
|
|
165
|
+
/// - service: concrete implementation of `LightWalletService` protocol
|
|
166
|
+
/// - storage: concrete implementation of `CompactBlockRepository` protocol
|
|
167
|
+
/// - backend: a class that complies to `ZcashRustBackendWelding`
|
|
168
|
+
/// - config: `Configuration` struct for this processor
|
|
178
169
|
init(
|
|
179
170
|
container: DIContainer,
|
|
180
|
-
config: Configuration
|
|
181
|
-
accountRepository: AccountRepository
|
|
171
|
+
config: Configuration
|
|
182
172
|
) {
|
|
183
173
|
Dependencies.setupCompactBlockProcessor(
|
|
184
174
|
in: container,
|
|
185
|
-
config: config
|
|
186
|
-
accountRepository: accountRepository
|
|
175
|
+
config: config
|
|
187
176
|
)
|
|
188
177
|
|
|
189
178
|
let configProvider = ConfigProvider(config: config)
|
|
@@ -199,7 +188,6 @@ actor CompactBlockProcessor {
|
|
|
199
188
|
self.storage = container.resolve(CompactBlockRepository.self)
|
|
200
189
|
self.config = config
|
|
201
190
|
self.transactionRepository = container.resolve(TransactionRepository.self)
|
|
202
|
-
self.accountRepository = accountRepository
|
|
203
191
|
self.fileManager = container.resolve(ZcashFileManager.self)
|
|
204
192
|
self.configProvider = configProvider
|
|
205
193
|
}
|
|
@@ -263,6 +251,7 @@ extension CompactBlockProcessor {
|
|
|
263
251
|
func start(retry: Bool = false) async {
|
|
264
252
|
if retry {
|
|
265
253
|
self.retryAttempts = 0
|
|
254
|
+
self.serviceFailureRetryAttempts = 0
|
|
266
255
|
self.backoffTimer?.invalidate()
|
|
267
256
|
self.backoffTimer = nil
|
|
268
257
|
}
|
|
@@ -289,6 +278,7 @@ extension CompactBlockProcessor {
|
|
|
289
278
|
self.backoffTimer = nil
|
|
290
279
|
await stopAllActions()
|
|
291
280
|
retryAttempts = 0
|
|
281
|
+
serviceFailureRetryAttempts = 0
|
|
292
282
|
}
|
|
293
283
|
|
|
294
284
|
func latestHeight() async throws -> BlockHeight {
|
|
@@ -396,6 +386,8 @@ extension CompactBlockProcessor {
|
|
|
396
386
|
|
|
397
387
|
try await rewindDownloadBlockAction(to: nil)
|
|
398
388
|
|
|
389
|
+
await latestBlocksDataProvider.reset()
|
|
390
|
+
|
|
399
391
|
await context.completion(nil)
|
|
400
392
|
} catch {
|
|
401
393
|
await context.completion(error)
|
|
@@ -409,6 +401,52 @@ extension CompactBlockProcessor {
|
|
|
409
401
|
}
|
|
410
402
|
}
|
|
411
403
|
|
|
404
|
+
// MARK: - Switch server
|
|
405
|
+
|
|
406
|
+
extension CompactBlockProcessor {
|
|
407
|
+
func updateService(_ container: DIContainer) {
|
|
408
|
+
// LightWalletGRPCService
|
|
409
|
+
let updatedLWDService = container.resolve(LightWalletService.self)
|
|
410
|
+
|
|
411
|
+
(actions[.processSuggestedScanRanges] as? ProcessSuggestedScanRangesAction)?.service = updatedLWDService
|
|
412
|
+
(actions[.updateChainTip] as? UpdateChainTipAction)?.service = updatedLWDService
|
|
413
|
+
(actions[.updateSubtreeRoots] as? UpdateSubtreeRootsAction)?.service = updatedLWDService
|
|
414
|
+
(actions[.validateServer] as? ValidateServerAction)?.service = updatedLWDService
|
|
415
|
+
self.service = updatedLWDService
|
|
416
|
+
|
|
417
|
+
// BlockDownloaderService
|
|
418
|
+
let updatedDownloaderService = container.resolve(BlockDownloaderService.self)
|
|
419
|
+
|
|
420
|
+
(actions[.rewind] as? RewindAction)?.downloaderService = updatedDownloaderService
|
|
421
|
+
self.blockDownloaderService = updatedDownloaderService
|
|
422
|
+
|
|
423
|
+
// LatestBlocksDataProvider
|
|
424
|
+
let updatedLBDProvider = container.resolve(LatestBlocksDataProvider.self)
|
|
425
|
+
|
|
426
|
+
(actions[.scan] as? ScanAction)?.latestBlocksDataProvider = updatedLBDProvider
|
|
427
|
+
(actions[.updateChainTip] as? UpdateChainTipAction)?.latestBlocksDataProvider = updatedLBDProvider
|
|
428
|
+
self.latestBlocksDataProvider = updatedLBDProvider
|
|
429
|
+
|
|
430
|
+
// BlockDownloader
|
|
431
|
+
let updatedBlockDownloader = container.resolve(BlockDownloader.self)
|
|
432
|
+
|
|
433
|
+
(actions[.download] as? DownloadAction)?.downloader = updatedBlockDownloader
|
|
434
|
+
(actions[.updateChainTip] as? UpdateChainTipAction)?.downloader = updatedBlockDownloader
|
|
435
|
+
(actions[.rewind] as? RewindAction)?.downloader = updatedBlockDownloader
|
|
436
|
+
self.blockDownloaderService = updatedDownloaderService
|
|
437
|
+
|
|
438
|
+
// BlockEnhancer
|
|
439
|
+
let updatedEnhancer = container.resolve(BlockEnhancer.self)
|
|
440
|
+
|
|
441
|
+
(actions[.enhance] as? EnhanceAction)?.blockEnhancer = updatedEnhancer
|
|
442
|
+
|
|
443
|
+
// UTXOFetcher
|
|
444
|
+
let updatedUTXOFetcher = container.resolve(UTXOFetcher.self)
|
|
445
|
+
|
|
446
|
+
(actions[.fetchUTXO] as? FetchUTXOsAction)?.utxoFetcher = updatedUTXOFetcher
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
412
450
|
// MARK: - Events
|
|
413
451
|
|
|
414
452
|
extension CompactBlockProcessor {
|
|
@@ -478,6 +516,7 @@ extension CompactBlockProcessor {
|
|
|
478
516
|
// swiftlint:disable:next cyclomatic_complexity
|
|
479
517
|
private func run() async {
|
|
480
518
|
logger.debug("Starting run")
|
|
519
|
+
metrics.cbpStart()
|
|
481
520
|
await resetContext()
|
|
482
521
|
|
|
483
522
|
while true {
|
|
@@ -513,6 +552,7 @@ extension CompactBlockProcessor {
|
|
|
513
552
|
try Task.checkCancellation()
|
|
514
553
|
|
|
515
554
|
// Execute action.
|
|
555
|
+
metrics.actionStart(state)
|
|
516
556
|
context = try await action.run(with: context) { [weak self] event in
|
|
517
557
|
await self?.send(event: event)
|
|
518
558
|
if let progressChanged = await self?.compactBlockProgress.hasProgressUpdated(event), progressChanged {
|
|
@@ -528,7 +568,27 @@ extension CompactBlockProcessor {
|
|
|
528
568
|
await stopAllActions()
|
|
529
569
|
logger.error("Sync failed with error: \(error)")
|
|
530
570
|
|
|
531
|
-
|
|
571
|
+
// catching the service errors
|
|
572
|
+
let serviceError: Bool
|
|
573
|
+
switch error {
|
|
574
|
+
case ZcashError.serviceGetInfoFailed, ZcashError.serviceLatestBlockFailed,
|
|
575
|
+
ZcashError.serviceLatestBlockHeightFailed, ZcashError.serviceBlockRangeFailed,
|
|
576
|
+
ZcashError.serviceSubmitFailed, ZcashError.serviceFetchTransactionFailed,
|
|
577
|
+
ZcashError.serviceFetchUTXOsFailed, ZcashError.serviceBlockStreamFailed,
|
|
578
|
+
ZcashError.serviceSubtreeRootsStreamFailed: serviceError = true
|
|
579
|
+
default: serviceError = false
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if serviceError && self.serviceFailureRetryAttempts < ZcashSDK.serviceFailureRetries {
|
|
583
|
+
// This may be false positive communication error that is usually resolved by retry.
|
|
584
|
+
// We will try to reset the sync and continue but this will we done at most `ZcashSDK.serviceFailureRetries` times.
|
|
585
|
+
logger.error("ServiceError: \(error), retry is available, starting the sync all over again.")
|
|
586
|
+
|
|
587
|
+
self.serviceFailureRetryAttempts += 1
|
|
588
|
+
|
|
589
|
+
// Start sync all over again
|
|
590
|
+
await resetContext()
|
|
591
|
+
} else if Task.isCancelled {
|
|
532
592
|
logger.info("Processing cancelled.")
|
|
533
593
|
do {
|
|
534
594
|
if try await syncTaskWasCancelled() {
|
|
@@ -543,13 +603,8 @@ extension CompactBlockProcessor {
|
|
|
543
603
|
break
|
|
544
604
|
}
|
|
545
605
|
} else {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
await resetContext()
|
|
549
|
-
} else {
|
|
550
|
-
// end the sync loop
|
|
551
|
-
break
|
|
552
|
-
}
|
|
606
|
+
await handleSyncFailure(action: action, error: error)
|
|
607
|
+
break
|
|
553
608
|
}
|
|
554
609
|
}
|
|
555
610
|
}
|
|
@@ -565,15 +620,13 @@ extension CompactBlockProcessor {
|
|
|
565
620
|
return try await handleAfterSyncHooks()
|
|
566
621
|
}
|
|
567
622
|
|
|
568
|
-
private func handleSyncFailure(action: Action, error: Error) async
|
|
623
|
+
private func handleSyncFailure(action: Action, error: Error) async {
|
|
569
624
|
if action.removeBlocksCacheWhenFailed {
|
|
570
625
|
await ifTaskIsNotCanceledClearCompactBlockCache()
|
|
571
626
|
}
|
|
572
627
|
|
|
573
628
|
logger.error("Sync failed with error: \(error)")
|
|
574
629
|
await failure(error)
|
|
575
|
-
|
|
576
|
-
return false
|
|
577
630
|
}
|
|
578
631
|
|
|
579
632
|
// swiftlint:disable:next cyclomatic_complexity
|
|
@@ -640,6 +693,7 @@ extension CompactBlockProcessor {
|
|
|
640
693
|
latestBlockHeightWhenSyncing > 0 && latestBlockHeightWhenSyncing < latestBlockHeight
|
|
641
694
|
|
|
642
695
|
retryAttempts = 0
|
|
696
|
+
serviceFailureRetryAttempts = 0
|
|
643
697
|
consecutiveChainValidationErrors = 0
|
|
644
698
|
|
|
645
699
|
let lastScannedHeight = await latestBlocksDataProvider.maxScannedHeight
|
|
@@ -649,6 +703,9 @@ extension CompactBlockProcessor {
|
|
|
649
703
|
await send(event: .finished(lastScannedHeight))
|
|
650
704
|
await context.update(state: .finished)
|
|
651
705
|
|
|
706
|
+
let walletSummary = try? await rustBackend.getWalletSummary()
|
|
707
|
+
await metrics.logCBPOverviewReport(logger, walletSummary: walletSummary)
|
|
708
|
+
|
|
652
709
|
// If new blocks were mined during previous sync run the sync process again
|
|
653
710
|
if newerBlocksWereMinedDuringSync {
|
|
654
711
|
return true
|
|
@@ -777,21 +834,6 @@ extension CompactBlockProcessor {
|
|
|
777
834
|
func getTransparentAddress(accountIndex: Int) async throws -> TransparentAddress {
|
|
778
835
|
try await getUnifiedAddress(accountIndex: accountIndex).transparentReceiver()
|
|
779
836
|
}
|
|
780
|
-
|
|
781
|
-
func getTransparentBalance(accountIndex: Int) async throws -> WalletBalance {
|
|
782
|
-
guard accountIndex >= 0 else {
|
|
783
|
-
throw ZcashError.compactBlockProcessorInvalidAccount
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
return WalletBalance(
|
|
787
|
-
verified: Zatoshi(
|
|
788
|
-
try await rustBackend.getVerifiedTransparentBalance(account: Int32(accountIndex))
|
|
789
|
-
),
|
|
790
|
-
total: Zatoshi(
|
|
791
|
-
try await rustBackend.getTransparentBalance(account: Int32(accountIndex))
|
|
792
|
-
)
|
|
793
|
-
)
|
|
794
|
-
}
|
|
795
837
|
}
|
|
796
838
|
|
|
797
839
|
extension CompactBlockProcessor {
|
|
@@ -195,44 +195,18 @@ actor BlockDownloaderImpl {
|
|
|
195
195
|
var buffer: [ZcashCompactBlock] = []
|
|
196
196
|
logger.debug("Downloading blocks in range: \(range.lowerBound)...\(range.upperBound)")
|
|
197
197
|
|
|
198
|
-
var startTime = Date()
|
|
199
|
-
var counter = 0
|
|
200
|
-
var lastDownloadedBlockHeight = -1
|
|
201
|
-
|
|
202
|
-
let pushMetrics: (BlockHeight, Date, Date) -> Void = { [metrics] _, startTime, finishTime in
|
|
203
|
-
metrics.pushProgressReport(
|
|
204
|
-
start: startTime,
|
|
205
|
-
end: finishTime,
|
|
206
|
-
batchSize: maxBlockBufferSize,
|
|
207
|
-
operation: .downloadBlocks
|
|
208
|
-
)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
198
|
for _ in stride(from: range.lowerBound, to: range.upperBound + 1, by: 1) {
|
|
212
199
|
try Task.checkCancellation()
|
|
213
200
|
guard let block = try await stream.nextBlock() else { break }
|
|
214
201
|
|
|
215
|
-
counter += 1
|
|
216
|
-
lastDownloadedBlockHeight = block.height
|
|
217
|
-
|
|
218
202
|
buffer.append(block)
|
|
219
203
|
if buffer.count >= maxBlockBufferSize {
|
|
220
|
-
let finishTime = Date()
|
|
221
204
|
try await storage.write(blocks: buffer)
|
|
222
205
|
try await blocksBufferWritten(buffer)
|
|
223
206
|
buffer.removeAll(keepingCapacity: true)
|
|
224
|
-
|
|
225
|
-
pushMetrics(block.height, startTime, finishTime)
|
|
226
|
-
|
|
227
|
-
counter = 0
|
|
228
|
-
startTime = finishTime
|
|
229
207
|
}
|
|
230
208
|
}
|
|
231
209
|
|
|
232
|
-
if counter > 0 {
|
|
233
|
-
pushMetrics(lastDownloadedBlockHeight, startTime, Date())
|
|
234
|
-
}
|
|
235
|
-
|
|
236
210
|
try await storage.write(blocks: buffer)
|
|
237
211
|
try await blocksBufferWritten(buffer)
|
|
238
212
|
}
|
|
@@ -96,6 +96,7 @@ extension BlockEnhancerImpl: BlockEnhancer {
|
|
|
96
96
|
|
|
97
97
|
guard !transactions.isEmpty else {
|
|
98
98
|
logger.debug("no transactions detected on range: \(range.lowerBound)...\(range.upperBound)")
|
|
99
|
+
logger.sync("No transactions detected on range: \(range.lowerBound)...\(range.upperBound)")
|
|
99
100
|
return nil
|
|
100
101
|
}
|
|
101
102
|
|
|
@@ -134,12 +135,10 @@ extension BlockEnhancerImpl: BlockEnhancer {
|
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
operation: .enhancement
|
|
142
|
-
)
|
|
138
|
+
let endTime = Date()
|
|
139
|
+
let logMsg = "Enhanced \(transactions.count) transaction(s) in \(endTime.timeIntervalSince1970 - startTime.timeIntervalSince1970) for range \(range.lowerBound)...\(range.upperBound)"
|
|
140
|
+
logger.sync(logMsg)
|
|
141
|
+
metrics.actionDetail(logMsg, for: .enhance)
|
|
143
142
|
} catch {
|
|
144
143
|
logger.error("error enhancing transactions! \(error)")
|
|
145
144
|
throw error
|
|
@@ -23,7 +23,6 @@ protocol UTXOFetcher {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
struct UTXOFetcherImpl {
|
|
26
|
-
let accountRepository: AccountRepository
|
|
27
26
|
let blockDownloaderService: BlockDownloaderService
|
|
28
27
|
let config: UTXOFetcherConfig
|
|
29
28
|
let rustBackend: ZcashRustBackendWelding
|
|
@@ -37,8 +36,7 @@ extension UTXOFetcherImpl: UTXOFetcher {
|
|
|
37
36
|
) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
|
|
38
37
|
try Task.checkCancellation()
|
|
39
38
|
|
|
40
|
-
let accounts = try
|
|
41
|
-
.map { $0.account }
|
|
39
|
+
let accounts = try await rustBackend.listAccounts()
|
|
42
40
|
|
|
43
41
|
var tAddresses: [TransparentAddress] = []
|
|
44
42
|
for account in accounts {
|
|
@@ -62,7 +60,6 @@ extension UTXOFetcherImpl: UTXOFetcher {
|
|
|
62
60
|
var refreshed: [UnspentTransactionOutputEntity] = []
|
|
63
61
|
var skipped: [UnspentTransactionOutputEntity] = []
|
|
64
62
|
|
|
65
|
-
let startTime = Date()
|
|
66
63
|
let all = Float(utxos.count)
|
|
67
64
|
var counter = Float(0)
|
|
68
65
|
for utxo in utxos {
|
|
@@ -85,13 +82,6 @@ extension UTXOFetcherImpl: UTXOFetcher {
|
|
|
85
82
|
}
|
|
86
83
|
}
|
|
87
84
|
|
|
88
|
-
metrics.pushProgressReport(
|
|
89
|
-
start: startTime,
|
|
90
|
-
end: Date(),
|
|
91
|
-
batchSize: 1,
|
|
92
|
-
operation: .fetchUTXOs
|
|
93
|
-
)
|
|
94
|
-
|
|
95
85
|
let result = (inserted: refreshed, skipped: skipped)
|
|
96
86
|
|
|
97
87
|
if Task.isCancelled {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
2
|
+
// SaplingParametersHandler.swift
|
|
3
|
+
//
|
|
4
4
|
//
|
|
5
5
|
// Created by Lukáš Korba on 23.11.2022.
|
|
6
6
|
//
|
|
@@ -28,11 +28,13 @@ extension SaplingParametersHandlerImpl: SaplingParametersHandler {
|
|
|
28
28
|
try Task.checkCancellation()
|
|
29
29
|
|
|
30
30
|
do {
|
|
31
|
-
let
|
|
31
|
+
let totalSaplingBalance =
|
|
32
|
+
try await rustBackend.getWalletSummary()?.accountBalances[0]?.saplingBalance.total().amount
|
|
33
|
+
?? 0
|
|
32
34
|
let totalTransparentBalance = try await rustBackend.getTransparentBalance(account: Int32(0))
|
|
33
35
|
|
|
34
36
|
// Download Sapling parameters only if sapling funds are detected.
|
|
35
|
-
guard
|
|
37
|
+
guard totalSaplingBalance > 0 || totalTransparentBalance > 0 else { return }
|
|
36
38
|
} catch {
|
|
37
39
|
// if sapling balance can't be detected of we fail to obtain the balance
|
|
38
40
|
// for some reason we shall not proceed to download the parameters and
|
|
@@ -23,6 +23,7 @@ protocol BlockScanner {
|
|
|
23
23
|
struct BlockScannerImpl {
|
|
24
24
|
let config: BlockScannerConfig
|
|
25
25
|
let rustBackend: ZcashRustBackendWelding
|
|
26
|
+
let service: LightWalletService
|
|
26
27
|
let transactionRepository: TransactionRepository
|
|
27
28
|
let metrics: SDKMetrics
|
|
28
29
|
let logger: Logger
|
|
@@ -51,9 +52,14 @@ extension BlockScannerImpl: BlockScanner {
|
|
|
51
52
|
|
|
52
53
|
let batchSize = UInt32(config.scanningBatchSize)
|
|
53
54
|
|
|
55
|
+
// TODO: [#1355] Do more with ScanSummary
|
|
56
|
+
// https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/issues/1355
|
|
57
|
+
let scanSummary: ScanSummary
|
|
54
58
|
let scanStartTime = Date()
|
|
55
59
|
do {
|
|
56
|
-
try await
|
|
60
|
+
let fromState = try await service.getTreeState(BlockID(height: startHeight - 1))
|
|
61
|
+
|
|
62
|
+
scanSummary = try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), fromState: fromState, limit: batchSize)
|
|
57
63
|
} catch {
|
|
58
64
|
logger.debug("block scanning failed with error: \(String(describing: error))")
|
|
59
65
|
throw error
|
|
@@ -61,24 +67,16 @@ extension BlockScannerImpl: BlockScanner {
|
|
|
61
67
|
|
|
62
68
|
let scanFinishTime = Date()
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
lastScannedHeight = startHeight + Int(batchSize) - 1
|
|
67
|
-
|
|
70
|
+
lastScannedHeight = scanSummary.scannedRange.upperBound - 1
|
|
71
|
+
|
|
68
72
|
scannedNewBlocks = previousScannedHeight != lastScannedHeight
|
|
69
73
|
if scannedNewBlocks {
|
|
70
74
|
try await didScan(lastScannedHeight, batchSize)
|
|
71
75
|
|
|
72
|
-
metrics.pushProgressReport(
|
|
73
|
-
start: scanStartTime,
|
|
74
|
-
end: scanFinishTime,
|
|
75
|
-
batchSize: Int(batchSize),
|
|
76
|
-
operation: .scanBlocks
|
|
77
|
-
)
|
|
78
|
-
|
|
79
76
|
let heightCount = lastScannedHeight - previousScannedHeight
|
|
80
77
|
let seconds = scanFinishTime.timeIntervalSinceReferenceDate - scanStartTime.timeIntervalSinceReferenceDate
|
|
81
78
|
logger.debug("Scanned \(heightCount) blocks in \(seconds) seconds")
|
|
79
|
+
logger.sync("Scanned \(heightCount) blocks in \(seconds) seconds")
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
await Task.yield()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BundleCheckpointSource.swift
|
|
3
|
+
//
|
|
4
|
+
//
|
|
5
|
+
// Created by Francisco Gindre on 2023-10-30.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
struct BundleCheckpointSource: CheckpointSource {
|
|
11
|
+
var network: NetworkType
|
|
12
|
+
|
|
13
|
+
var saplingActivation: Checkpoint
|
|
14
|
+
|
|
15
|
+
init(network: NetworkType) {
|
|
16
|
+
self.network = network
|
|
17
|
+
self.saplingActivation = switch network {
|
|
18
|
+
case .mainnet:
|
|
19
|
+
Checkpoint.mainnetMin
|
|
20
|
+
case .testnet:
|
|
21
|
+
Checkpoint.testnetMin
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func latestKnownCheckpoint() -> Checkpoint {
|
|
26
|
+
Checkpoint.birthday(
|
|
27
|
+
with: .max,
|
|
28
|
+
checkpointDirectory: BundleCheckpointURLProvider.default.url(self.network)
|
|
29
|
+
) ?? saplingActivation
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func birthday(for height: BlockHeight) -> Checkpoint {
|
|
33
|
+
Checkpoint.birthday(
|
|
34
|
+
with: height,
|
|
35
|
+
checkpointDirectory: BundleCheckpointURLProvider.default.url(self.network)
|
|
36
|
+
) ?? saplingActivation
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BundleCheckpointURLProvider.swift
|
|
3
|
+
//
|
|
4
|
+
//
|
|
5
|
+
// Created by Francisco Gindre on 2023-10-30.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
struct BundleCheckpointURLProvider {
|
|
11
|
+
var url: (NetworkType) -> URL
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
extension BundleCheckpointURLProvider {
|
|
15
|
+
/// Attempts to resolve the platform. `#if os(macOS)` implies that the build is for a macOS
|
|
16
|
+
/// target, otherwise we assume the build is for an iOS target.
|
|
17
|
+
static let `default` = BundleCheckpointURLProvider { networkType in
|
|
18
|
+
#if os(macOS)
|
|
19
|
+
Self.macOS.url(networkType)
|
|
20
|
+
#else
|
|
21
|
+
Self.iOS.url(networkType)
|
|
22
|
+
#endif
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static let iOS = BundleCheckpointURLProvider(url: { networkType in
|
|
26
|
+
switch networkType {
|
|
27
|
+
case .mainnet:
|
|
28
|
+
return Checkpoint.mainnetCheckpointDirectory
|
|
29
|
+
case .testnet:
|
|
30
|
+
return Checkpoint.testnetCheckpointDirectory
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
/// This variant attempts to retrieve the saplingActivation checkpoint for the given network
|
|
35
|
+
/// type using `Bundle.module.url(forResource:withExtension:subdirectory:localization)`.
|
|
36
|
+
/// If not found it will return `WalletBirthday.mainnetCheckpointDirectory` or
|
|
37
|
+
/// `WalletBirthday.testnetCheckpointDirectory`. This responds to tests failing on a macOS
|
|
38
|
+
/// target because the checkpoint resources would not be found.
|
|
39
|
+
|
|
40
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//
|
|
2
|
-
//
|
|
2
|
+
// Checkpoint+helpers.swift
|
|
3
3
|
// ZcashLightClientKit
|
|
4
4
|
//
|
|
5
5
|
// Created by Francisco Gindre on 7/28/21.
|
|
@@ -64,35 +64,3 @@ extension Checkpoint {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
struct BundleCheckpointURLProvider {
|
|
69
|
-
var url: (NetworkType) -> URL
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
extension BundleCheckpointURLProvider {
|
|
73
|
-
/// Attempts to resolve the platform by checking `#if os(macOS)` build corresponds to a MacOS target
|
|
74
|
-
/// `#else` branch of that condition will assume iOS is the target platform
|
|
75
|
-
static let `default` = BundleCheckpointURLProvider { networkType in
|
|
76
|
-
#if os(macOS)
|
|
77
|
-
Self.macOS.url(networkType)
|
|
78
|
-
#else
|
|
79
|
-
Self.iOS.url(networkType)
|
|
80
|
-
#endif
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
static let iOS = BundleCheckpointURLProvider(url: { networkType in
|
|
84
|
-
switch networkType {
|
|
85
|
-
case .mainnet:
|
|
86
|
-
return Checkpoint.mainnetCheckpointDirectory
|
|
87
|
-
case .testnet:
|
|
88
|
-
return Checkpoint.testnetCheckpointDirectory
|
|
89
|
-
}
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
/// This variant attempts to retrieve the saplingActivation checkpoint for the given network type
|
|
93
|
-
/// using `Bundle.module.url(forResource:withExtension:subdirectory:localization)`
|
|
94
|
-
/// if not found it will return `WalletBirthday.mainnetCheckpointDirectory` or
|
|
95
|
-
/// `WalletBirthday.testnetCheckpointDirectory`. This responds to tests
|
|
96
|
-
/// failing on MacOS target because the checkpoint resources would fail.
|
|
97
|
-
|
|
98
|
-
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
// CheckpointSource.swift
|
|
3
|
+
//
|
|
4
|
+
//
|
|
5
|
+
// Created by Francisco Gindre on 2023-10-30.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
/// A protocol that abstracts the requirements around obtaining wallet checkpoints
|
|
11
|
+
/// (also known as TreeStates).
|
|
12
|
+
protocol CheckpointSource {
|
|
13
|
+
/// `NetworkType` of this Checkpoint source
|
|
14
|
+
var network: NetworkType { get }
|
|
15
|
+
|
|
16
|
+
/// The `Checkpoint` that represents the block in which Sapling was activated
|
|
17
|
+
var saplingActivation: Checkpoint { get }
|
|
18
|
+
|
|
19
|
+
/// Obtain the latest `Checkpoint` in terms of block height known by
|
|
20
|
+
/// this `CheckpointSource`. It is possible that the returned checkpoint
|
|
21
|
+
/// is not the latest checkpoint that exists in the blockchain.
|
|
22
|
+
/// - Returns a `Checkpoint` with the highest height known by this source
|
|
23
|
+
func latestKnownCheckpoint() -> Checkpoint
|
|
24
|
+
|
|
25
|
+
/// Obtain a `Checkpoint` in terms of a "wallet birthday". Wallet birthday
|
|
26
|
+
/// is estimated to be the latest height of the Zcash blockchain at the moment when the wallet was
|
|
27
|
+
/// created.
|
|
28
|
+
/// - Parameter height: Estimated or effective height known for the wallet birthday
|
|
29
|
+
/// - Returns: a `Checkpoint` that will allow the wallet to manage funds from the given `height`
|
|
30
|
+
/// onwards.
|
|
31
|
+
/// - Note: When the user knows the exact height of the first received funds for a wallet,
|
|
32
|
+
/// the effective birthday of that wallet is `transaction.height - 1`.
|
|
33
|
+
func birthday(for height: BlockHeight) -> Checkpoint
|
|
34
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//
|
|
2
|
+
// CheckpointSourceFactory.swift
|
|
3
|
+
//
|
|
4
|
+
//
|
|
5
|
+
// Created by Francisco Gindre on 2023-10-30.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
struct CheckpointSourceFactory {
|
|
11
|
+
static func fromBundle(for network: NetworkType) -> CheckpointSource {
|
|
12
|
+
BundleCheckpointSource(network: network)
|
|
13
|
+
}
|
|
14
|
+
}
|