react-native-zcash 0.5.0 → 0.6.1

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.
Files changed (157) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +7 -3
  3. package/android/build.gradle +5 -4
  4. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2240000.json +8 -0
  5. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2250000.json +8 -0
  6. package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +221 -169
  7. package/android/src/main/java/app/edge/rnzcash/RNZcashPackage.kt +1 -2
  8. package/ios/RNZcash.m +5 -8
  9. package/ios/RNZcash.swift +177 -137
  10. package/ios/ZCashLightClientKit/Block/Actions/Action.swift +98 -0
  11. package/ios/ZCashLightClientKit/Block/Actions/ClearAlreadyScannedBlocksAction.swift +35 -0
  12. package/ios/ZCashLightClientKit/Block/Actions/ClearCacheAction.swift +30 -0
  13. package/ios/ZCashLightClientKit/Block/Actions/DownloadAction.swift +67 -0
  14. package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +97 -0
  15. package/ios/ZCashLightClientKit/Block/Actions/FetchUTXOsAction.swift +33 -0
  16. package/ios/ZCashLightClientKit/Block/Actions/MigrateLegacyCacheDBAction.swift +70 -0
  17. package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +59 -0
  18. package/ios/ZCashLightClientKit/Block/Actions/RewindAction.swift +48 -0
  19. package/ios/ZCashLightClientKit/Block/Actions/SaplingParamsAction.swift +33 -0
  20. package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +95 -0
  21. package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +55 -0
  22. package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +58 -0
  23. package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +60 -0
  24. package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +421 -937
  25. package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +31 -17
  26. package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +2 -2
  27. package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +46 -15
  28. package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +4 -15
  29. package/ios/ZCashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift +4 -4
  30. package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +10 -35
  31. package/ios/ZCashLightClientKit/Block/Utils/CompactBlockProgress.swift +24 -0
  32. package/ios/ZCashLightClientKit/Block/Utils/SyncControlData.swift +25 -0
  33. package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +1 -2
  34. package/ios/ZCashLightClientKit/CombineSynchronizer.swift +2 -5
  35. package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +7 -25
  36. package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +40 -42
  37. package/ios/ZCashLightClientKit/DAO/UnspentTransactionOutputDao.swift +13 -4
  38. package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +9 -0
  39. package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +7 -10
  40. package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
  41. package/ios/ZCashLightClientKit/Error/ZcashError.swift +121 -12
  42. package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +43 -5
  43. package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +72 -6
  44. package/ios/ZCashLightClientKit/Extensions/Bool+ToData.swift +15 -0
  45. package/ios/ZCashLightClientKit/Extensions/Data+ToOtherTypes.swift +18 -0
  46. package/ios/ZCashLightClientKit/Extensions/Int+ToData.swift +15 -0
  47. package/ios/ZCashLightClientKit/Initializer.swift +47 -26
  48. package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +0 -12
  49. package/ios/ZCashLightClientKit/Model/Checkpoint.swift +12 -0
  50. package/ios/ZCashLightClientKit/Model/ScanProgress.swift +29 -0
  51. package/ios/ZCashLightClientKit/Model/ScanRange.swift +31 -0
  52. package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +15 -0
  53. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/compact_formats.pb.swift +150 -46
  54. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/compact_formats.proto +30 -16
  55. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/service.proto +32 -6
  56. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.grpc.swift +259 -22
  57. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.pb.swift +193 -7
  58. package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +8 -0
  59. package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +18 -28
  60. package/ios/ZCashLightClientKit/Repository/CompactBlockRepository.swift +1 -1
  61. package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +2 -6
  62. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2092500.json +8 -0
  63. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2095000.json +8 -0
  64. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2097500.json +8 -0
  65. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2102500.json +8 -0
  66. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2105000.json +8 -0
  67. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2107500.json +8 -0
  68. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2112500.json +8 -0
  69. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2115000.json +8 -0
  70. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2117500.json +8 -0
  71. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2122500.json +8 -0
  72. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2125000.json +8 -0
  73. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2127500.json +8 -0
  74. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2132500.json +8 -0
  75. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2135000.json +8 -0
  76. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2137500.json +8 -0
  77. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2142500.json +8 -0
  78. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2145000.json +8 -0
  79. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2147500.json +8 -0
  80. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2152500.json +8 -0
  81. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2155000.json +8 -0
  82. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2157500.json +8 -0
  83. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2162500.json +8 -0
  84. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2165000.json +8 -0
  85. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2167500.json +8 -0
  86. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2172500.json +8 -0
  87. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2175000.json +8 -0
  88. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2177500.json +8 -0
  89. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2182500.json +8 -0
  90. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2185000.json +8 -0
  91. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2187500.json +8 -0
  92. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2192500.json +8 -0
  93. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2195000.json +8 -0
  94. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2197500.json +8 -0
  95. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2202500.json +8 -0
  96. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2205000.json +8 -0
  97. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2207500.json +8 -0
  98. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2212500.json +8 -0
  99. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2215000.json +8 -0
  100. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2217500.json +8 -0
  101. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2222500.json +8 -0
  102. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2225000.json +8 -0
  103. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2227500.json +8 -0
  104. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2230000.json +8 -0
  105. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2232500.json +8 -0
  106. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2235000.json +8 -0
  107. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2237500.json +8 -0
  108. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2240000.json +8 -0
  109. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2242500.json +8 -0
  110. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2245000.json +8 -0
  111. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2247500.json +8 -0
  112. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2250000.json +8 -0
  113. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2350000.json +8 -0
  114. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2360000.json +8 -0
  115. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2370000.json +8 -0
  116. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2380000.json +8 -0
  117. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2390000.json +8 -0
  118. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2400000.json +8 -0
  119. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2410000.json +8 -0
  120. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2420000.json +8 -0
  121. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2430000.json +8 -0
  122. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2440000.json +8 -0
  123. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2450000.json +8 -0
  124. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2460000.json +8 -0
  125. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2470000.json +8 -0
  126. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2480000.json +8 -0
  127. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2490000.json +8 -0
  128. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2500000.json +8 -0
  129. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2510000.json +8 -0
  130. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2520000.json +8 -0
  131. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2530000.json +8 -0
  132. package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +293 -158
  133. package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +58 -64
  134. package/ios/ZCashLightClientKit/Rust/zcashlc.h +618 -512
  135. package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +2 -8
  136. package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +3 -15
  137. package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +11 -30
  138. package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +41 -50
  139. package/ios/ZCashLightClientKit/Synchronizer.swift +51 -65
  140. package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +2 -2
  141. package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +7 -7
  142. package/ios/ZCashLightClientKit/Utils/OSLogger.swift +3 -3
  143. package/ios/ZCashLightClientKit/Utils/ZcashFileManager.swift +16 -0
  144. package/ios/libzcashlc.xcframework/Info.plist +4 -0
  145. package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
  146. package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
  147. package/lib/rnzcash.rn.js +29 -29
  148. package/lib/rnzcash.rn.js.map +1 -1
  149. package/lib/src/react-native.d.ts +5 -5
  150. package/lib/src/types.d.ts +27 -15
  151. package/package.json +2 -1
  152. package/src/react-native.ts +40 -21
  153. package/src/types.ts +36 -24
  154. package/ios/ZCashLightClientKit/Block/Utils/InternalSyncProgress.swift +0 -200
  155. package/ios/ZCashLightClientKit/Block/Validate/BlockValidator.swift +0 -51
  156. package/ios/ZCashLightClientKit/DAO/BlockDao.swift +0 -112
  157. package/ios/ZCashLightClientKit/Entity/BlockProgress.swift +0 -24
@@ -52,6 +52,14 @@ 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
55
63
  }
56
64
 
57
65
  actor BlockDownloaderImpl {
@@ -62,9 +70,9 @@ actor BlockDownloaderImpl {
62
70
  let service: LightWalletService
63
71
  let downloaderService: BlockDownloaderService
64
72
  let storage: CompactBlockRepository
65
- let internalSyncProgress: InternalSyncProgress
66
73
  let metrics: SDKMetrics
67
74
  let logger: Logger
75
+ var latestDownloadedBlockHeight: BlockHeight = -1
68
76
 
69
77
  private var downloadStreamCreatedAtRange: CompactBlockRange = 0...0
70
78
  private var downloadStream: BlockDownloaderStream?
@@ -80,14 +88,12 @@ actor BlockDownloaderImpl {
80
88
  service: LightWalletService,
81
89
  downloaderService: BlockDownloaderService,
82
90
  storage: CompactBlockRepository,
83
- internalSyncProgress: InternalSyncProgress,
84
91
  metrics: SDKMetrics,
85
92
  logger: Logger
86
93
  ) {
87
94
  self.service = service
88
95
  self.downloaderService = downloaderService
89
96
  self.storage = storage
90
- self.internalSyncProgress = internalSyncProgress
91
97
  self.metrics = metrics
92
98
  self.logger = logger
93
99
  }
@@ -100,8 +106,6 @@ actor BlockDownloaderImpl {
100
106
  throw ZcashError.blockDownloadSyncRangeNotSet
101
107
  }
102
108
 
103
- let latestDownloadedBlockHeight = await internalSyncProgress.load(.latestDownloadedBlockHeight)
104
-
105
109
  let downloadFrom = max(syncRange.lowerBound, latestDownloadedBlockHeight + 1)
106
110
  let downloadTo = min(downloadToHeight, syncRange.upperBound)
107
111
 
@@ -195,13 +199,8 @@ actor BlockDownloaderImpl {
195
199
  var counter = 0
196
200
  var lastDownloadedBlockHeight = -1
197
201
 
198
- let pushMetrics: (BlockHeight, Date, Date) -> Void = { [metrics] lastDownloadedBlockHeight, startTime, finishTime in
202
+ let pushMetrics: (BlockHeight, Date, Date) -> Void = { [metrics] _, startTime, finishTime in
199
203
  metrics.pushProgressReport(
200
- progress: BlockProgress(
201
- startHeight: totalProgressRange.lowerBound,
202
- targetHeight: totalProgressRange.upperBound,
203
- progressHeight: Int(lastDownloadedBlockHeight)
204
- ),
205
204
  start: startTime,
206
205
  end: finishTime,
207
206
  batchSize: maxBlockBufferSize,
@@ -220,7 +219,7 @@ actor BlockDownloaderImpl {
220
219
  if buffer.count >= maxBlockBufferSize {
221
220
  let finishTime = Date()
222
221
  try await storage.write(blocks: buffer)
223
- await blocksBufferWritten(buffer)
222
+ try await blocksBufferWritten(buffer)
224
223
  buffer.removeAll(keepingCapacity: true)
225
224
 
226
225
  pushMetrics(block.height, startTime, finishTime)
@@ -235,21 +234,36 @@ actor BlockDownloaderImpl {
235
234
  }
236
235
 
237
236
  try await storage.write(blocks: buffer)
238
- await blocksBufferWritten(buffer)
237
+ try await blocksBufferWritten(buffer)
239
238
  }
240
239
 
241
- private func blocksBufferWritten(_ buffer: [ZcashCompactBlock]) async {
240
+ private func blocksBufferWritten(_ buffer: [ZcashCompactBlock]) async throws {
242
241
  guard let lastBlock = buffer.last else { return }
243
- await internalSyncProgress.set(lastBlock.height, .latestDownloadedBlockHeight)
242
+ latestDownloadedBlockHeight = lastBlock.height
244
243
  }
245
244
  }
246
245
 
247
246
  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
+
248
261
  func setDownloadLimit(_ limit: BlockHeight) async {
249
262
  downloadToHeight = limit
250
263
  }
251
264
 
252
265
  func setSyncRange(_ range: CompactBlockRange, batchSize: Int) async throws {
266
+ guard range != syncRange else { return }
253
267
  downloadStream = nil
254
268
  self.batchSize = batchSize
255
269
  syncRange = range
@@ -282,13 +296,13 @@ extension BlockDownloaderImpl: BlockDownloader {
282
296
 
283
297
  func waitUntilRequestedBlocksAreDownloaded(in range: CompactBlockRange) async throws {
284
298
  logger.debug("Waiting until requested blocks are downloaded at \(range)")
285
- var latestDownloadedBlock = await internalSyncProgress.load(.latestDownloadedBlockHeight)
299
+ var latestDownloadedBlock = latestDownloadedBlockHeight
286
300
  while latestDownloadedBlock < range.upperBound {
287
301
  if let error = lastError {
288
302
  throw error
289
303
  }
290
304
  try await Task.sleep(milliseconds: 10)
291
- latestDownloadedBlock = await internalSyncProgress.load(.latestDownloadedBlockHeight)
305
+ latestDownloadedBlock = latestDownloadedBlockHeight
292
306
  }
293
307
  logger.debug("Waiting done. Blocks are downloaded at \(range)")
294
308
  }
@@ -107,8 +107,8 @@ extension BlockDownloaderServiceImpl: BlockDownloaderService {
107
107
  try await self.storage.rewind(to: height)
108
108
  }
109
109
 
110
- func lastDownloadedBlockHeight() async -> BlockHeight {
111
- await self.storage.latestHeight()
110
+ func lastDownloadedBlockHeight() async throws -> BlockHeight {
111
+ try await self.storage.latestHeight()
112
112
  }
113
113
 
114
114
  func fetchTransaction(txId: Data) async throws -> ZcashTransaction.Fetched {
@@ -7,13 +7,56 @@
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
+
10
54
  protocol BlockEnhancer {
11
- func enhance(at range: CompactBlockRange, didEnhance: (EnhancementProgress) async -> Void) async throws -> [ZcashTransaction.Overview]?
55
+ func enhance(at range: CompactBlockRange, didEnhance: @escaping (EnhancementProgress) async -> Void) async throws -> [ZcashTransaction.Overview]?
12
56
  }
13
57
 
14
58
  struct BlockEnhancerImpl {
15
59
  let blockDownloaderService: BlockDownloaderService
16
- let internalSyncProgress: InternalSyncProgress
17
60
  let rustBackend: ZcashRustBackendWelding
18
61
  let transactionRepository: TransactionRepository
19
62
  let metrics: SDKMetrics
@@ -38,7 +81,7 @@ struct BlockEnhancerImpl {
38
81
  }
39
82
 
40
83
  extension BlockEnhancerImpl: BlockEnhancer {
41
- func enhance(at range: CompactBlockRange, didEnhance: (EnhancementProgress) async -> Void) async throws -> [ZcashTransaction.Overview]? {
84
+ func enhance(at range: CompactBlockRange, didEnhance: @escaping (EnhancementProgress) async -> Void) async throws -> [ZcashTransaction.Overview]? {
42
85
  try Task.checkCancellation()
43
86
 
44
87
  logger.debug("Started Enhancing range: \(range)")
@@ -52,7 +95,6 @@ extension BlockEnhancerImpl: BlockEnhancer {
52
95
  let transactions = try await transactionRepository.find(in: range, limit: Int.max, kind: .all)
53
96
 
54
97
  guard !transactions.isEmpty else {
55
- await internalSyncProgress.set(range.upperBound, .latestEnhancedHeight)
56
98
  logger.debug("no transactions detected on range: \(range.lowerBound)...\(range.upperBound)")
57
99
  return nil
58
100
  }
@@ -82,10 +124,6 @@ extension BlockEnhancerImpl: BlockEnhancer {
82
124
  )
83
125
 
84
126
  await didEnhance(progress)
85
-
86
- if let minedHeight = confirmedTx.minedHeight {
87
- await internalSyncProgress.set(minedHeight, .latestEnhancedHeight)
88
- }
89
127
  } catch {
90
128
  retries += 1
91
129
  logger.error("could not enhance txId \(transaction.rawID.toHexStringTxId()) - Error: \(error)")
@@ -97,11 +135,6 @@ extension BlockEnhancerImpl: BlockEnhancer {
97
135
  }
98
136
 
99
137
  metrics.pushProgressReport(
100
- progress: BlockProgress(
101
- startHeight: range.lowerBound,
102
- targetHeight: range.upperBound,
103
- progressHeight: range.upperBound
104
- ),
105
138
  start: startTime,
106
139
  end: Date(),
107
140
  batchSize: range.count,
@@ -111,8 +144,6 @@ extension BlockEnhancerImpl: BlockEnhancer {
111
144
  logger.error("error enhancing transactions! \(error)")
112
145
  throw error
113
146
  }
114
-
115
- await internalSyncProgress.set(range.upperBound, .latestEnhancedHeight)
116
147
 
117
148
  if Task.isCancelled {
118
149
  logger.debug("Warning: compactBlockEnhancement on range \(range) cancelled")
@@ -18,8 +18,7 @@ struct UTXOFetcherConfig {
18
18
 
19
19
  protocol UTXOFetcher {
20
20
  func fetch(
21
- at range: CompactBlockRange,
22
- didFetch: (Float) async -> Void
21
+ didFetch: @escaping (Float) async -> Void
23
22
  ) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity])
24
23
  }
25
24
 
@@ -27,7 +26,6 @@ struct UTXOFetcherImpl {
27
26
  let accountRepository: AccountRepository
28
27
  let blockDownloaderService: BlockDownloaderService
29
28
  let config: UTXOFetcherConfig
30
- let internalSyncProgress: InternalSyncProgress
31
29
  let rustBackend: ZcashRustBackendWelding
32
30
  let metrics: SDKMetrics
33
31
  let logger: Logger
@@ -35,8 +33,7 @@ struct UTXOFetcherImpl {
35
33
 
36
34
  extension UTXOFetcherImpl: UTXOFetcher {
37
35
  func fetch(
38
- at range: CompactBlockRange,
39
- didFetch: (Float) async -> Void
36
+ didFetch: @escaping (Float) async -> Void
40
37
  ) async throws -> (inserted: [UnspentTransactionOutputEntity], skipped: [UnspentTransactionOutputEntity]) {
41
38
  try Task.checkCancellation()
42
39
 
@@ -82,7 +79,6 @@ extension UTXOFetcherImpl: UTXOFetcher {
82
79
 
83
80
  counter += 1
84
81
  await didFetch(counter / all)
85
- await internalSyncProgress.set(utxo.height, .latestUTXOFetchedHeight)
86
82
  } catch {
87
83
  logger.error("failed to put utxo - error: \(error)")
88
84
  skipped.append(utxo)
@@ -90,23 +86,16 @@ extension UTXOFetcherImpl: UTXOFetcher {
90
86
  }
91
87
 
92
88
  metrics.pushProgressReport(
93
- progress: BlockProgress(
94
- startHeight: range.lowerBound,
95
- targetHeight: range.upperBound,
96
- progressHeight: range.upperBound
97
- ),
98
89
  start: startTime,
99
90
  end: Date(),
100
- batchSize: range.count,
91
+ batchSize: 1,
101
92
  operation: .fetchUTXOs
102
93
  )
103
94
 
104
95
  let result = (inserted: refreshed, skipped: skipped)
105
96
 
106
- await internalSyncProgress.set(range.upperBound, .latestUTXOFetchedHeight)
107
-
108
97
  if Task.isCancelled {
109
- logger.debug("Warning: fetchUnspentTxOutputs on range \(range) cancelled")
98
+ logger.debug("Warning: fetchUnspentTxOutputs cancelled")
110
99
  }
111
100
 
112
101
  return result
@@ -64,8 +64,8 @@ extension FSCompactBlockRepository: CompactBlockRepository {
64
64
  }
65
65
  }
66
66
 
67
- func latestHeight() async -> BlockHeight {
68
- await metadataStore.latestHeight()
67
+ func latestHeight() async throws -> BlockHeight {
68
+ try 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 -> BlockHeight
254
+ let latestHeight: () async throws -> 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
- await rustBackend.latestCachedBlockHeight()
271
+ try await rustBackend.latestCachedBlockHeight()
272
272
  }
273
273
  }
274
274
  }
@@ -16,8 +16,7 @@ protocol BlockScanner {
16
16
  @discardableResult
17
17
  func scanBlocks(
18
18
  at range: CompactBlockRange,
19
- totalProgressRange: CompactBlockRange,
20
- didScan: @escaping (BlockHeight) async -> Void
19
+ didScan: @escaping (BlockHeight, UInt32) async throws -> Void
21
20
  ) async throws -> BlockHeight
22
21
  }
23
22
 
@@ -27,20 +26,18 @@ struct BlockScannerImpl {
27
26
  let transactionRepository: TransactionRepository
28
27
  let metrics: SDKMetrics
29
28
  let logger: Logger
30
- let latestBlocksDataProvider: LatestBlocksDataProvider
31
29
  }
32
30
 
33
31
  extension BlockScannerImpl: BlockScanner {
34
32
  @discardableResult
35
33
  func scanBlocks(
36
34
  at range: CompactBlockRange,
37
- totalProgressRange: CompactBlockRange,
38
- didScan: @escaping (BlockHeight) async -> Void
35
+ didScan: @escaping (BlockHeight, UInt32) async throws -> Void
39
36
  ) async throws -> BlockHeight {
40
37
  logger.debug("Going to scan blocks in range: \(range)")
41
38
  try Task.checkCancellation()
42
39
 
43
- let scanStartHeight = try await transactionRepository.lastScannedHeight()
40
+ let scanStartHeight = range.lowerBound
44
41
  let targetScanHeight = range.upperBound
45
42
 
46
43
  var scannedNewBlocks = false
@@ -50,13 +47,13 @@ extension BlockScannerImpl: BlockScanner {
50
47
  try Task.checkCancellation()
51
48
 
52
49
  let previousScannedHeight = lastScannedHeight
50
+ let startHeight = previousScannedHeight + 1
53
51
 
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)
52
+ let batchSize = UInt32(config.scanningBatchSize)
56
53
 
57
54
  let scanStartTime = Date()
58
55
  do {
59
- try await self.rustBackend.scanBlocks(limit: batchSize)
56
+ try await self.rustBackend.scanBlocks(fromHeight: Int32(startHeight), limit: batchSize)
60
57
  } catch {
61
58
  logger.debug("block scanning failed with error: \(String(describing: error))")
62
59
  throw error
@@ -64,24 +61,15 @@ extension BlockScannerImpl: BlockScanner {
64
61
 
65
62
  let scanFinishTime = Date()
66
63
 
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
- }
64
+ // TODO: [#1259] potential bug when rustBackend.scanBlocks scan less blocks than batchSize,
65
+ // https://github.com/zcash/ZcashLightClientKit/issues/1259
66
+ lastScannedHeight = startHeight + Int(batchSize) - 1
72
67
 
73
68
  scannedNewBlocks = previousScannedHeight != lastScannedHeight
74
69
  if scannedNewBlocks {
75
- await didScan(lastScannedHeight)
76
-
77
- let progress = BlockProgress(
78
- startHeight: totalProgressRange.lowerBound,
79
- targetHeight: totalProgressRange.upperBound,
80
- progressHeight: lastScannedHeight
81
- )
70
+ try await didScan(lastScannedHeight, batchSize)
82
71
 
83
72
  metrics.pushProgressReport(
84
- progress: progress,
85
73
  start: scanStartTime,
86
74
  end: scanFinishTime,
87
75
  batchSize: Int(batchSize),
@@ -98,17 +86,4 @@ extension BlockScannerImpl: BlockScanner {
98
86
 
99
87
  return lastScannedHeight
100
88
  }
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
- }
114
89
  }
@@ -0,0 +1,24 @@
1
+ //
2
+ // CompactBlockProgress.swift
3
+ //
4
+ //
5
+ // Created by Michal Fousek on 11.05.2023.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ final actor CompactBlockProgress {
11
+ static let zero = CompactBlockProgress()
12
+
13
+ var progress: Float = 0.0
14
+
15
+ func hasProgressUpdated(_ event: CompactBlockProcessor.Event) -> Bool {
16
+ guard case .syncProgress(let update) = event else {
17
+ return false
18
+ }
19
+
20
+ progress = update
21
+
22
+ return true
23
+ }
24
+ }
@@ -0,0 +1,25 @@
1
+ //
2
+ // SyncControlData.swift
3
+ //
4
+ //
5
+ // Created by Michal Fousek on 23.11.2022.
6
+ //
7
+
8
+ import Foundation
9
+
10
+ struct SyncControlData: Equatable {
11
+ /// The tip of the blockchain
12
+ let latestBlockHeight: BlockHeight
13
+ /// The last height that has been scanned
14
+ let latestScannedHeight: BlockHeight?
15
+ /// The height from the enhancement must start
16
+ let firstUnenhancedHeight: BlockHeight?
17
+
18
+ static var empty: SyncControlData {
19
+ SyncControlData(
20
+ latestBlockHeight: 0,
21
+ latestScannedHeight: nil,
22
+ firstUnenhancedHeight: nil
23
+ )
24
+ }
25
+ }
@@ -24,8 +24,8 @@ public protocol ClosureSynchronizer {
24
24
 
25
25
  func prepare(
26
26
  with seed: [UInt8]?,
27
- viewingKeys: [UnifiedFullViewingKey],
28
27
  walletBirthday: BlockHeight,
28
+ for walletMode: WalletInitMode,
29
29
  completion: @escaping (Result<Initializer.InitializationResult, Error>) -> Void
30
30
  )
31
31
 
@@ -51,7 +51,6 @@ public protocol ClosureSynchronizer {
51
51
  completion: @escaping (Result<ZcashTransaction.Overview, Error>) -> Void
52
52
  )
53
53
 
54
- func pendingTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
55
54
  func clearedTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
56
55
  func sentTranscations(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
57
56
  func receivedTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void)
@@ -24,8 +24,8 @@ public protocol CombineSynchronizer {
24
24
 
25
25
  func prepare(
26
26
  with seed: [UInt8]?,
27
- viewingKeys: [UnifiedFullViewingKey],
28
- walletBirthday: BlockHeight
27
+ walletBirthday: BlockHeight,
28
+ for walletMode: WalletInitMode
29
29
  ) -> SinglePublisher<Initializer.InitializationResult, Error>
30
30
 
31
31
  func start(retry: Bool) -> CompletablePublisher<Error>
@@ -49,7 +49,6 @@ public protocol CombineSynchronizer {
49
49
  ) -> SinglePublisher<ZcashTransaction.Overview, Error>
50
50
 
51
51
  var allTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
52
- var pendingTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
53
52
  var sentTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
54
53
  var receivedTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> { get }
55
54
 
@@ -59,8 +58,6 @@ public protocol CombineSynchronizer {
59
58
 
60
59
  func getRecipients(for transaction: ZcashTransaction.Overview) -> SinglePublisher<[TransactionRecipient], Never>
61
60
 
62
- func allPendingTransactions() -> SinglePublisher<[ZcashTransaction.Overview], Error>
63
-
64
61
  func allTransactions(from transaction: ZcashTransaction.Overview, limit: Int) -> SinglePublisher<[ZcashTransaction.Overview], Error>
65
62
 
66
63
  func latestHeight() -> SinglePublisher<BlockHeight, Error>
@@ -88,17 +88,10 @@ public enum ZcashSDK {
88
88
  // MARK: Defaults
89
89
 
90
90
  /// Default size of batches of blocks to request from the compact block service. Which was used both for scanning and downloading.
91
- /// consider basing your code assumptions on `DefaultDownloadBatch` and `DefaultScanningBatch` instead.
92
- @available(*, deprecated, message: "this value is being deprecated in favor of `DefaultDownloadBatch` and `DefaultScanningBatch`")
93
91
  public static let DefaultBatchSize = 100
94
-
95
- /// Default batch size for downloading blocks for the compact block processor. Be careful with this number. This amount of blocks is held in
96
- /// memory at some point of the sync process.
97
- /// This values can't be smaller than `DefaultScanningBatch`. Otherwise bad things will happen.
98
- public static let DefaultDownloadBatch = 100
99
-
100
- /// Default batch size for scanning blocks for the compact block processor
101
- public static let DefaultScanningBatch = 100
92
+
93
+ /// Default batch size for enhancing transactions for the compact block processor
94
+ public static let DefaultEnhanceBatch = 1000
102
95
 
103
96
  /// Default amount of time, in in seconds, to poll for new blocks. Typically, this should be about half the average
104
97
  /// block time.
@@ -161,19 +154,13 @@ public protocol NetworkConstants {
161
154
  /// Default prefix for db filenames
162
155
  static var defaultDbNamePrefix: String { get }
163
156
 
164
- /// fixed height where the SDK considers that the ZIP-321 was deployed. This is a workaround
165
- /// for librustzcash not figuring out the tx fee from the tx itself.
166
- static var feeChangeHeight: BlockHeight { get }
167
-
168
- /// Returns the default fee according to the blockheight. see [ZIP-313](https://zips.z.cash/zip-0313)
169
- static func defaultFee(for height: BlockHeight) -> Zatoshi
157
+ /// Returns the default fee, hardcoded 10k Zatoshi is the minimum ZIP 317 fee
158
+ static func defaultFee() -> Zatoshi
170
159
  }
171
160
 
172
161
  public extension NetworkConstants {
173
- static func defaultFee(for height: BlockHeight = BlockHeight.max) -> Zatoshi {
174
- guard height >= feeChangeHeight else { return Zatoshi(10_000) }
175
-
176
- return Zatoshi(1_000)
162
+ static func defaultFee() -> Zatoshi {
163
+ Zatoshi(10_000)
177
164
  }
178
165
  }
179
166
 
@@ -191,8 +178,6 @@ public enum ZcashSDKMainnetConstants: NetworkConstants {
191
178
  public static let defaultCacheDbName = "caches.db"
192
179
 
193
180
  public static let defaultDbNamePrefix = "ZcashSdk_mainnet_"
194
-
195
- public static let feeChangeHeight: BlockHeight = 1_077_550
196
181
  }
197
182
 
198
183
  public enum ZcashSDKTestnetConstants: NetworkConstants {
@@ -209,7 +194,4 @@ public enum ZcashSDKTestnetConstants: NetworkConstants {
209
194
  public static let defaultFsBlockDbRootName = "fs_cache"
210
195
 
211
196
  public static let defaultDbNamePrefix = "ZcashSdk_testnet_"
212
-
213
- /// Estimated height where wallets are supposed to change the fee
214
- public static let feeChangeHeight: BlockHeight = 1_028_500
215
197
  }