react-native-zcash 0.6.10 → 0.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2460000.json +8 -0
  3. package/ios/ZCashLightClientKit/Block/CompactBlockProcessor.swift +937 -425
  4. package/ios/ZCashLightClientKit/Block/Download/BlockDownloader.swift +17 -31
  5. package/ios/ZCashLightClientKit/Block/Download/BlockDownloaderService.swift +2 -2
  6. package/ios/ZCashLightClientKit/Block/Enhance/BlockEnhancer.swift +15 -46
  7. package/ios/ZCashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift +15 -4
  8. package/ios/ZCashLightClientKit/Block/FilesystemStorage/FSCompactBlockRepository.swift +4 -4
  9. package/ios/ZCashLightClientKit/Block/Scan/BlockScanner.swift +35 -10
  10. package/ios/ZCashLightClientKit/Block/Utils/InternalSyncProgress.swift +200 -0
  11. package/ios/ZCashLightClientKit/Block/Validate/BlockValidator.swift +51 -0
  12. package/ios/ZCashLightClientKit/ClosureSynchronizer.swift +2 -1
  13. package/ios/ZCashLightClientKit/CombineSynchronizer.swift +5 -2
  14. package/ios/ZCashLightClientKit/Constants/ZcashSDK.swift +26 -13
  15. package/ios/ZCashLightClientKit/DAO/BlockDao.swift +112 -0
  16. package/ios/ZCashLightClientKit/DAO/TransactionDao.swift +42 -40
  17. package/ios/ZCashLightClientKit/DAO/UnspentTransactionOutputDao.swift +4 -13
  18. package/ios/ZCashLightClientKit/Entity/AccountEntity.swift +0 -9
  19. package/ios/ZCashLightClientKit/Entity/BlockProgress.swift +24 -0
  20. package/ios/ZCashLightClientKit/Entity/TransactionEntity.swift +10 -7
  21. package/ios/ZCashLightClientKit/Error/Sourcery/generateErrorCode.sh +1 -1
  22. package/ios/ZCashLightClientKit/Error/ZcashError.swift +12 -121
  23. package/ios/ZCashLightClientKit/Error/ZcashErrorCode.swift +5 -43
  24. package/ios/ZCashLightClientKit/Error/ZcashErrorCodeDefinition.swift +6 -72
  25. package/ios/ZCashLightClientKit/Initializer.swift +26 -47
  26. package/ios/ZCashLightClientKit/Metrics/SDKMetrics.swift +12 -0
  27. package/ios/ZCashLightClientKit/Model/Checkpoint.swift +0 -12
  28. package/ios/ZCashLightClientKit/Modules/Service/GRPC/LightWalletGRPCService.swift +0 -15
  29. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/compact_formats.pb.swift +46 -150
  30. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/compact_formats.proto +16 -30
  31. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/proto/service.proto +6 -32
  32. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.grpc.swift +22 -259
  33. package/ios/ZCashLightClientKit/Modules/Service/GRPC/ProtoBuf/service.pb.swift +7 -193
  34. package/ios/ZCashLightClientKit/Modules/Service/LightWalletService.swift +0 -8
  35. package/ios/ZCashLightClientKit/Providers/LatestBlocksDataProvider.swift +28 -18
  36. package/ios/ZCashLightClientKit/Repository/CompactBlockRepository.swift +1 -1
  37. package/ios/ZCashLightClientKit/Repository/TransactionRepository.swift +6 -2
  38. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2460000.json +8 -0
  39. package/ios/ZCashLightClientKit/Rust/ZcashRustBackend.swift +158 -293
  40. package/ios/ZCashLightClientKit/Rust/ZcashRustBackendWelding.swift +64 -58
  41. package/ios/ZCashLightClientKit/Rust/zcashlc.h +513 -619
  42. package/ios/ZCashLightClientKit/Synchronizer/ClosureSDKSynchronizer.swift +8 -2
  43. package/ios/ZCashLightClientKit/Synchronizer/CombineSDKSynchronizer.swift +15 -3
  44. package/ios/ZCashLightClientKit/Synchronizer/Dependencies.swift +30 -11
  45. package/ios/ZCashLightClientKit/Synchronizer/SDKSynchronizer.swift +50 -41
  46. package/ios/ZCashLightClientKit/Synchronizer.swift +65 -51
  47. package/ios/ZCashLightClientKit/Transaction/TransactionEncoder.swift +2 -2
  48. package/ios/ZCashLightClientKit/Transaction/WalletTransactionEncoder.swift +7 -7
  49. package/ios/ZCashLightClientKit/Utils/OSLogger.swift +3 -3
  50. package/ios/libzcashlc.xcframework/Info.plist +0 -4
  51. package/ios/libzcashlc.xcframework/ios-arm64/libzcashlc.a +0 -0
  52. package/ios/libzcashlc.xcframework/ios-arm64_x86_64-simulator/libzcashlc.a +0 -0
  53. package/package.json +1 -1
  54. package/ios/ZCashLightClientKit/Block/Actions/Action.swift +0 -98
  55. package/ios/ZCashLightClientKit/Block/Actions/ClearAlreadyScannedBlocksAction.swift +0 -35
  56. package/ios/ZCashLightClientKit/Block/Actions/ClearCacheAction.swift +0 -30
  57. package/ios/ZCashLightClientKit/Block/Actions/DownloadAction.swift +0 -67
  58. package/ios/ZCashLightClientKit/Block/Actions/EnhanceAction.swift +0 -97
  59. package/ios/ZCashLightClientKit/Block/Actions/FetchUTXOsAction.swift +0 -33
  60. package/ios/ZCashLightClientKit/Block/Actions/MigrateLegacyCacheDBAction.swift +0 -70
  61. package/ios/ZCashLightClientKit/Block/Actions/ProcessSuggestedScanRangesAction.swift +0 -60
  62. package/ios/ZCashLightClientKit/Block/Actions/RewindAction.swift +0 -48
  63. package/ios/ZCashLightClientKit/Block/Actions/SaplingParamsAction.swift +0 -33
  64. package/ios/ZCashLightClientKit/Block/Actions/ScanAction.swift +0 -95
  65. package/ios/ZCashLightClientKit/Block/Actions/UpdateChainTipAction.swift +0 -55
  66. package/ios/ZCashLightClientKit/Block/Actions/UpdateSubtreeRootsAction.swift +0 -58
  67. package/ios/ZCashLightClientKit/Block/Actions/ValidateServerAction.swift +0 -60
  68. package/ios/ZCashLightClientKit/Block/Utils/CompactBlockProgress.swift +0 -24
  69. package/ios/ZCashLightClientKit/Block/Utils/SyncControlData.swift +0 -25
  70. package/ios/ZCashLightClientKit/Extensions/Bool+ToData.swift +0 -15
  71. package/ios/ZCashLightClientKit/Extensions/Data+ToOtherTypes.swift +0 -18
  72. package/ios/ZCashLightClientKit/Extensions/Int+ToData.swift +0 -15
  73. package/ios/ZCashLightClientKit/Model/ScanProgress.swift +0 -29
  74. package/ios/ZCashLightClientKit/Model/ScanRange.swift +0 -31
  75. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2092500.json +0 -8
  76. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2095000.json +0 -8
  77. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2097500.json +0 -8
  78. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2102500.json +0 -8
  79. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2105000.json +0 -8
  80. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2107500.json +0 -8
  81. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2112500.json +0 -8
  82. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2115000.json +0 -8
  83. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2117500.json +0 -8
  84. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2122500.json +0 -8
  85. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2125000.json +0 -8
  86. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2127500.json +0 -8
  87. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2132500.json +0 -8
  88. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2135000.json +0 -8
  89. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2137500.json +0 -8
  90. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2142500.json +0 -8
  91. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2145000.json +0 -8
  92. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2147500.json +0 -8
  93. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2152500.json +0 -8
  94. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2155000.json +0 -8
  95. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2157500.json +0 -8
  96. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2162500.json +0 -8
  97. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2165000.json +0 -8
  98. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2167500.json +0 -8
  99. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2172500.json +0 -8
  100. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2175000.json +0 -8
  101. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2177500.json +0 -8
  102. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2182500.json +0 -8
  103. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2185000.json +0 -8
  104. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2187500.json +0 -8
  105. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2192500.json +0 -8
  106. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2195000.json +0 -8
  107. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2197500.json +0 -8
  108. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2202500.json +0 -8
  109. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2205000.json +0 -8
  110. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2207500.json +0 -8
  111. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2212500.json +0 -8
  112. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2215000.json +0 -8
  113. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2217500.json +0 -8
  114. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2222500.json +0 -8
  115. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2225000.json +0 -8
  116. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2227500.json +0 -8
  117. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2232500.json +0 -8
  118. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2235000.json +0 -8
  119. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2237500.json +0 -8
  120. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2242500.json +0 -8
  121. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2245000.json +0 -8
  122. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2247500.json +0 -8
  123. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2252500.json +0 -8
  124. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2255000.json +0 -8
  125. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2257500.json +0 -8
  126. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2262500.json +0 -8
  127. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2265000.json +0 -8
  128. package/ios/ZCashLightClientKit/Resources/checkpoints/mainnet/2267500.json +0 -8
  129. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2350000.json +0 -8
  130. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2360000.json +0 -8
  131. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2370000.json +0 -8
  132. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2380000.json +0 -8
  133. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2390000.json +0 -8
  134. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2400000.json +0 -8
  135. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2410000.json +0 -8
  136. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2420000.json +0 -8
  137. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2430000.json +0 -8
  138. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2440000.json +0 -8
  139. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2450000.json +0 -8
  140. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2460000.json +0 -8
  141. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2470000.json +0 -8
  142. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2480000.json +0 -8
  143. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2490000.json +0 -8
  144. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2500000.json +0 -8
  145. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2510000.json +0 -8
  146. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2520000.json +0 -8
  147. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2530000.json +0 -8
  148. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2540000.json +0 -8
  149. package/ios/ZCashLightClientKit/Resources/checkpoints/testnet/2550000.json +0 -8
  150. package/ios/ZCashLightClientKit/Utils/ZcashFileManager.swift +0 -16
@@ -9,8 +9,6 @@
9
9
  import Foundation
10
10
 
11
11
 
12
- let globalDBLock = NSLock()
13
-
14
12
  actor ZcashRustBackend: ZcashRustBackendWelding {
15
13
  let minimumConfirmations: UInt32 = 10
16
14
  let useZIP317Fees = false
@@ -23,7 +21,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
23
21
 
24
22
  nonisolated let networkType: NetworkType
25
23
 
26
- static var tracingEnabled = false
27
24
  /// Creates instance of `ZcashRustBackend`.
28
25
  /// - Parameters:
29
26
  /// - dbData: `URL` pointing to file where data database will be.
@@ -33,43 +30,23 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
33
30
  /// - spendParamsPath: `URL` pointing to spend parameters file.
34
31
  /// - outputParamsPath: `URL` pointing to output parameters file.
35
32
  /// - networkType: Network type to use.
36
- /// - enableTracing: this sets up whether the tracing system will dump logs onto the OSLogger system or not.
37
- /// **Important note:** this will enable the tracing **for all instances** of ZcashRustBackend, not only for this one.
38
- init(dbData: URL, fsBlockDbRoot: URL, spendParamsPath: URL, outputParamsPath: URL, networkType: NetworkType, enableTracing: Bool = false) {
33
+ init(dbData: URL, fsBlockDbRoot: URL, spendParamsPath: URL, outputParamsPath: URL, networkType: NetworkType) {
39
34
  self.dbData = dbData.osStr()
40
35
  self.fsBlockDbRoot = fsBlockDbRoot.osPathStr()
41
36
  self.spendParamsPath = spendParamsPath.osPathStr()
42
37
  self.outputParamsPath = outputParamsPath.osPathStr()
43
38
  self.networkType = networkType
44
39
  self.keyDeriving = ZcashKeyDerivationBackend(networkType: networkType)
45
-
46
- if enableTracing && !Self.tracingEnabled {
47
- Self.tracingEnabled = true
48
- Self.enableTracing()
49
- }
50
40
  }
51
41
 
52
- func createAccount(seed: [UInt8], treeState: TreeState, recoverUntil: UInt32?) async throws -> UnifiedSpendingKey {
53
- var rUntil: Int64 = -1
54
-
55
- if let recoverUntil {
56
- rUntil = Int64(recoverUntil)
57
- }
58
-
59
- let treeStateBytes = try treeState.serializedData(partial: false).bytes
60
-
61
- globalDBLock.lock()
42
+ func createAccount(seed: [UInt8]) async throws -> UnifiedSpendingKey {
62
43
  let ffiBinaryKeyPtr = zcashlc_create_account(
63
44
  dbData.0,
64
45
  dbData.1,
65
46
  seed,
66
47
  UInt(seed.count),
67
- treeStateBytes,
68
- UInt(treeStateBytes.count),
69
- rUntil,
70
48
  networkType.networkId
71
49
  )
72
- globalDBLock.unlock()
73
50
 
74
51
  guard let ffiBinaryKeyPtr else {
75
52
  throw ZcashError.rustCreateAccount(lastErrorMessage(fallback: "`createAccount` failed with unknown error"))
@@ -85,44 +62,34 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
85
62
  to address: String,
86
63
  value: Int64,
87
64
  memo: MemoBytes?
88
- ) async throws -> Data {
89
- var contiguousTxIdBytes = ContiguousArray<UInt8>([UInt8](repeating: 0x0, count: 32))
90
-
91
- globalDBLock.lock()
92
- let success = contiguousTxIdBytes.withUnsafeMutableBufferPointer { txIdBytePtr in
93
- usk.bytes.withUnsafeBufferPointer { uskPtr in
94
- zcashlc_create_to_address(
95
- dbData.0,
96
- dbData.1,
97
- uskPtr.baseAddress,
98
- UInt(usk.bytes.count),
99
- [CChar](address.utf8CString),
100
- value,
101
- memo?.bytes,
102
- spendParamsPath.0,
103
- spendParamsPath.1,
104
- outputParamsPath.0,
105
- outputParamsPath.1,
106
- networkType.networkId,
107
- minimumConfirmations,
108
- useZIP317Fees,
109
- txIdBytePtr.baseAddress
110
- )
111
- }
65
+ ) async throws -> Int64 {
66
+ let result = usk.bytes.withUnsafeBufferPointer { uskPtr in
67
+ zcashlc_create_to_address(
68
+ dbData.0,
69
+ dbData.1,
70
+ uskPtr.baseAddress,
71
+ UInt(usk.bytes.count),
72
+ [CChar](address.utf8CString),
73
+ value,
74
+ memo?.bytes,
75
+ spendParamsPath.0,
76
+ spendParamsPath.1,
77
+ outputParamsPath.0,
78
+ outputParamsPath.1,
79
+ networkType.networkId,
80
+ minimumConfirmations,
81
+ useZIP317Fees
82
+ )
112
83
  }
113
- globalDBLock.unlock()
114
84
 
115
- guard success else {
85
+ guard result > 0 else {
116
86
  throw ZcashError.rustCreateToAddress(lastErrorMessage(fallback: "`createToAddress` failed with unknown error"))
117
87
  }
118
88
 
119
- return contiguousTxIdBytes.withUnsafeBufferPointer { txIdBytePtr in
120
- Data(txIdBytePtr)
121
- }
89
+ return result
122
90
  }
123
91
 
124
92
  func decryptAndStoreTransaction(txBytes: [UInt8], minedHeight: Int32) async throws {
125
- globalDBLock.lock()
126
93
  let result = zcashlc_decrypt_and_store_transaction(
127
94
  dbData.0,
128
95
  dbData.1,
@@ -131,7 +98,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
131
98
  UInt32(minedHeight),
132
99
  networkType.networkId
133
100
  )
134
- globalDBLock.unlock()
135
101
 
136
102
  guard result != 0 else {
137
103
  throw ZcashError.rustDecryptAndStoreTransaction(lastErrorMessage(fallback: "`decryptAndStoreTransaction` failed with unknown error"))
@@ -139,9 +105,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
139
105
  }
140
106
 
141
107
  func getBalance(account: Int32) async throws -> Int64 {
142
- globalDBLock.lock()
143
108
  let balance = zcashlc_get_balance(dbData.0, dbData.1, account, networkType.networkId)
144
- globalDBLock.unlock()
145
109
 
146
110
  guard balance >= 0 else {
147
111
  throw ZcashError.rustGetBalance(Int(account), lastErrorMessage(fallback: "Error getting total balance from account \(account)"))
@@ -151,14 +115,12 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
151
115
  }
152
116
 
153
117
  func getCurrentAddress(account: Int32) async throws -> UnifiedAddress {
154
- globalDBLock.lock()
155
118
  let addressCStr = zcashlc_get_current_address(
156
119
  dbData.0,
157
120
  dbData.1,
158
121
  account,
159
122
  networkType.networkId
160
123
  )
161
- globalDBLock.unlock()
162
124
 
163
125
  guard let addressCStr else {
164
126
  throw ZcashError.rustGetCurrentAddress(lastErrorMessage(fallback: "`getCurrentAddress` failed with unknown error"))
@@ -174,14 +136,12 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
174
136
  }
175
137
 
176
138
  func getNearestRewindHeight(height: Int32) async throws -> Int32 {
177
- globalDBLock.lock()
178
139
  let result = zcashlc_get_nearest_rewind_height(
179
140
  dbData.0,
180
141
  dbData.1,
181
142
  height,
182
143
  networkType.networkId
183
144
  )
184
- globalDBLock.unlock()
185
145
 
186
146
  guard result > 0 else {
187
147
  throw ZcashError.rustGetNearestRewindHeight(lastErrorMessage(fallback: "`getNearestRewindHeight` failed with unknown error"))
@@ -191,14 +151,12 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
191
151
  }
192
152
 
193
153
  func getNextAvailableAddress(account: Int32) async throws -> UnifiedAddress {
194
- globalDBLock.lock()
195
154
  let addressCStr = zcashlc_get_next_available_address(
196
155
  dbData.0,
197
156
  dbData.1,
198
157
  account,
199
158
  networkType.networkId
200
159
  )
201
- globalDBLock.unlock()
202
160
 
203
161
  guard let addressCStr else {
204
162
  throw ZcashError.rustGetNextAvailableAddress(lastErrorMessage(fallback: "`getNextAvailableAddress` failed with unknown error"))
@@ -213,19 +171,26 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
213
171
  return UnifiedAddress(validatedEncoding: address, networkType: networkType)
214
172
  }
215
173
 
216
- func getMemo(txId: Data, outputIndex: UInt16) async throws -> Memo? {
217
- guard txId.count == 32 else {
218
- throw ZcashError.rustGetMemoInvalidTxIdLength
174
+ func getReceivedMemo(idNote: Int64) async -> Memo? {
175
+ var contiguousMemoBytes = ContiguousArray<UInt8>(MemoBytes.empty().bytes)
176
+ var success = false
177
+
178
+ contiguousMemoBytes.withUnsafeMutableBufferPointer { memoBytePtr in
179
+ success = zcashlc_get_received_memo(dbData.0, dbData.1, idNote, memoBytePtr.baseAddress, networkType.networkId)
219
180
  }
220
181
 
182
+ guard success else { return nil }
183
+
184
+ return (try? MemoBytes(contiguousBytes: contiguousMemoBytes)).flatMap { try? $0.intoMemo() }
185
+ }
186
+
187
+ func getSentMemo(idNote: Int64) async -> Memo? {
221
188
  var contiguousMemoBytes = ContiguousArray<UInt8>(MemoBytes.empty().bytes)
222
189
  var success = false
223
190
 
224
- globalDBLock.lock()
225
- contiguousMemoBytes.withUnsafeMutableBufferPointer { memoBytePtr in
226
- success = zcashlc_get_memo(dbData.0, dbData.1, txId.bytes, outputIndex, memoBytePtr.baseAddress, networkType.networkId)
191
+ contiguousMemoBytes.withUnsafeMutableBytes { memoBytePtr in
192
+ success = zcashlc_get_sent_memo(dbData.0, dbData.1, idNote, memoBytePtr.baseAddress, networkType.networkId)
227
193
  }
228
- globalDBLock.unlock()
229
194
 
230
195
  guard success else { return nil }
231
196
 
@@ -237,14 +202,12 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
237
202
  throw ZcashError.rustGetTransparentBalanceNegativeAccount(Int(account))
238
203
  }
239
204
 
240
- globalDBLock.lock()
241
205
  let balance = zcashlc_get_total_transparent_balance_for_account(
242
206
  dbData.0,
243
207
  dbData.1,
244
208
  networkType.networkId,
245
209
  account
246
210
  )
247
- globalDBLock.unlock()
248
211
 
249
212
  guard balance >= 0 else {
250
213
  throw ZcashError.rustGetTransparentBalance(
@@ -257,7 +220,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
257
220
  }
258
221
 
259
222
  func getVerifiedBalance(account: Int32) async throws -> Int64 {
260
- globalDBLock.lock()
261
223
  let balance = zcashlc_get_verified_balance(
262
224
  dbData.0,
263
225
  dbData.1,
@@ -265,7 +227,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
265
227
  networkType.networkId,
266
228
  minimumConfirmations
267
229
  )
268
- globalDBLock.unlock()
269
230
 
270
231
  guard balance >= 0 else {
271
232
  throw ZcashError.rustGetVerifiedBalance(
@@ -282,7 +243,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
282
243
  throw ZcashError.rustGetVerifiedTransparentBalanceNegativeAccount(Int(account))
283
244
  }
284
245
 
285
- globalDBLock.lock()
286
246
  let balance = zcashlc_get_verified_transparent_balance_for_account(
287
247
  dbData.0,
288
248
  dbData.1,
@@ -290,7 +250,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
290
250
  account,
291
251
  minimumConfirmations
292
252
  )
293
- globalDBLock.unlock()
294
253
 
295
254
  guard balance >= 0 else {
296
255
  throw ZcashError.rustGetVerifiedTransparentBalance(
@@ -303,11 +262,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
303
262
  }
304
263
 
305
264
  func initDataDb(seed: [UInt8]?) async throws -> DbInitResult {
306
- globalDBLock.lock()
307
- let initResult = zcashlc_init_data_database(dbData.0, dbData.1, seed, UInt(seed?.count ?? 0), networkType.networkId)
308
- globalDBLock.unlock()
309
-
310
- switch initResult {
265
+ switch zcashlc_init_data_database(dbData.0, dbData.1, seed, UInt(seed?.count ?? 0), networkType.networkId) {
311
266
  case 0: // ok
312
267
  return DbInitResult.success
313
268
  case 1:
@@ -317,10 +272,59 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
317
272
  }
318
273
  }
319
274
 
275
+ func initAccountsTable(ufvks: [UnifiedFullViewingKey]) async throws {
276
+ var ffiUfvks: [FFIEncodedKey] = []
277
+ for ufvk in ufvks {
278
+ guard !ufvk.encoding.containsCStringNullBytesBeforeStringEnding() else {
279
+ throw ZcashError.rustInitAccountsTableViewingKeyCotainsNullBytes
280
+ }
281
+
282
+ guard self.keyDeriving.isValidUnifiedFullViewingKey(ufvk.encoding) else {
283
+ throw ZcashError.rustInitAccountsTableViewingKeyIsInvalid
284
+ }
285
+
286
+ let ufvkCStr = [CChar](String(ufvk.encoding).utf8CString)
287
+
288
+ let ufvkPtr = UnsafeMutablePointer<CChar>.allocate(capacity: ufvkCStr.count)
289
+ ufvkPtr.initialize(from: ufvkCStr, count: ufvkCStr.count)
290
+
291
+ ffiUfvks.append(
292
+ FFIEncodedKey(account_id: ufvk.account, encoding: ufvkPtr)
293
+ )
294
+ }
295
+
296
+ var contiguousUVKs = ContiguousArray(ffiUfvks)
297
+
298
+ var result = false
299
+
300
+ contiguousUVKs.withContiguousMutableStorageIfAvailable { ufvksPtr in
301
+ result = zcashlc_init_accounts_table_with_keys(
302
+ dbData.0,
303
+ dbData.1,
304
+ ufvksPtr.baseAddress,
305
+ UInt(ufvks.count),
306
+ networkType.networkId
307
+ )
308
+ }
309
+
310
+ defer {
311
+ for ufvk in ffiUfvks {
312
+ ufvk.encoding.deallocate()
313
+ }
314
+ }
315
+
316
+ guard result else {
317
+ let message = lastErrorMessage(fallback: "`initAccountsTable` failed with unknown error")
318
+ if message.isDbNotEmptyErrorMessage() {
319
+ throw ZcashError.rustInitAccountsTableDataDbNotEmpty
320
+ } else {
321
+ throw ZcashError.rustInitAccountsTable(message)
322
+ }
323
+ }
324
+ }
325
+
320
326
  func initBlockMetadataDb() async throws {
321
- globalDBLock.lock()
322
327
  let result = zcashlc_init_block_metadata_db(fsBlockDbRoot.0, fsBlockDbRoot.1)
323
- globalDBLock.unlock()
324
328
 
325
329
  guard result else {
326
330
  throw ZcashError.rustInitBlockMetadataDb(lastErrorMessage(fallback: "`initBlockMetadataDb` failed with unknown error"))
@@ -376,9 +380,7 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
376
380
 
377
381
  fsBlocks.initialize(to: meta)
378
382
 
379
- globalDBLock.lock()
380
383
  let res = zcashlc_write_block_metadata(fsBlockDbRoot.0, fsBlockDbRoot.1, fsBlocks)
381
- globalDBLock.unlock()
382
384
 
383
385
  guard res else {
384
386
  throw ZcashError.rustWriteBlocksMetadata(lastErrorMessage(fallback: "`writeBlocksMetadata` failed with unknown error"))
@@ -386,29 +388,51 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
386
388
  }
387
389
  }
388
390
 
389
- func latestCachedBlockHeight() async throws -> BlockHeight {
390
- globalDBLock.lock()
391
- let height = zcashlc_latest_cached_block_height(fsBlockDbRoot.0, fsBlockDbRoot.1)
392
- globalDBLock.unlock()
391
+ func initBlocksTable(
392
+ height: Int32,
393
+ hash: String,
394
+ time: UInt32,
395
+ saplingTree: String
396
+ ) async throws {
397
+ guard !hash.containsCStringNullBytesBeforeStringEnding() else {
398
+ throw ZcashError.rustInitBlocksTableHashContainsNullBytes
399
+ }
393
400
 
394
- if height >= 0 {
395
- return BlockHeight(height)
396
- } else if height == -1 {
397
- return BlockHeight.empty()
398
- } else {
399
- throw ZcashError.rustLatestCachedBlockHeight(lastErrorMessage(fallback: "`latestCachedBlockHeight` failed with unknown error"))
401
+ guard !saplingTree.containsCStringNullBytesBeforeStringEnding() else {
402
+ throw ZcashError.rustInitBlocksTableSaplingTreeContainsNullBytes
400
403
  }
404
+
405
+ let result = zcashlc_init_blocks_table(
406
+ dbData.0,
407
+ dbData.1,
408
+ height,
409
+ [CChar](hash.utf8CString),
410
+ time,
411
+ [CChar](saplingTree.utf8CString),
412
+ networkType.networkId
413
+ )
414
+
415
+ guard result != 0 else {
416
+ let message = lastErrorMessage(fallback: "`initBlocksTable` failed with unknown error")
417
+ if message.isDbNotEmptyErrorMessage() {
418
+ throw ZcashError.rustInitBlocksTableDataDbNotEmpty
419
+ } else {
420
+ throw ZcashError.rustInitBlocksTable(message)
421
+ }
422
+ }
423
+ }
424
+
425
+ func latestCachedBlockHeight() async -> BlockHeight {
426
+ return BlockHeight(zcashlc_latest_cached_block_height(fsBlockDbRoot.0, fsBlockDbRoot.1))
401
427
  }
402
428
 
403
429
  func listTransparentReceivers(account: Int32) async throws -> [TransparentAddress] {
404
- globalDBLock.lock()
405
430
  let encodedKeysPtr = zcashlc_list_transparent_receivers(
406
431
  dbData.0,
407
432
  dbData.1,
408
433
  account,
409
434
  networkType.networkId
410
435
  )
411
- globalDBLock.unlock()
412
436
 
413
437
  guard let encodedKeysPtr else {
414
438
  throw ZcashError.rustListTransparentReceivers(lastErrorMessage(fallback: "`listTransparentReceivers` failed with unknown error"))
@@ -440,7 +464,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
440
464
  value: Int64,
441
465
  height: BlockHeight
442
466
  ) async throws {
443
- globalDBLock.lock()
444
467
  let result = zcashlc_put_utxo(
445
468
  dbData.0,
446
469
  dbData.1,
@@ -453,17 +476,29 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
453
476
  Int32(height),
454
477
  networkType.networkId
455
478
  )
456
- globalDBLock.unlock()
457
479
 
458
480
  guard result else {
459
481
  throw ZcashError.rustPutUnspentTransparentOutput(lastErrorMessage(fallback: "`putUnspentTransparentOutput` failed with unknown error"))
460
482
  }
461
483
  }
462
484
 
485
+ func validateCombinedChain(limit: UInt32 = 0) async throws {
486
+ let result = zcashlc_validate_combined_chain(fsBlockDbRoot.0, fsBlockDbRoot.1, dbData.0, dbData.1, limit, networkType.networkId)
487
+
488
+ switch result {
489
+ case -1:
490
+ return
491
+ case 0:
492
+ throw ZcashError.rustValidateCombinedChainValidationFailed(
493
+ lastErrorMessage(fallback: "`validateCombinedChain` failed with unknown error")
494
+ )
495
+ default:
496
+ throw ZcashError.rustValidateCombinedChainInvalidChain(result)
497
+ }
498
+ }
499
+
463
500
  func rewindToHeight(height: Int32) async throws {
464
- globalDBLock.lock()
465
501
  let result = zcashlc_rewind_to_height(dbData.0, dbData.1, height, networkType.networkId)
466
- globalDBLock.unlock()
467
502
 
468
503
  guard result else {
469
504
  throw ZcashError.rustRewindToHeight(height, lastErrorMessage(fallback: "`rewindToHeight` failed with unknown error"))
@@ -471,162 +506,15 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
471
506
  }
472
507
 
473
508
  func rewindCacheToHeight(height: Int32) async throws {
474
- globalDBLock.lock()
475
509
  let result = zcashlc_rewind_fs_block_cache_to_height(fsBlockDbRoot.0, fsBlockDbRoot.1, height)
476
- globalDBLock.unlock()
477
510
 
478
511
  guard result else {
479
512
  throw ZcashError.rustRewindCacheToHeight(lastErrorMessage(fallback: "`rewindCacheToHeight` failed with unknown error"))
480
513
  }
481
514
  }
482
515
 
483
- func putSaplingSubtreeRoots(startIndex: UInt64, roots: [SubtreeRoot]) async throws {
484
- var ffiSubtreeRootsVec: [FfiSubtreeRoot] = []
485
-
486
- for root in roots {
487
- let hashPtr = UnsafeMutablePointer<UInt8>.allocate(capacity: root.rootHash.count)
488
-
489
- let contiguousHashBytes = ContiguousArray(root.rootHash.bytes)
490
-
491
- let result: Void? = contiguousHashBytes.withContiguousStorageIfAvailable { hashBytesPtr in
492
- // swiftlint:disable:next force_unwrapping
493
- hashPtr.initialize(from: hashBytesPtr.baseAddress!, count: hashBytesPtr.count)
494
- }
495
-
496
- guard result != nil else {
497
- defer {
498
- hashPtr.deallocate()
499
- ffiSubtreeRootsVec.deallocateElements()
500
- }
501
- throw ZcashError.rustPutSaplingSubtreeRootsAllocationProblem
502
- }
503
-
504
- ffiSubtreeRootsVec.append(
505
- FfiSubtreeRoot(
506
- root_hash_ptr: hashPtr,
507
- root_hash_ptr_len: UInt(contiguousHashBytes.count),
508
- completing_block_height: UInt32(root.completingBlockHeight)
509
- )
510
- )
511
- }
512
-
513
- var contiguousFfiRoots = ContiguousArray(ffiSubtreeRootsVec)
514
-
515
- let len = UInt(contiguousFfiRoots.count)
516
-
517
- let rootsPtr = UnsafeMutablePointer<FfiSubtreeRoots>.allocate(capacity: 1)
518
-
519
- defer {
520
- ffiSubtreeRootsVec.deallocateElements()
521
- rootsPtr.deallocate()
522
- }
523
-
524
- try contiguousFfiRoots.withContiguousMutableStorageIfAvailable { ptr in
525
- var roots = FfiSubtreeRoots()
526
- roots.ptr = ptr.baseAddress
527
- roots.len = len
528
-
529
- rootsPtr.initialize(to: roots)
530
-
531
- globalDBLock.lock()
532
- let res = zcashlc_put_sapling_subtree_roots(dbData.0, dbData.1, startIndex, rootsPtr, networkType.networkId)
533
- globalDBLock.unlock()
534
-
535
- guard res else {
536
- throw ZcashError.rustPutSaplingSubtreeRoots(lastErrorMessage(fallback: "`putSaplingSubtreeRoots` failed with unknown error"))
537
- }
538
- }
539
- }
540
-
541
- func updateChainTip(height: Int32) async throws {
542
- globalDBLock.lock()
543
- let result = zcashlc_update_chain_tip(dbData.0, dbData.1, height, networkType.networkId)
544
- globalDBLock.unlock()
545
-
546
- guard result else {
547
- throw ZcashError.rustUpdateChainTip(lastErrorMessage(fallback: "`updateChainTip` failed with unknown error"))
548
- }
549
- }
550
-
551
- func fullyScannedHeight() async throws -> BlockHeight? {
552
- globalDBLock.lock()
553
- let height = zcashlc_fully_scanned_height(dbData.0, dbData.1, networkType.networkId)
554
- globalDBLock.unlock()
555
-
556
- if height >= 0 {
557
- return BlockHeight(height)
558
- } else if height == -1 {
559
- return nil
560
- } else {
561
- throw ZcashError.rustFullyScannedHeight(lastErrorMessage(fallback: "`fullyScannedHeight` failed with unknown error"))
562
- }
563
- }
564
-
565
- func maxScannedHeight() async throws -> BlockHeight? {
566
- globalDBLock.lock()
567
- let height = zcashlc_max_scanned_height(dbData.0, dbData.1, networkType.networkId)
568
- globalDBLock.unlock()
569
-
570
- if height >= 0 {
571
- return BlockHeight(height)
572
- } else if height == -1 {
573
- return nil
574
- } else {
575
- throw ZcashError.rustMaxScannedHeight(lastErrorMessage(fallback: "`maxScannedHeight` failed with unknown error"))
576
- }
577
- }
578
-
579
- func getScanProgress() async throws -> ScanProgress? {
580
- globalDBLock.lock()
581
- let result = zcashlc_get_scan_progress(dbData.0, dbData.1, networkType.networkId)
582
- globalDBLock.unlock()
583
-
584
- if result.denominator == 0 {
585
- switch result.numerator {
586
- case 0:
587
- return nil
588
- default:
589
- throw ZcashError.rustGetScanProgress(lastErrorMessage(fallback: "`getScanProgress` failed with unknown error"))
590
- }
591
- } else {
592
- return ScanProgress(numerator: result.numerator, denominator: result.denominator)
593
- }
594
- }
595
-
596
- func suggestScanRanges() async throws -> [ScanRange] {
597
- globalDBLock.lock()
598
- let scanRangesPtr = zcashlc_suggest_scan_ranges(dbData.0, dbData.1, networkType.networkId)
599
- globalDBLock.unlock()
600
-
601
- guard let scanRangesPtr else {
602
- throw ZcashError.rustSuggestScanRanges(lastErrorMessage(fallback: "`suggestScanRanges` failed with unknown error"))
603
- }
604
-
605
- defer { zcashlc_free_scan_ranges(scanRangesPtr) }
606
-
607
- var scanRanges: [ScanRange] = []
608
-
609
- for i in (0 ..< Int(scanRangesPtr.pointee.len)) {
610
- let scanRange = scanRangesPtr.pointee.ptr.advanced(by: i).pointee
611
-
612
- scanRanges.append(
613
- ScanRange(
614
- range: Range(uncheckedBounds: (
615
- BlockHeight(scanRange.start),
616
- BlockHeight(scanRange.end)
617
- )),
618
- priority: ScanRange.Priority(scanRange.priority)
619
- )
620
- )
621
- }
622
-
623
- return scanRanges
624
- }
625
-
626
- func scanBlocks(fromHeight: Int32, limit: UInt32 = 0) async throws {
627
- globalDBLock.lock()
628
- let result = zcashlc_scan_blocks(fsBlockDbRoot.0, fsBlockDbRoot.1, dbData.0, dbData.1, fromHeight, limit, networkType.networkId)
629
- globalDBLock.unlock()
516
+ func scanBlocks(limit: UInt32 = 0) async throws {
517
+ let result = zcashlc_scan_blocks(fsBlockDbRoot.0, fsBlockDbRoot.1, dbData.0, dbData.1, limit, networkType.networkId)
630
518
 
631
519
  guard result != 0 else {
632
520
  throw ZcashError.rustScanBlocks(lastErrorMessage(fallback: "`scanBlocks` failed with unknown error"))
@@ -637,39 +525,30 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
637
525
  usk: UnifiedSpendingKey,
638
526
  memo: MemoBytes?,
639
527
  shieldingThreshold: Zatoshi
640
- ) async throws -> Data {
641
- var contiguousTxIdBytes = ContiguousArray<UInt8>([UInt8](repeating: 0x0, count: 32))
642
-
643
- globalDBLock.lock()
644
- let success = contiguousTxIdBytes.withUnsafeMutableBufferPointer { txIdBytePtr in
645
- usk.bytes.withUnsafeBufferPointer { uskBuffer in
646
- zcashlc_shield_funds(
647
- dbData.0,
648
- dbData.1,
649
- uskBuffer.baseAddress,
650
- UInt(usk.bytes.count),
651
- memo?.bytes,
652
- UInt64(shieldingThreshold.amount),
653
- spendParamsPath.0,
654
- spendParamsPath.1,
655
- outputParamsPath.0,
656
- outputParamsPath.1,
657
- networkType.networkId,
658
- minimumConfirmations,
659
- useZIP317Fees,
660
- txIdBytePtr.baseAddress
661
- )
662
- }
528
+ ) async throws -> Int64 {
529
+ let result = usk.bytes.withUnsafeBufferPointer { uskBuffer in
530
+ zcashlc_shield_funds(
531
+ dbData.0,
532
+ dbData.1,
533
+ uskBuffer.baseAddress,
534
+ UInt(usk.bytes.count),
535
+ memo?.bytes,
536
+ UInt64(shieldingThreshold.amount),
537
+ spendParamsPath.0,
538
+ spendParamsPath.1,
539
+ outputParamsPath.0,
540
+ outputParamsPath.1,
541
+ networkType.networkId,
542
+ minimumConfirmations,
543
+ useZIP317Fees
544
+ )
663
545
  }
664
- globalDBLock.unlock()
665
546
 
666
- guard success else {
547
+ guard result > 0 else {
667
548
  throw ZcashError.rustShieldFunds(lastErrorMessage(fallback: "`shieldFunds` failed with unknown error"))
668
549
  }
669
550
 
670
- return contiguousTxIdBytes.withUnsafeBufferPointer { txIdBytePtr in
671
- Data(txIdBytePtr)
672
- }
551
+ return result
673
552
  }
674
553
 
675
554
  nonisolated func consensusBranchIdFor(height: Int32) throws -> Int32 {
@@ -683,12 +562,6 @@ actor ZcashRustBackend: ZcashRustBackendWelding {
683
562
  }
684
563
  }
685
564
 
686
- private extension ZcashRustBackend {
687
- static func enableTracing() {
688
- zcashlc_init_on_load(false)
689
- }
690
- }
691
-
692
565
  private extension ZcashRustBackend {
693
566
  nonisolated func lastErrorMessage(fallback: String) -> String {
694
567
  let errorLen = zcashlc_last_error_length()
@@ -770,11 +643,3 @@ extension Array where Element == FFIBlockMeta {
770
643
  }
771
644
  }
772
645
  }
773
-
774
- extension Array where Element == FfiSubtreeRoot {
775
- func deallocateElements() {
776
- self.forEach { element in
777
- element.root_hash_ptr.deallocate()
778
- }
779
- }
780
- }