react-native-zcash 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +6 -3
  3. package/android/build.gradle +5 -4
  4. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2230000.json +8 -0
  5. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2240000.json +8 -0
  6. package/android/src/main/assets/co.electriccoin.zcash/checkpoint/mainnet/2250000.json +8 -0
  7. package/android/src/main/java/app/edge/rnzcash/RNZcashModule.kt +117 -122
  8. package/ios/RNZcash.m +1 -12
  9. package/ios/RNZcash.swift +127 -153
  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 +9 -5
  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 +8 -30
  148. package/lib/rnzcash.rn.js.map +1 -1
  149. package/lib/src/react-native.d.ts +3 -5
  150. package/lib/src/types.d.ts +19 -14
  151. package/package.json +1 -1
  152. package/src/react-native.ts +13 -21
  153. package/src/types.ts +26 -23
  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
@@ -5,16 +5,14 @@ import {
5
5
  } from 'react-native'
6
6
 
7
7
  import {
8
- BlockRange,
9
- ConfirmedTransaction,
8
+ Addresses,
10
9
  InitializerConfig,
11
10
  Network,
12
11
  SpendFailure,
13
12
  SpendInfo,
14
13
  SpendSuccess,
15
14
  SynchronizerCallbacks,
16
- UnifiedViewingKey,
17
- WalletBalance
15
+ UnifiedViewingKey
18
16
  } from './types'
19
17
 
20
18
  const { RNZcash } = NativeModules
@@ -68,11 +66,12 @@ export class Synchronizer {
68
66
  initializerConfig.alias,
69
67
  initializerConfig.networkName,
70
68
  initializerConfig.defaultHost,
71
- initializerConfig.defaultPort
69
+ initializerConfig.defaultPort,
70
+ initializerConfig.newWallet
72
71
  )
73
72
  }
74
73
 
75
- async deriveUnifiedAddress(): Promise<string> {
74
+ async deriveUnifiedAddress(): Promise<Addresses> {
76
75
  const result = await RNZcash.deriveUnifiedAddress(this.alias)
77
76
  return result
78
77
  }
@@ -82,20 +81,6 @@ export class Synchronizer {
82
81
  return result
83
82
  }
84
83
 
85
- async getBalance(): Promise<WalletBalance> {
86
- const result = await RNZcash.getBalance(this.alias)
87
- return result
88
- }
89
-
90
- async getTransactions(range: BlockRange): Promise<ConfirmedTransaction[]> {
91
- const result = await RNZcash.getTransactions(
92
- this.alias,
93
- range.first,
94
- range.last
95
- )
96
- return result
97
- }
98
-
99
84
  rescan(): void {
100
85
  RNZcash.rescan(this.alias)
101
86
  }
@@ -115,8 +100,15 @@ export class Synchronizer {
115
100
 
116
101
  // Events
117
102
 
118
- subscribe({ onStatusChanged, onUpdate }: SynchronizerCallbacks): void {
103
+ subscribe({
104
+ onBalanceChanged,
105
+ onStatusChanged,
106
+ onTransactionsChanged,
107
+ onUpdate
108
+ }: SynchronizerCallbacks): void {
109
+ this.setListener('BalanceEvent', onBalanceChanged)
119
110
  this.setListener('StatusEvent', onStatusChanged)
111
+ this.setListener('TransactionEvent', onTransactionsChanged)
120
112
  this.setListener('UpdateEvent', onUpdate)
121
113
  }
122
114
 
package/src/types.ts CHANGED
@@ -1,10 +1,5 @@
1
1
  export type Network = 'mainnet' | 'testnet'
2
2
 
3
- export interface WalletBalance {
4
- availableZatoshi: string
5
- totalZatoshi: string
6
- }
7
-
8
3
  export interface InitializerConfig {
9
4
  networkName: Network
10
5
  defaultHost: string
@@ -12,6 +7,7 @@ export interface InitializerConfig {
12
7
  mnemonicSeed: string
13
8
  alias: string
14
9
  birthdayHeight: number
10
+ newWallet: boolean
15
11
  }
16
12
 
17
13
  export interface SpendInfo {
@@ -31,40 +27,39 @@ export interface SpendFailure {
31
27
  errorCode?: string
32
28
  }
33
29
 
34
- export interface SynchronizerStatus {
35
- alias: string
36
- name:
37
- | 'STOPPED' /** Indicates that [stop] has been called on this Synchronizer and it will no longer be used. */
38
- | 'DISCONNECTED' /** Indicates that this Synchronizer is disconnected from its lightwalletd server. When set, a UI element may want to turn red. */
39
- | 'DOWNLOADING' /** Indicates that this Synchronizer is actively downloading new blocks from the server. */
40
- | 'VALIDATING' /** Indicates that this Synchronizer is actively validating new blocks that were downloaded from the server. Blocks need to be verified before they are scanned. This confirms that each block is chain-sequential, thereby detecting missing blocks and reorgs. */
41
- | 'SCANNING' /** Indicates that this Synchronizer is actively decrypting new blocks that were downloaded from the server. */
42
- | 'ENHANCING' /** Indicates that this Synchronizer is actively enhancing newly scanned blocks with additional transaction details, fetched from the server. */
43
- | 'SYNCED' /** Indicates that this Synchronizer is fully up to date and ready for all wallet functions. When set, a UI element may want to turn green. In this state, the balance can be trusted. */
44
- }
45
-
46
30
  export interface UnifiedViewingKey {
47
31
  extfvk: string
48
32
  extpub: string
49
33
  }
50
34
 
35
+ export interface BalanceEvent {
36
+ availableZatoshi: string
37
+ totalZatoshi: string
38
+ }
39
+
51
40
  export interface StatusEvent {
52
41
  alias: string
53
- name: SynchronizerStatus
42
+ name:
43
+ | 'STOPPED' /** Indicates that [stop] has been called on this Synchronizer and it will no longer be used. */
44
+ | 'DISCONNECTED' /** Indicates that this Synchronizer is disconnected from its lightwalletd server. When set, a UI element may want to turn red. */
45
+ | 'SYNCING' /** Indicates that this Synchronizer is actively downloading and scanning new blocks */
46
+ | 'SYNCED' /** Indicates that this Synchronizer is fully up to date and ready for all wallet functions. When set, a UI element may want to turn green. In this state, the balance can be trusted. */
47
+ }
48
+
49
+ export interface TransactionEvent {
50
+ transactions: ConfirmedTransaction[]
54
51
  }
55
52
 
56
53
  export interface UpdateEvent {
57
54
  alias: string
58
- isDownloading: boolean
59
- isScanning: boolean
60
- lastDownloadedHeight: number
61
- lastScannedHeight: number
62
55
  scanProgress: number // 0 - 100
63
56
  networkBlockHeight: number
64
57
  }
65
58
 
66
59
  export interface SynchronizerCallbacks {
67
- onStatusChanged(status: SynchronizerStatus): void
60
+ onBalanceChanged(balance: BalanceEvent): void
61
+ onStatusChanged(status: StatusEvent): void
62
+ onTransactionsChanged(transactions: TransactionEvent): void
68
63
  onUpdate(event: UpdateEvent): void
69
64
  }
70
65
 
@@ -75,9 +70,17 @@ export interface BlockRange {
75
70
 
76
71
  export interface ConfirmedTransaction {
77
72
  rawTransactionId: string
73
+ raw?: string
78
74
  blockTimeInSeconds: number
79
75
  minedHeight: number
80
76
  value: string
77
+ fee?: string
81
78
  toAddress?: string
82
79
  memos: string[]
83
80
  }
81
+
82
+ export interface Addresses {
83
+ unifiedAddress: string
84
+ saplingAddress: string
85
+ transparentAddress: string
86
+ }
@@ -1,200 +0,0 @@
1
- //
2
- // InternalSyncProgress.swift
3
- //
4
- //
5
- // Created by Michal Fousek on 23.11.2022.
6
- //
7
-
8
- import Foundation
9
-
10
- struct SyncRanges: Equatable {
11
- let latestBlockHeight: BlockHeight
12
- /// The sync process can be interrupted in any phase. It may happen that it's interrupted while downloading blocks. In that case in next sync
13
- /// process already downloaded blocks needs to be scanned before the sync process starts to download new blocks. And the range of blocks that are
14
- /// already downloaded but not scanned is stored in this variable.
15
- let downloadedButUnscannedRange: CompactBlockRange?
16
- /// Range of blocks that are not yet downloaded and not yet scanned.
17
- let downloadAndScanRange: CompactBlockRange?
18
- /// Range of blocks that are not enhanced yet.
19
- let enhanceRange: CompactBlockRange?
20
- /// Range of blocks for which no UTXOs are fetched yet.
21
- let fetchUTXORange: CompactBlockRange?
22
-
23
- let latestScannedHeight: BlockHeight?
24
-
25
- let latestDownloadedBlockHeight: BlockHeight?
26
- }
27
-
28
- protocol InternalSyncProgressStorage {
29
- func bool(forKey defaultName: String) -> Bool
30
- func integer(forKey defaultName: String) -> Int
31
- func set(_ value: Int, forKey defaultName: String)
32
- func set(_ value: Bool, forKey defaultName: String)
33
- @discardableResult
34
- func synchronize() -> Bool
35
- }
36
-
37
- extension UserDefaults: InternalSyncProgressStorage { }
38
-
39
- actor InternalSyncProgress {
40
- enum Key: String, CaseIterable {
41
- case latestDownloadedBlockHeight
42
- case latestEnhancedHeight
43
- case latestUTXOFetchedHeight
44
-
45
- func with(_ alias: ZcashSynchronizerAlias) -> String {
46
- switch alias {
47
- case .`default`:
48
- return self.rawValue
49
- case let .custom(rawAlias):
50
- return "\(self.rawValue)_\(rawAlias)"
51
- }
52
- }
53
- }
54
-
55
- private let alias: ZcashSynchronizerAlias
56
- private let storage: InternalSyncProgressStorage
57
- let logger: Logger
58
-
59
- var latestDownloadedBlockHeight: BlockHeight { load(.latestDownloadedBlockHeight) }
60
- var latestEnhancedHeight: BlockHeight { load(.latestEnhancedHeight) }
61
- var latestUTXOFetchedHeight: BlockHeight { load(.latestUTXOFetchedHeight) }
62
-
63
- init(alias: ZcashSynchronizerAlias, storage: InternalSyncProgressStorage, logger: Logger) {
64
- self.alias = alias
65
- self.storage = storage
66
- self.logger = logger
67
- }
68
-
69
- func load(_ key: Key) -> BlockHeight {
70
- storage.integer(forKey: key.with(alias))
71
- }
72
-
73
- func set(_ value: BlockHeight, _ key: Key) {
74
- storage.set(value, forKey: key.with(alias))
75
- storage.synchronize()
76
- }
77
-
78
- func rewind(to: BlockHeight) {
79
- Key.allCases.forEach { key in
80
- let finalRewindHeight = min(load(key), to)
81
- self.set(finalRewindHeight, key)
82
- }
83
- }
84
-
85
- /// `InternalSyncProgress` is from now on used to track which block were already downloaded. Previous versions of the SDK were using cache DB to
86
- /// track this. Because of this we have to migrate height of latest downloaded block from cache DB to here.
87
- ///
88
- /// - Parameter latestDownloadedBlockHeight: Height of latest downloaded block from cache DB.
89
- func migrateIfNeeded(latestDownloadedBlockHeightFromCacheDB latestDownloadedBlockHeight: BlockHeight) {
90
- let key = "InternalSyncProgressMigrated"
91
- if !storage.bool(forKey: key) {
92
- set(latestDownloadedBlockHeight, .latestDownloadedBlockHeight)
93
- }
94
- storage.set(true, forKey: key)
95
- storage.synchronize()
96
- }
97
-
98
- /// Computes the next state for the sync process. Thanks to this it's possible to interrupt the sync process at any phase and then it can be safely
99
- /// resumed.
100
- ///
101
- /// The sync process has 4 phases (download, scan, enhance, fetch UTXO). `InternalSyncProgress` tracks independently which blocks were already
102
- /// processed in each phase. To compute the next state these 4 numbers are compared with `latestBlockHeight`.
103
- ///
104
- /// - If any of these numbers are larger than `latestBlockHeight` then `wait` is used as the next state. We have locally higher block heights than
105
- /// are currently available at LightWalletd.
106
- /// - If any of these numbers are lower than `latestBlockHeight` then `processNewBlocks` is used as the next state. The sync process should run.
107
- /// - Otherwise `finishProcessing` is used as the next state. It means that local data are synced with what is available at LightWalletd.
108
- ///
109
- /// - Parameters:
110
- /// - latestBlockHeight: Latest height fetched from LightWalletd API.
111
- /// - latestScannedHeight: Latest height of latest block scanned.
112
- /// - walletBirthday: Wallet birthday.
113
- /// - Returns: Computed state.
114
- func computeNextState(
115
- latestBlockHeight: BlockHeight,
116
- latestScannedHeight: BlockHeight,
117
- walletBirthday: BlockHeight
118
- ) -> CompactBlockProcessor.NextState {
119
- logger.debug("""
120
- Init numbers:
121
- latestBlockHeight: \(latestBlockHeight)
122
- latestDownloadedHeight: \(latestDownloadedBlockHeight)
123
- latestScannedHeight: \(latestScannedHeight)
124
- latestEnhancedHeight: \(latestEnhancedHeight)
125
- latestUTXOFetchedHeight: \(latestUTXOFetchedHeight)
126
- """)
127
-
128
- if latestDownloadedBlockHeight > latestBlockHeight ||
129
- latestScannedHeight > latestBlockHeight ||
130
- latestEnhancedHeight > latestBlockHeight ||
131
- latestUTXOFetchedHeight > latestBlockHeight {
132
- return .wait(latestHeight: latestBlockHeight, latestDownloadHeight: latestDownloadedBlockHeight)
133
- } else if latestDownloadedBlockHeight < latestBlockHeight ||
134
- latestScannedHeight < latestBlockHeight ||
135
- latestEnhancedHeight < latestEnhancedHeight ||
136
- latestUTXOFetchedHeight < latestBlockHeight {
137
- let ranges = computeSyncRanges(
138
- birthday: walletBirthday,
139
- latestBlockHeight: latestBlockHeight,
140
- latestScannedHeight: latestScannedHeight
141
- )
142
- return .processNewBlocks(ranges: ranges)
143
- } else {
144
- return .finishProcessing(height: latestBlockHeight)
145
- }
146
- }
147
-
148
- func computeSyncRanges(
149
- birthday: BlockHeight,
150
- latestBlockHeight: BlockHeight,
151
- latestScannedHeight: BlockHeight
152
- ) -> SyncRanges {
153
- // If there is more downloaded then scanned blocks we have to range for these blocks. The sync process will then start with scanning these
154
- // blocks instead of downloading new ones.
155
- let downloadedButUnscannedRange: CompactBlockRange?
156
- if latestScannedHeight < latestDownloadedBlockHeight {
157
- downloadedButUnscannedRange = latestScannedHeight + 1...latestDownloadedBlockHeight
158
- } else {
159
- downloadedButUnscannedRange = nil
160
- }
161
-
162
- if latestScannedHeight > latestDownloadedBlockHeight {
163
- logger.warn("""
164
- InternalSyncProgress found inconsistent state.
165
- latestBlockHeight: \(latestBlockHeight)
166
- --> latestDownloadedHeight: \(latestDownloadedBlockHeight)
167
- latestScannedHeight: \(latestScannedHeight)
168
- latestEnhancedHeight: \(latestEnhancedHeight)
169
- latestUTXOFetchedHeight: \(latestUTXOFetchedHeight)
170
-
171
- latest downloaded height
172
- """)
173
- }
174
-
175
- // compute the range that must be downloaded and scanned based on
176
- // birthday, `latestDownloadedBlockHeight`, `latestScannedHeight` and
177
- // latest block height fetched from the chain.
178
- let downloadAndScanRange = computeRange(
179
- latestHeight: max(latestDownloadedBlockHeight, latestScannedHeight),
180
- birthday: birthday,
181
- latestBlockHeight: latestBlockHeight
182
- )
183
-
184
- return SyncRanges(
185
- latestBlockHeight: latestBlockHeight,
186
- downloadedButUnscannedRange: downloadedButUnscannedRange,
187
- downloadAndScanRange: downloadAndScanRange,
188
- enhanceRange: computeRange(latestHeight: latestEnhancedHeight, birthday: birthday, latestBlockHeight: latestBlockHeight),
189
- fetchUTXORange: computeRange(latestHeight: latestUTXOFetchedHeight, birthday: birthday, latestBlockHeight: latestBlockHeight),
190
- latestScannedHeight: latestScannedHeight,
191
- latestDownloadedBlockHeight: latestDownloadedBlockHeight
192
- )
193
- }
194
-
195
- private func computeRange(latestHeight: BlockHeight, birthday: BlockHeight, latestBlockHeight: BlockHeight) -> CompactBlockRange? {
196
- guard latestHeight < latestBlockHeight else { return nil }
197
- let lowerBound = latestHeight <= birthday ? birthday : latestHeight + 1
198
- return lowerBound...latestBlockHeight
199
- }
200
- }
@@ -1,51 +0,0 @@
1
- //
2
- // CompactBlockValidationInformation.swift
3
- // ZcashLightClientKit
4
- //
5
- // Created by Francisco Gindre on 10/30/19.
6
- // Copyright © 2019 Electric Coin Company. All rights reserved.
7
- //
8
-
9
- import Foundation
10
-
11
- protocol BlockValidator {
12
- /// Validate all the downloaded blocks that haven't been yet validated.
13
- func validate() async throws
14
- }
15
-
16
- struct BlockValidatorImpl {
17
- let rustBackend: ZcashRustBackendWelding
18
- let metrics: SDKMetrics
19
- let logger: Logger
20
- }
21
-
22
- extension BlockValidatorImpl: BlockValidator {
23
- /// - Throws:
24
- /// - `rustValidateCombinedChainValidationFailed` if there was an error during validation unrelated to chain validity.
25
- /// - `rustValidateCombinedChainInvalidChain(upperBound)` if the combined chain is invalid. `upperBound` is the height of the highest invalid
26
- /// block(on the assumption that the highest block in the cache database is correct).
27
- func validate() async throws {
28
- try Task.checkCancellation()
29
-
30
- let startTime = Date()
31
- do {
32
- try await rustBackend.validateCombinedChain(limit: 0)
33
- pushProgressReport(startTime: startTime, finishTime: Date())
34
- logger.debug("validateChainFinished")
35
- } catch {
36
- logger.debug("Validate chain failed with \(error)")
37
- pushProgressReport(startTime: startTime, finishTime: Date())
38
- throw error
39
- }
40
- }
41
-
42
- private func pushProgressReport(startTime: Date, finishTime: Date) {
43
- metrics.pushProgressReport(
44
- progress: BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0),
45
- start: startTime,
46
- end: finishTime,
47
- batchSize: 0,
48
- operation: .validateBlocks
49
- )
50
- }
51
- }
@@ -1,112 +0,0 @@
1
- //
2
- // BlockDao.swift
3
- // ZcashLightClientKit
4
- //
5
- // Created by Francisco Gindre on 10/16/19.
6
- // Copyright © 2019 Electric Coin Company. All rights reserved.
7
- //
8
-
9
- import Foundation
10
- import SQLite
11
-
12
- protocol BlockDao {
13
- func latestBlockHeight() throws -> BlockHeight
14
- func latestBlock() throws -> Block?
15
- func block(at height: BlockHeight) throws -> Block?
16
- }
17
-
18
- struct Block: Codable {
19
- enum CodingKeys: String, CodingKey {
20
- case height
21
- case hash
22
- case time
23
- case saplingTree = "sapling_tree"
24
- }
25
-
26
- enum TableStructure {
27
- static let height = Expression<Int>(Block.CodingKeys.height.rawValue)
28
- static let hash = Expression<Blob>(Block.CodingKeys.hash.rawValue)
29
- static let time = Expression<Int>(Block.CodingKeys.time.rawValue)
30
- static let saplingTree = Expression<Blob>(Block.CodingKeys.saplingTree.rawValue)
31
- }
32
-
33
- let height: BlockHeight
34
- let hash: Data
35
- let time: Int
36
- let saplingTree: Data
37
-
38
- static let table = Table("blocks")
39
- }
40
-
41
- class BlockSQLDAO: BlockDao {
42
- let dbProvider: ConnectionProvider
43
- let table: Table
44
- let height = Expression<Int>("height")
45
-
46
- init(dbProvider: ConnectionProvider) {
47
- self.dbProvider = dbProvider
48
- self.table = Table("Blocks")
49
- }
50
-
51
- /// - Throws:
52
- /// - `blockDAOCantDecode` if block data loaded from DB can't be decoded to `Block` object.
53
- /// - `blockDAOBlock` if sqlite query to load block metadata failed.
54
- func block(at height: BlockHeight) throws -> Block? {
55
- do {
56
- return try dbProvider
57
- .connection()
58
- .prepare(Block.table.filter(Block.TableStructure.height == height).limit(1))
59
- .map {
60
- do {
61
- return try $0.decode()
62
- } catch {
63
- throw ZcashError.blockDAOCantDecode(error)
64
- }
65
- }
66
- .first
67
- } catch {
68
- if let error = error as? ZcashError {
69
- throw error
70
- } else {
71
- throw ZcashError.blockDAOBlock(error)
72
- }
73
- }
74
- }
75
-
76
- /// - Throws: `blockDAOLatestBlockHeight` if sqlite to fetch height fails.
77
- func latestBlockHeight() throws -> BlockHeight {
78
- do {
79
- return try dbProvider.connection().scalar(table.select(height.max)) ?? BlockHeight.empty()
80
- } catch {
81
- throw ZcashError.blockDAOLatestBlockHeight(error)
82
- }
83
- }
84
-
85
- func latestBlock() throws -> Block? {
86
- do {
87
- return try dbProvider
88
- .connection()
89
- .prepare(Block.table.order(height.desc).limit(1))
90
- .map {
91
- do {
92
- return try $0.decode()
93
- } catch {
94
- throw ZcashError.blockDAOLatestBlockCantDecode(error)
95
- }
96
- }
97
- .first
98
- } catch {
99
- if let error = error as? ZcashError {
100
- throw error
101
- } else {
102
- throw ZcashError.blockDAOLatestBlock(error)
103
- }
104
- }
105
- }
106
- }
107
-
108
- extension BlockSQLDAO: BlockRepository {
109
- func lastScannedBlockHeight() -> BlockHeight {
110
- (try? self.latestBlockHeight()) ?? BlockHeight.empty()
111
- }
112
- }
@@ -1,24 +0,0 @@
1
- //
2
- // BlockProgress.swift
3
- //
4
- //
5
- // Created by Michal Fousek on 03.02.2023.
6
- //
7
-
8
- import Foundation
9
-
10
- public struct BlockProgress: Equatable {
11
- public let startHeight: BlockHeight
12
- public let targetHeight: BlockHeight
13
- public let progressHeight: BlockHeight
14
-
15
- public var progress: Float {
16
- let overall = self.targetHeight - self.startHeight
17
-
18
- return overall > 0 ? Float((self.progressHeight - self.startHeight)) / Float(overall) : 0
19
- }
20
- }
21
-
22
- public extension BlockProgress {
23
- static let nullProgress = BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)
24
- }