react-native-zcash 0.6.11 → 0.6.13

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 (148) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/ios/ZCashLightClientKit/Block/Actions/Action.swift +98 -0
  3. package/ios/ZCashLightClientKit/Block/Actions/ClearAlreadyScannedBlocksAction.swift +35 -0
  4. package/ios/ZCashLightClientKit/Block/Actions/ClearCacheAction.swift +30 -0
  5. package/ios/ZCashLightClientKit/Block/Actions/DownloadAction.swift +67 -0
  6. package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +97 -0
  7. package/ios/ZCashLightClientKit/Block/Actions/FetchUTXOsAction.swift +33 -0
  8. package/ios/ZCashLightClientKit/Block/Actions/MigrateLegacyCacheDBAction.swift +70 -0
  9. package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +60 -0
  10. package/ios/ZCashLightClientKit/Block/Actions/RewindAction.swift +48 -0
  11. package/ios/ZCashLightClientKit/Block/Actions/SaplingParamsAction.swift +33 -0
  12. package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +95 -0
  13. package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +55 -0
  14. package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +58 -0
  15. package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +60 -0
  16. package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +425 -937
  17. package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +31 -17
  18. package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +2 -2
  19. package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +46 -15
  20. package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +4 -15
  21. package/ios/ZCashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift +4 -4
  22. package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +10 -35
  23. package/ios/ZCashLightClientKit/Block/Utils/CompactBlockProgress.swift +24 -0
  24. package/ios/ZCashLightClientKit/Block/Utils/SyncControlData.swift +25 -0
  25. package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +1 -2
  26. package/ios/ZCashLightClientKit/CombineSynchronizer.swift +2 -5
  27. package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +13 -26
  28. package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +40 -42
  29. package/ios/ZCashLightClientKit/DAO/UnspentTransactionOutputDao.swift +13 -4
  30. package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +9 -0
  31. package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +7 -10
  32. package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
  33. package/ios/ZCashLightClientKit/Error/ZcashError.swift +121 -12
  34. package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +43 -5
  35. package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +72 -6
  36. package/ios/ZCashLightClientKit/Extensions/Bool+ToData.swift +15 -0
  37. package/ios/ZCashLightClientKit/Extensions/Data+ToOtherTypes.swift +18 -0
  38. package/ios/ZCashLightClientKit/Extensions/Int+ToData.swift +15 -0
  39. package/ios/ZCashLightClientKit/Initializer.swift +47 -26
  40. package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +0 -12
  41. package/ios/ZCashLightClientKit/Model/Checkpoint.swift +12 -0
  42. package/ios/ZCashLightClientKit/Model/ScanProgress.swift +29 -0
  43. package/ios/ZCashLightClientKit/Model/ScanRange.swift +31 -0
  44. package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +15 -0
  45. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/compact_formats.pb.swift +150 -46
  46. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/compact_formats.proto +30 -16
  47. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/service.proto +32 -6
  48. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.grpc.swift +259 -22
  49. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.pb.swift +193 -7
  50. package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +8 -0
  51. package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +18 -28
  52. package/ios/ZCashLightClientKit/Repository/CompactBlockRepository.swift +1 -1
  53. package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +2 -6
  54. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2092500.json +8 -0
  55. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2095000.json +8 -0
  56. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2097500.json +8 -0
  57. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2102500.json +8 -0
  58. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2105000.json +8 -0
  59. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2107500.json +8 -0
  60. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2112500.json +8 -0
  61. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2115000.json +8 -0
  62. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2117500.json +8 -0
  63. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2122500.json +8 -0
  64. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2125000.json +8 -0
  65. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2127500.json +8 -0
  66. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2132500.json +8 -0
  67. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2135000.json +8 -0
  68. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2137500.json +8 -0
  69. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2142500.json +8 -0
  70. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2145000.json +8 -0
  71. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2147500.json +8 -0
  72. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2152500.json +8 -0
  73. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2155000.json +8 -0
  74. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2157500.json +8 -0
  75. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2162500.json +8 -0
  76. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2165000.json +8 -0
  77. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2167500.json +8 -0
  78. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2172500.json +8 -0
  79. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2175000.json +8 -0
  80. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2177500.json +8 -0
  81. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2182500.json +8 -0
  82. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2185000.json +8 -0
  83. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2187500.json +8 -0
  84. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2192500.json +8 -0
  85. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2195000.json +8 -0
  86. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2197500.json +8 -0
  87. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2202500.json +8 -0
  88. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2205000.json +8 -0
  89. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2207500.json +8 -0
  90. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2212500.json +8 -0
  91. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2215000.json +8 -0
  92. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2217500.json +8 -0
  93. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2222500.json +8 -0
  94. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2225000.json +8 -0
  95. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2227500.json +8 -0
  96. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2232500.json +8 -0
  97. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2235000.json +8 -0
  98. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2237500.json +8 -0
  99. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2242500.json +8 -0
  100. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2245000.json +8 -0
  101. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2247500.json +8 -0
  102. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2252500.json +8 -0
  103. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2255000.json +8 -0
  104. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2257500.json +8 -0
  105. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2262500.json +8 -0
  106. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2265000.json +8 -0
  107. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2267500.json +8 -0
  108. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2350000.json +8 -0
  109. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2360000.json +8 -0
  110. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2370000.json +8 -0
  111. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2380000.json +8 -0
  112. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2390000.json +8 -0
  113. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2400000.json +8 -0
  114. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2410000.json +8 -0
  115. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2420000.json +8 -0
  116. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2430000.json +8 -0
  117. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2440000.json +8 -0
  118. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2450000.json +8 -0
  119. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2460000.json +8 -0
  120. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2470000.json +8 -0
  121. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2480000.json +8 -0
  122. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2490000.json +8 -0
  123. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2500000.json +8 -0
  124. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2510000.json +8 -0
  125. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2520000.json +8 -0
  126. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2530000.json +8 -0
  127. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2540000.json +8 -0
  128. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2550000.json +8 -0
  129. package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +293 -158
  130. package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +58 -64
  131. package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +2 -8
  132. package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +3 -15
  133. package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +11 -30
  134. package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +41 -50
  135. package/ios/ZCashLightClientKit/Synchronizer.swift +51 -65
  136. package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +2 -2
  137. package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +7 -7
  138. package/ios/ZCashLightClientKit/Utils/OSLogger.swift +3 -3
  139. package/ios/ZCashLightClientKit/Utils/ZcashFileManager.swift +16 -0
  140. package/ios/libzcashlc.xcframework/Info.plist +9 -5
  141. package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
  142. package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
  143. package/package.json +2 -2
  144. package/ios/ZCashLightClientKit/Block/Utils/InternalSyncProgress.swift +0 -200
  145. package/ios/ZCashLightClientKit/Block/Validate/BlockValidator.swift +0 -51
  146. package/ios/ZCashLightClientKit/DAO/BlockDao.swift +0 -112
  147. package/ios/ZCashLightClientKit/Entity/BlockProgress.swift +0 -24
  148. package/ios/ZCashLightClientKit/Rust/zcashlc.h +0 -1051
@@ -35,9 +35,11 @@ protocol ZcashRustBackendWelding {
35
35
  /// have been received by the currently-available account (in order to enable
36
36
  /// automated account recovery).
37
37
  /// - parameter seed: byte array of the zip32 seed
38
+ /// - parameter treeState: The TreeState Protobuf object for the height prior to the account birthday
39
+ /// - parameter recoverUntil: the fully-scanned height up to which the account will be treated as "being recovered"
38
40
  /// - Returns: The `UnifiedSpendingKey` structs for the number of accounts created
39
41
  /// - Throws: `rustCreateAccount`.
40
- func createAccount(seed: [UInt8]) async throws -> UnifiedSpendingKey
42
+ func createAccount(seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?) async throws -> UnifiedSpendingKey
41
43
 
42
44
  /// Creates a transaction to the given address from the given account
43
45
  /// - Parameter usk: `UnifiedSpendingKey` for the account that controls the funds to be spent.
@@ -50,7 +52,7 @@ protocol ZcashRustBackendWelding {
50
52
  to address: String,
51
53
  value: Int64,
52
54
  memo: MemoBytes?
53
- ) async throws -> Int64
55
+ ) async throws -> Data
54
56
 
55
57
  /// Scans a transaction for any information that can be decrypted by the accounts in the wallet, and saves it to the wallet.
56
58
  /// - parameter tx: the transaction to decrypt
@@ -89,14 +91,10 @@ protocol ZcashRustBackendWelding {
89
91
  /// - `rustGetNextAvailableAddressInvalidAddress` if generated unified address isn't valid.
90
92
  func getNextAvailableAddress(account: Int32) async throws -> UnifiedAddress
91
93
 
92
- /// Get received memo from note.
93
- /// - parameter idNote: note_id of note where the memo is located
94
- func getReceivedMemo(idNote: Int64) async -> Memo?
95
-
96
- /// Get sent memo from note.
97
- /// - parameter idNote: note_id of note where the memo is located
98
- /// - Returns: a `Memo` if any
99
- func getSentMemo(idNote: Int64) async -> Memo?
94
+ /// Get memo from note.
95
+ /// - parameter txId: ID of transaction containing the note
96
+ /// - parameter outputIndex: output index of note
97
+ func getMemo(txId: Data, outputIndex: UInt16) async throws -> Memo?
100
98
 
101
99
  /// Get the verified cached transparent balance for the given address
102
100
  /// - parameter account; the account index to query
@@ -105,14 +103,6 @@ protocol ZcashRustBackendWelding {
105
103
  /// - `rustGetTransparentBalance` if rust layer returns error.
106
104
  func getTransparentBalance(account: Int32) async throws -> Int64
107
105
 
108
- /// Initialize the accounts table from a set of unified full viewing keys.
109
- /// - Note: this function should only be used when restoring an existing seed phrase. when creating a new wallet, use `createAccount()` instead.
110
- /// - Parameter ufvks: an array of UnifiedFullViewingKeys
111
- /// - Throws:
112
- /// - `rustInitAccountsTableViewingKeyCotainsNullBytes` if any of the key in `ufvks` contains null bytes before end.
113
- /// - `rustInitAccountsTableViewingKeyIsInvalid` if any of the key in `ufvks` isn't valid.
114
- func initAccountsTable(ufvks: [UnifiedFullViewingKey]) async throws
115
-
116
106
  /// Initializes the data db. This will performs any migrations needed on the sqlite file
117
107
  /// provided. Some migrations might need that callers provide the seed bytes.
118
108
  /// - Parameter seed: ZIP-32 compliant seed bytes for this wallet
@@ -122,23 +112,6 @@ protocol ZcashRustBackendWelding {
122
112
  /// Throws `rustInitDataDb` if rust layer returns error.
123
113
  func initDataDb(seed: [UInt8]?) async throws -> DbInitResult
124
114
 
125
- /// Initialize the blocks table from a given checkpoint (heigh, hash, time, saplingTree and networkType).
126
- /// - parameter height: represents the block height of the given checkpoint
127
- /// - parameter hash: hash of the merkle tree
128
- /// - parameter time: in milliseconds from reference
129
- /// - parameter saplingTree: hash of the sapling tree
130
- /// - Throws:
131
- /// - `rustInitBlocksTableHashContainsNullBytes` if `hash` contains null bytes before end.
132
- /// - `rustInitBlocksTableSaplingTreeContainsNullBytes` if `saplingTree` contains null bytes before end.
133
- /// - `rustInitBlocksTableDataDbNotEmpty` if data DB is not empty.
134
- /// - `rustInitBlocksTable` if rust layer returns error.
135
- func initBlocksTable(
136
- height: Int32,
137
- hash: String,
138
- time: UInt32,
139
- saplingTree: String
140
- ) async throws
141
-
142
115
  /// Returns a list of the transparent receivers for the diversified unified addresses that have
143
116
  /// been allocated for the provided account.
144
117
  /// - parameter account: index of the given account
@@ -159,26 +132,6 @@ protocol ZcashRustBackendWelding {
159
132
  /// - `rustGetVerifiedTransparentBalance` if rust layer returns error.
160
133
  func getVerifiedTransparentBalance(account: Int32) async throws -> Int64
161
134
 
162
- /// Checks that the scanned blocks in the data database, when combined with the recent
163
- /// `CompactBlock`s in the cache database, form a valid chain.
164
- /// This function is built on the core assumption that the information provided in the
165
- /// cache database is more likely to be accurate than the previously-scanned information.
166
- /// This follows from the design (and trust) assumption that the `lightwalletd` server
167
- /// provides accurate block information as of the time it was requested.
168
- /// - parameter fsBlockDbRoot: `URL` pointing to the filesystem root directory where the fsBlock cache is.
169
- /// this directory is expected to contain a `/blocks` sub-directory with the blocks stored in the convened filename
170
- /// format `{height}-{hash}-block`. This directory has must be granted both write and read permissions.
171
- /// - parameter dbData: location of the data db file
172
- /// - parameter networkType: the network type
173
- /// - parameter limit: a limit to validate a fixed number of blocks instead of the whole cache.
174
- /// - Throws:
175
- /// - `rustValidateCombinedChainValidationFailed` if there was an error during validation unrelated to chain validity.
176
- /// - `rustValidateCombinedChainInvalidChain(upperBound)` if the combined chain is invalid. `upperBound` is the height of the highest invalid
177
- /// block(on the assumption that the highest block in the cache database is correct).
178
- ///
179
- /// - Important: This function does not mutate either of the databases.
180
- func validateCombinedChain(limit: UInt32) async throws
181
-
182
135
  /// Resets the state of the database to only contain block and transaction information up to the given height. clears up all derived data as well
183
136
  /// - parameter height: height to rewind to.
184
137
  /// - Throws: `rustRewindToHeight` if rust layer returns error.
@@ -190,21 +143,62 @@ protocol ZcashRustBackendWelding {
190
143
  /// - Throws: `rustRewindCacheToHeight` if rust layer returns error.
191
144
  func rewindCacheToHeight(height: Int32) async throws
192
145
 
146
+ func putSaplingSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws
147
+
148
+ /// Updates the wallet's view of the blockchain.
149
+ ///
150
+ /// This method is used to provide the wallet with information about the state of the blockchain,
151
+ /// and detect any previously scanned data that needs to be re-validated before proceeding with
152
+ /// scanning. It should be called at wallet startup prior to calling `suggestScanRanges`
153
+ /// in order to provide the wallet with the information it needs to correctly prioritize scanning
154
+ /// operations.
155
+ func updateChainTip(height: Int32) async throws
156
+
157
+ /// Returns the height to which the wallet has been fully scanned.
158
+ ///
159
+ /// This is the height for which the wallet has fully trial-decrypted this and all
160
+ /// preceding blocks beginning with the wallet's birthday height.
161
+ func fullyScannedHeight() async throws -> BlockHeight?
162
+
163
+ /// Returns the maximum height that the wallet has scanned.
164
+ ///
165
+ /// If the wallet is fully synced, this will be equivalent to `fullyScannedHeight`;
166
+ /// otherwise the maximal scanned height is likely to be greater than the fully scanned
167
+ /// height due to the fact that out-of-order scanning can leave gaps.
168
+ func maxScannedHeight() async throws -> BlockHeight?
169
+
170
+ /// Returns the scan progress derived from the current wallet state.
171
+ func getScanProgress() async throws -> ScanProgress?
172
+
173
+ /// Returns a list of suggested scan ranges based upon the current wallet state.
174
+ ///
175
+ /// This method should only be used in cases where the `CompactBlock` data that will be
176
+ /// made available to `scanBlocks` for the requested block ranges includes note
177
+ /// commitment tree size information for each block; or else the scan is likely to fail if
178
+ /// notes belonging to the wallet are detected.
179
+ func suggestScanRanges() async throws -> [ScanRange]
180
+
193
181
  /// Scans new blocks added to the cache for any transactions received by the tracked
194
- /// accounts.
195
- /// This function pays attention only to cached blocks with heights greater than the
196
- /// highest scanned block in `db_data`. Cached blocks with lower heights are not verified
197
- /// against previously-scanned blocks. In particular, this function **assumes** that the
198
- /// caller is handling rollbacks.
182
+ /// accounts, while checking that they form a valid chan.
183
+ ///
184
+ /// This function is built on the core assumption that the information provided in the
185
+ /// block cache is more likely to be accurate than the previously-scanned information.
186
+ /// This follows from the design (and trust) assumption that the `lightwalletd` server
187
+ /// provides accurate block information as of the time it was requested.
188
+ ///
189
+ /// This function **assumes** that the caller is handling rollbacks.
190
+ ///
199
191
  /// For brand-new light client databases, this function starts scanning from the Sapling
200
192
  /// activation height. This height can be fast-forwarded to a more recent block by calling
201
193
  /// [`initBlocksTable`] before this function.
194
+ ///
202
195
  /// Scanned blocks are required to be height-sequential. If a block is missing from the
203
196
  /// cache, an error will be signalled.
204
197
  ///
205
- /// - parameter limit: scan up to limit blocks. pass 0 to set no limit.
198
+ /// - parameter fromHeight: scan starting from the given height.
199
+ /// - parameter limit: scan up to limit blocks.
206
200
  /// - Throws: `rustScanBlocks` if rust layer returns error.
207
- func scanBlocks(limit: UInt32) async throws
201
+ func scanBlocks(fromHeight: Int32, limit: UInt32) async throws
208
202
 
209
203
  /// Upserts a UTXO into the data db database
210
204
  /// - parameter txid: the txid bytes for the UTXO
@@ -229,7 +223,7 @@ protocol ZcashRustBackendWelding {
229
223
  usk: UnifiedSpendingKey,
230
224
  memo: MemoBytes?,
231
225
  shieldingThreshold: Zatoshi
232
- ) async throws -> Int64
226
+ ) async throws -> Data
233
227
 
234
228
  /// Gets the consensus branch id for the given height
235
229
  /// - Parameter height: the height you what to know the branch id for
@@ -252,5 +246,5 @@ protocol ZcashRustBackendWelding {
252
246
  /// this directory is expected to contain a `/blocks` sub-directory with the blocks stored in the convened filename
253
247
  /// format `{height}-{hash}-block`. This directory has must be granted both write and read permissions.
254
248
  /// - Returns `BlockHeight` of the latest cached block or `.empty` if no blocks are stored.
255
- func latestCachedBlockHeight() async -> BlockHeight
249
+ func latestCachedBlockHeight() async throws -> BlockHeight
256
250
  }
@@ -33,12 +33,12 @@ extension ClosureSDKSynchronizer: ClosureSynchronizer {
33
33
 
34
34
  public func prepare(
35
35
  with seed: [UInt8]?,
36
- viewingKeys: [UnifiedFullViewingKey],
37
36
  walletBirthday: BlockHeight,
37
+ for walletMode: WalletInitMode,
38
38
  completion: @escaping (Result<Initializer.InitializationResult, Error>) -> Void
39
39
  ) {
40
40
  AsyncToClosureGateway.executeThrowingAction(completion) {
41
- return try await self.synchronizer.prepare(with: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday)
41
+ return try await self.synchronizer.prepare(with: seed, walletBirthday: walletBirthday, for: walletMode)
42
42
  }
43
43
  }
44
44
 
@@ -93,12 +93,6 @@ extension ClosureSDKSynchronizer: ClosureSynchronizer {
93
93
  }
94
94
  }
95
95
 
96
- public func pendingTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void) {
97
- AsyncToClosureGateway.executeAction(completion) {
98
- await self.synchronizer.pendingTransactions
99
- }
100
- }
101
-
102
96
  public func clearedTransactions(completion: @escaping ([ZcashTransaction.Overview]) -> Void) {
103
97
  AsyncToClosureGateway.executeAction(completion) {
104
98
  await self.synchronizer.transactions
@@ -33,11 +33,11 @@ extension CombineSDKSynchronizer: CombineSynchronizer {
33
33
 
34
34
  public func prepare(
35
35
  with seed: [UInt8]?,
36
- viewingKeys: [UnifiedFullViewingKey],
37
- walletBirthday: BlockHeight
36
+ walletBirthday: BlockHeight,
37
+ for walletMode: WalletInitMode
38
38
  ) -> SinglePublisher<Initializer.InitializationResult, Error> {
39
39
  AsyncToCombineGateway.executeThrowingAction() {
40
- return try await self.synchronizer.prepare(with: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday)
40
+ return try await self.synchronizer.prepare(with: seed, walletBirthday: walletBirthday, for: walletMode)
41
41
  }
42
42
  }
43
43
 
@@ -90,12 +90,6 @@ extension CombineSDKSynchronizer: CombineSynchronizer {
90
90
  }
91
91
  }
92
92
 
93
- public var pendingTransactions: AnyPublisher<[ZcashTransaction.Overview], Never> {
94
- AsyncToCombineGateway.executeAction() {
95
- await self.synchronizer.pendingTransactions
96
- }
97
- }
98
-
99
93
  public var allTransactions: SinglePublisher<[ZcashTransaction.Overview], Never> {
100
94
  AsyncToCombineGateway.executeAction() {
101
95
  await self.synchronizer.transactions
@@ -128,12 +122,6 @@ extension CombineSDKSynchronizer: CombineSynchronizer {
128
122
  }
129
123
  }
130
124
 
131
- public func allPendingTransactions() -> AnyPublisher<[ZcashTransaction.Overview], Error> {
132
- AsyncToCombineGateway.executeThrowingAction() {
133
- try await self.synchronizer.allPendingTransactions()
134
- }
135
- }
136
-
137
125
  public func allTransactions(from transaction: ZcashTransaction.Overview, limit: Int) -> SinglePublisher<[ZcashTransaction.Overview], Error> {
138
126
  AsyncToCombineGateway.executeThrowingAction() {
139
127
  try await self.synchronizer.allTransactions(from: transaction, limit: limit)
@@ -14,7 +14,8 @@ enum Dependencies {
14
14
  alias: ZcashSynchronizerAlias,
15
15
  networkType: NetworkType,
16
16
  endpoint: LightWalletEndpoint,
17
- loggingPolicy: Initializer.LoggingPolicy = .default(.debug)
17
+ loggingPolicy: Initializer.LoggingPolicy = .default(.debug),
18
+ enableBackendTracing: Bool = false
18
19
  ) {
19
20
  container.register(type: Logger.self, isSingleton: true) { _ in
20
21
  let logger: Logger
@@ -36,7 +37,8 @@ enum Dependencies {
36
37
  fsBlockDbRoot: urls.fsBlockDbRoot,
37
38
  spendParamsPath: urls.spendParamsURL,
38
39
  outputParamsPath: urls.outputParamsURL,
39
- networkType: networkType
40
+ networkType: networkType,
41
+ enableTracing: enableBackendTracing
40
42
  )
41
43
  }
42
44
 
@@ -78,18 +80,17 @@ enum Dependencies {
78
80
 
79
81
  container.register(type: LatestBlocksDataProvider.self, isSingleton: true) { di in
80
82
  let service = di.resolve(LightWalletService.self)
81
- let transactionRepository = di.resolve(TransactionRepository.self)
83
+ let rustBackend = di.resolve(ZcashRustBackendWelding.self)
82
84
 
83
- return LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
85
+ return LatestBlocksDataProviderImpl(service: service, rustBackend: rustBackend)
84
86
  }
85
87
 
86
88
  container.register(type: SyncSessionIDGenerator.self, isSingleton: false) { _ in
87
89
  UniqueSyncSessionIDGenerator()
88
90
  }
89
-
90
- container.register(type: InternalSyncProgress.self, isSingleton: true) { di in
91
- let logger = di.resolve(Logger.self)
92
- return InternalSyncProgress(alias: alias, storage: UserDefaults.standard, logger: logger)
91
+
92
+ container.register(type: ZcashFileManager.self, isSingleton: true) { _ in
93
+ FileManager.default
93
94
  }
94
95
  }
95
96
 
@@ -102,7 +103,6 @@ enum Dependencies {
102
103
  let service = di.resolve(LightWalletService.self)
103
104
  let blockDownloaderService = di.resolve(BlockDownloaderService.self)
104
105
  let storage = di.resolve(CompactBlockRepository.self)
105
- let internalSyncProgress = di.resolve(InternalSyncProgress.self)
106
106
  let metrics = di.resolve(SDKMetrics.self)
107
107
  let logger = di.resolve(Logger.self)
108
108
 
@@ -110,19 +110,6 @@ enum Dependencies {
110
110
  service: service,
111
111
  downloaderService: blockDownloaderService,
112
112
  storage: storage,
113
- internalSyncProgress: internalSyncProgress,
114
- metrics: metrics,
115
- logger: logger
116
- )
117
- }
118
-
119
- container.register(type: BlockValidator.self, isSingleton: true) { di in
120
- let rustBackend = di.resolve(ZcashRustBackendWelding.self)
121
- let metrics = di.resolve(SDKMetrics.self)
122
- let logger = di.resolve(Logger.self)
123
-
124
- return BlockValidatorImpl(
125
- rustBackend: rustBackend,
126
113
  metrics: metrics,
127
114
  logger: logger
128
115
  )
@@ -133,11 +120,10 @@ enum Dependencies {
133
120
  let transactionRepository = di.resolve(TransactionRepository.self)
134
121
  let metrics = di.resolve(SDKMetrics.self)
135
122
  let logger = di.resolve(Logger.self)
136
- let latestBlocksDataProvider = di.resolve(LatestBlocksDataProvider.self)
137
123
 
138
124
  let blockScannerConfig = BlockScannerConfig(
139
125
  networkType: config.network.networkType,
140
- scanningBatchSize: config.scanningBatchSize
126
+ scanningBatchSize: config.batchSize
141
127
  )
142
128
 
143
129
  return BlockScannerImpl(
@@ -145,14 +131,12 @@ enum Dependencies {
145
131
  rustBackend: rustBackend,
146
132
  transactionRepository: transactionRepository,
147
133
  metrics: metrics,
148
- logger: logger,
149
- latestBlocksDataProvider: latestBlocksDataProvider
134
+ logger: logger
150
135
  )
151
136
  }
152
137
 
153
138
  container.register(type: BlockEnhancer.self, isSingleton: true) { di in
154
139
  let blockDownloaderService = di.resolve(BlockDownloaderService.self)
155
- let internalSyncProgress = di.resolve(InternalSyncProgress.self)
156
140
  let rustBackend = di.resolve(ZcashRustBackendWelding.self)
157
141
  let transactionRepository = di.resolve(TransactionRepository.self)
158
142
  let metrics = di.resolve(SDKMetrics.self)
@@ -160,7 +144,6 @@ enum Dependencies {
160
144
 
161
145
  return BlockEnhancerImpl(
162
146
  blockDownloaderService: blockDownloaderService,
163
- internalSyncProgress: internalSyncProgress,
164
147
  rustBackend: rustBackend,
165
148
  transactionRepository: transactionRepository,
166
149
  metrics: metrics,
@@ -171,7 +154,6 @@ enum Dependencies {
171
154
  container.register(type: UTXOFetcher.self, isSingleton: true) { di in
172
155
  let blockDownloaderService = di.resolve(BlockDownloaderService.self)
173
156
  let utxoFetcherConfig = UTXOFetcherConfig(walletBirthdayProvider: config.walletBirthdayProvider)
174
- let internalSyncProgress = di.resolve(InternalSyncProgress.self)
175
157
  let rustBackend = di.resolve(ZcashRustBackendWelding.self)
176
158
  let metrics = di.resolve(SDKMetrics.self)
177
159
  let logger = di.resolve(Logger.self)
@@ -180,7 +162,6 @@ enum Dependencies {
180
162
  accountRepository: accountRepository,
181
163
  blockDownloaderService: blockDownloaderService,
182
164
  config: utxoFetcherConfig,
183
- internalSyncProgress: internalSyncProgress,
184
165
  rustBackend: rustBackend,
185
166
  metrics: metrics,
186
167
  logger: logger
@@ -24,7 +24,7 @@ public class SDKSynchronizer: Synchronizer {
24
24
 
25
25
  public let metrics: SDKMetrics
26
26
  public let logger: Logger
27
-
27
+
28
28
  // Don't read this variable directly. Use `status` instead. And don't update this variable directly use `updateStatus()` methods instead.
29
29
  private var underlyingStatus: GenericActor<InternalSyncStatus>
30
30
  var status: InternalSyncStatus {
@@ -102,9 +102,9 @@ public class SDKSynchronizer: Synchronizer {
102
102
  }
103
103
  }
104
104
 
105
- func updateStatus(_ newValue: InternalSyncStatus) async {
105
+ func updateStatus(_ newValue: InternalSyncStatus, updateExternalStatus: Bool = true) async {
106
106
  let oldValue = await underlyingStatus.update(newValue)
107
- await notify(oldStatus: oldValue, newStatus: newValue)
107
+ await notify(oldStatus: oldValue, newStatus: newValue, updateExternalStatus: updateExternalStatus)
108
108
  }
109
109
 
110
110
  func throwIfUnprepared() throws {
@@ -127,8 +127,8 @@ public class SDKSynchronizer: Synchronizer {
127
127
 
128
128
  public func prepare(
129
129
  with seed: [UInt8]?,
130
- viewingKeys: [UnifiedFullViewingKey],
131
- walletBirthday: BlockHeight
130
+ walletBirthday: BlockHeight,
131
+ for walletMode: WalletInitMode
132
132
  ) async throws -> Initializer.InitializationResult {
133
133
  guard await status == .unprepared else { return .success }
134
134
 
@@ -138,14 +138,14 @@ public class SDKSynchronizer: Synchronizer {
138
138
 
139
139
  try await utxoRepository.initialise()
140
140
 
141
- if case .seedRequired = try await self.initializer.initialize(with: seed, viewingKeys: viewingKeys, walletBirthday: walletBirthday) {
141
+ if case .seedRequired = try await self.initializer.initialize(with: seed, walletBirthday: walletBirthday, for: walletMode) {
142
142
  return .seedRequired
143
143
  }
144
-
144
+
145
145
  await latestBlocksDataProvider.updateWalletBirthday(initializer.walletBirthday)
146
146
  await latestBlocksDataProvider.updateScannedData()
147
147
 
148
- await updateStatus(.disconnected)
148
+ await updateStatus(.disconnected, updateExternalStatus: false)
149
149
 
150
150
  return .success
151
151
  }
@@ -157,14 +157,14 @@ public class SDKSynchronizer: Synchronizer {
157
157
  case .unprepared:
158
158
  throw ZcashError.synchronizerNotPrepared
159
159
 
160
- case .syncing, .enhancing, .fetching:
160
+ case .syncing:
161
161
  logger.warn("warning: Synchronizer started when already running. Next sync process will be started when the current one stops.")
162
162
  /// This may look strange but `CompactBlockProcessor` has mechanisms which can handle this situation. So we are fine with calling
163
163
  /// it's start here.
164
164
  await blockProcessor.start(retry: retry)
165
165
 
166
166
  case .stopped, .synced, .disconnected, .error:
167
- await updateStatus(.syncing(.nullProgress))
167
+ await updateStatus(.syncing(0))
168
168
  syncStartDate = Date()
169
169
  await blockProcessor.start(retry: retry)
170
170
  }
@@ -197,15 +197,14 @@ public class SDKSynchronizer: Synchronizer {
197
197
 
198
198
  // MARK: Handle CompactBlockProcessor.Flow
199
199
 
200
- // swiftlint:disable:next cyclomatic_complexity
201
200
  private func subscribeToProcessorEvents(_ processor: CompactBlockProcessor) async {
202
201
  let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
203
202
  switch event {
204
203
  case let .failed(error):
205
204
  await self?.failed(error: error)
206
205
 
207
- case let .finished(height, foundBlocks):
208
- await self?.finished(lastScannedHeight: height, foundBlocks: foundBlocks)
206
+ case let .finished(height):
207
+ await self?.finished(lastScannedHeight: height)
209
208
 
210
209
  case let .foundTransactions(transactions, range):
211
210
  self?.foundTransactions(transactions: transactions, in: range)
@@ -217,17 +216,14 @@ public class SDKSynchronizer: Synchronizer {
217
216
  case let .progressUpdated(progress):
218
217
  await self?.progressUpdated(progress: progress)
219
218
 
219
+ case .syncProgress:
220
+ break
221
+
220
222
  case let .storedUTXOs(utxos):
221
223
  self?.storedUTXOs(utxos: utxos)
222
224
 
223
- case .startedEnhancing:
224
- await self?.updateStatus(.enhancing(.zero))
225
-
226
- case .startedFetching:
227
- await self?.updateStatus(.fetching(0))
228
-
229
- case .startedSyncing:
230
- await self?.updateStatus(.syncing(.nullProgress))
225
+ case .startedEnhancing, .startedFetching, .startedSyncing:
226
+ break
231
227
 
232
228
  case .stopped:
233
229
  await self?.updateStatus(.stopped)
@@ -244,7 +240,7 @@ public class SDKSynchronizer: Synchronizer {
244
240
  await updateStatus(.error(error))
245
241
  }
246
242
 
247
- private func finished(lastScannedHeight: BlockHeight, foundBlocks: Bool) async {
243
+ private func finished(lastScannedHeight: BlockHeight) async {
248
244
  await latestBlocksDataProvider.updateScannedData()
249
245
 
250
246
  await updateStatus(.synced)
@@ -263,7 +259,7 @@ public class SDKSynchronizer: Synchronizer {
263
259
  }
264
260
  }
265
261
 
266
- private func progressUpdated(progress: CompactBlockProgress) async {
262
+ private func progressUpdated(progress: Float) async {
267
263
  let newStatus = InternalSyncStatus(progress)
268
264
  await updateStatus(newStatus)
269
265
  }
@@ -315,8 +311,8 @@ public class SDKSynchronizer: Synchronizer {
315
311
  let accountIndex = Int(spendingKey.account)
316
312
  let tBalance = try await self.getTransparentBalance(accountIndex: accountIndex)
317
313
 
318
- // Verify that at least there are funds for the fee. Ideally this logic will be improved by the shielding wallet.
319
- guard tBalance.verified >= self.network.constants.defaultFee(for: await self.latestBlocksDataProvider.latestScannedHeight) else {
314
+ // Verify that at least there are funds for the fee. Ideally this logic will be improved by the shielding wallet.
315
+ guard tBalance.verified >= self.network.constants.defaultFee() else {
320
316
  throw ZcashError.synchronizerShieldFundsInsuficientTransparentFunds
321
317
  }
322
318
 
@@ -369,12 +365,6 @@ public class SDKSynchronizer: Synchronizer {
369
365
  try await transactionRepository.findReceived(offset: 0, limit: Int.max)
370
366
  }
371
367
 
372
- public func allPendingTransactions() async throws -> [ZcashTransaction.Overview] {
373
- let latestScannedHeight = self.latestState.latestScannedHeight
374
-
375
- return try await transactionRepository.findPendingTransactions(latestHeight: latestScannedHeight, offset: 0, limit: .max)
376
- }
377
-
378
368
  public func allTransactions() async throws -> [ZcashTransaction.Overview] {
379
369
  return try await transactionRepository.find(offset: 0, limit: Int.max, kind: .all)
380
370
  }
@@ -396,15 +386,15 @@ public class SDKSynchronizer: Synchronizer {
396
386
  }
397
387
 
398
388
  public func getRecipients(for transaction: ZcashTransaction.Overview) async -> [TransactionRecipient] {
399
- return (try? await transactionRepository.getRecipients(for: transaction.id)) ?? []
389
+ return (try? await transactionRepository.getRecipients(for: transaction.rawID)) ?? []
400
390
  }
401
391
 
402
392
  public func getTransactionOutputs(for transaction: ZcashTransaction.Overview) async -> [ZcashTransaction.Output] {
403
- return (try? await transactionRepository.getTransactionOutputs(for: transaction.id)) ?? []
393
+ return (try? await transactionRepository.getTransactionOutputs(for: transaction.rawID)) ?? []
404
394
  }
405
395
 
406
396
  public func latestHeight() async throws -> BlockHeight {
407
- try await blockProcessor.blockDownloaderService.latestBlockHeight()
397
+ try await blockProcessor.latestHeight()
408
398
  }
409
399
 
410
400
  public func latestUTXOs(address: String) async throws -> [UnspentTransactionOutputEntity] {
@@ -503,7 +493,11 @@ public class SDKSynchronizer: Synchronizer {
503
493
  }
504
494
  )
505
495
 
506
- await blockProcessor.rewind(context: context)
496
+ do {
497
+ try await blockProcessor.rewind(context: context)
498
+ } catch {
499
+ subject.send(completion: .failure(error))
500
+ }
507
501
  }
508
502
  return subject.eraseToAnyPublisher()
509
503
  }
@@ -533,12 +527,16 @@ public class SDKSynchronizer: Synchronizer {
533
527
  }
534
528
  )
535
529
 
536
- await blockProcessor.wipe(context: context)
530
+ do {
531
+ try await blockProcessor.wipe(context: context)
532
+ } catch {
533
+ subject.send(completion: .failure(error))
534
+ }
537
535
  }
538
536
 
539
537
  return subject.eraseToAnyPublisher()
540
538
  }
541
-
539
+
542
540
  // MARK: notify state
543
541
 
544
542
  private func snapshotState(status: InternalSyncStatus) async -> SynchronizerState {
@@ -550,13 +548,11 @@ public class SDKSynchronizer: Synchronizer {
550
548
  ),
551
549
  transparentBalance: (try? await blockProcessor.getTransparentBalance(accountIndex: 0)) ?? .zero,
552
550
  internalSyncStatus: status,
553
- latestScannedHeight: latestBlocksDataProvider.latestScannedHeight,
554
- latestBlockHeight: latestBlocksDataProvider.latestBlockHeight,
555
- latestScannedTime: latestBlocksDataProvider.latestScannedTime
551
+ latestBlockHeight: latestBlocksDataProvider.latestBlockHeight
556
552
  )
557
553
  }
558
554
 
559
- private func notify(oldStatus: InternalSyncStatus, newStatus: InternalSyncStatus) async {
555
+ private func notify(oldStatus: InternalSyncStatus, newStatus: InternalSyncStatus, updateExternalStatus: Bool = true) async {
560
556
  guard oldStatus != newStatus else { return }
561
557
 
562
558
  let newState: SynchronizerState
@@ -579,7 +575,10 @@ public class SDKSynchronizer: Synchronizer {
579
575
  }
580
576
 
581
577
  latestState = newState
582
- updateStateStream(with: latestState)
578
+
579
+ if updateExternalStatus {
580
+ updateStateStream(with: latestState)
581
+ }
583
582
  }
584
583
 
585
584
  private func updateStateStream(with newState: SynchronizerState) {
@@ -613,12 +612,6 @@ extension SDKSynchronizer {
613
612
  (try? await allReceivedTransactions()) ?? []
614
613
  }
615
614
  }
616
-
617
- public var pendingTransactions: [ZcashTransaction.Overview] {
618
- get async {
619
- (try? await allPendingTransactions()) ?? []
620
- }
621
- }
622
615
  }
623
616
 
624
617
  extension InternalSyncStatus {
@@ -626,8 +619,6 @@ extension InternalSyncStatus {
626
619
  switch (self, otherStatus) {
627
620
  case (.unprepared, .unprepared): return false
628
621
  case (.syncing, .syncing): return false
629
- case (.enhancing, .enhancing): return false
630
- case (.fetching, .fetching): return false
631
622
  case (.synced, .synced): return false
632
623
  case (.stopped, .stopped): return false
633
624
  case (.disconnected, .disconnected): return false