Merge pull request #1373 from LukasKorba/1153-Allow-runtime-switch-of-lightwalletd-servers

[#1153] Allow runtime switch of lightwalletd servers
This commit is contained in:
Lukas Korba 2024-02-12 17:37:55 +01:00 committed by GitHub
commit 09fe70dff2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 253 additions and 54 deletions

View File

@ -11,6 +11,14 @@ and this library adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### [#1363] Account balances in the SynchronizerState ### [#1363] Account balances in the SynchronizerState
`shieldedBalance: WalletBalance` has been replaced with `accountBalances: AccountBalance`. `AccountBalance` provides the same values as `shieldedBalance` but adds up a pending changes. Under the hood this calls rust's `getWalletSummary` which improved also the syncing initial values of % and balances. `shieldedBalance: WalletBalance` has been replaced with `accountBalances: AccountBalance`. `AccountBalance` provides the same values as `shieldedBalance` but adds up a pending changes. Under the hood this calls rust's `getWalletSummary` which improved also the syncing initial values of % and balances.
## Added
### [#1153] Allow runtime switch of lightwalletd servers
New API implemented that allows clients to change the `mainnet` endpoint. Use `func switchTo(endpoint: LightWalletEndpoint) async throws`.
Possible errors:
- `ZcashError.synchronizerServerSwitch`: endpoint fails, check the address, port and format address:port,
- Some `ZcashError` related to `synchronizer.Start()`: the switch calls `start()` at the end and that is the only throwing function except the validation.
# 2.0.8 - 2024-01-30 # 2.0.8 - 2024-01-30
Adopt `zcash-light-client-ffi 0.5.1`. This fixes a serialization problem Adopt `zcash-light-client-ffi 0.5.1`. This fixes a serialization problem

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Ewq-Xy-xHb"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Ewq-Xy-xHb">
<device id="retina6_0" orientation="portrait" appearance="light"/> <device id="retina6_0" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -959,16 +959,16 @@
</constraints> </constraints>
</view> </view>
<stackView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="246" verticalCompressionResistancePriority="250" ambiguous="YES" alignment="center" spacing="13" translatesAutoresizingMaskIntoConstraints="NO" id="IIl-kO-2M8"> <stackView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="246" verticalCompressionResistancePriority="250" ambiguous="YES" alignment="center" spacing="13" translatesAutoresizingMaskIntoConstraints="NO" id="IIl-kO-2M8">
<rect key="frame" x="0.0" y="79.000000000000014" width="374" height="177.33333333333337"/> <rect key="frame" x="0.0" y="79" width="374" height="240"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" text="Status:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3t3-Tr-UlI"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" text="Status:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3t3-Tr-UlI">
<rect key="frame" x="0.0" y="69.666666666666657" width="95.666666666666671" height="38.333333333333343"/> <rect key="frame" x="0.0" y="101" width="95.666666666666671" height="38.333333333333343"/>
<fontDescription key="fontDescription" type="system" pointSize="32"/> <fontDescription key="fontDescription" type="system" pointSize="32"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jj9-7r-s2Y"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jj9-7r-s2Y">
<rect key="frame" x="108.66666666666666" y="75" width="265.33333333333337" height="27.666666666666671"/> <rect key="frame" x="108.66666666666666" y="106.33333333333331" width="265.33333333333337" height="27.666666666666657"/>
<fontDescription key="fontDescription" type="italicSystem" pointSize="23"/> <fontDescription key="fontDescription" type="italicSystem" pointSize="23"/>
<color key="textColor" systemColor="scrollViewTexturedBackgroundColor"/> <color key="textColor" systemColor="scrollViewTexturedBackgroundColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -979,28 +979,28 @@
</constraints> </constraints>
</stackView> </stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Progress" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JPx-ol-2nc"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Progress" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JPx-ol-2nc">
<rect key="frame" x="0.0" y="280.33333333333331" width="366" height="43"/> <rect key="frame" x="0.0" y="343" width="366" height="43"/>
<fontDescription key="fontDescription" type="system" pointSize="36"/> <fontDescription key="fontDescription" type="system" pointSize="36"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" ambiguous="YES" progressViewStyle="bar" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="oKg-9s-8Ym"> <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" ambiguous="YES" progressViewStyle="bar" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="oKg-9s-8Ym">
<rect key="frame" x="0.0" y="347.33333333333331" width="366" height="2.6666666666666856"/> <rect key="frame" x="0.0" y="410" width="366" height="2.6666666666666856"/>
</progressView> </progressView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="0%" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kXE-5z-HN2"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="0%" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kXE-5z-HN2">
<rect key="frame" x="0.0" y="373" width="374" height="39.666666666666686"/> <rect key="frame" x="0.0" y="435.66666666666663" width="374" height="39.666666666666686"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/> <fontDescription key="fontDescription" type="system" pointSize="33"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="x3B-hR-coo" userLabel="ProgressDataLabel"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="x3B-hR-coo" userLabel="ProgressDataLabel">
<rect key="frame" x="0.0" y="436.66666666666663" width="0.0" height="0.0"/> <rect key="frame" x="0.0" y="499.33333333333337" width="0.0" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<button opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="G5M-gm-1ux"> <button opaque="NO" contentMode="scaleToFill" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="G5M-gm-1ux">
<rect key="frame" x="0.0" y="460.66666666666663" width="374" height="45"/> <rect key="frame" x="0.0" y="523.33333333333337" width="374" height="45"/>
<fontDescription key="fontDescription" type="system" pointSize="27"/> <fontDescription key="fontDescription" type="system" pointSize="27"/>
<state key="normal" title="Start"/> <state key="normal" title="Start"/>
<connections> <connections>
@ -1008,19 +1008,19 @@
</connections> </connections>
</button> </button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XK2-GA-Ufv"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XK2-GA-Ufv">
<rect key="frame" x="0.0" y="529.66666666666663" width="374" height="14.333333333333371"/> <rect key="frame" x="0.0" y="592.33333333333337" width="374" height="14.333333333333371"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/> <fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ROk-70-c41"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ROk-70-c41">
<rect key="frame" x="0.0" y="568" width="374" height="14.333333333333371"/> <rect key="frame" x="0.0" y="630.66666666666663" width="374" height="14.333333333333371"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/> <fontDescription key="fontDescription" type="system" pointSize="12"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<view contentMode="scaleToFill" verticalHuggingPriority="750" verticalCompressionResistancePriority="737" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fB9-xh-4fl" userLabel="Trailing View"> <view contentMode="scaleToFill" verticalHuggingPriority="750" verticalCompressionResistancePriority="737" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fB9-xh-4fl" userLabel="Trailing View">
<rect key="frame" x="0.0" y="606.33333333333337" width="374" height="112.66666666666663"/> <rect key="frame" x="0.0" y="669" width="374" height="50"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints> <constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" priority="750" constant="20" id="Bpt-XM-IZA"/> <constraint firstAttribute="height" relation="greaterThanOrEqual" priority="750" constant="20" id="Bpt-XM-IZA"/>
@ -1399,7 +1399,7 @@
<resources> <resources>
<image name="play.circle" catalog="system" width="128" height="123"/> <image name="play.circle" catalog="system" width="128" height="123"/>
<systemColor name="labelColor"> <systemColor name="labelColor">
<color red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor> </systemColor>
<systemColor name="scrollViewTexturedBackgroundColor"> <systemColor name="scrollViewTexturedBackgroundColor">
<color red="0.43529411764705878" green="0.44313725490196082" blue="0.47450980392156861" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="0.43529411764705878" green="0.44313725490196082" blue="0.47450980392156861" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -1408,10 +1408,10 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor> </systemColor>
<systemColor name="systemGray2Color"> <systemColor name="systemGray2Color">
<color red="0.68235294117647061" green="0.68235294117647061" blue="0.69803921568627447" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="0.68235294120000001" green="0.68235294120000001" blue="0.69803921570000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor> </systemColor>
<systemColor name="systemRedColor"> <systemColor name="systemRedColor">
<color red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor> </systemColor>
</resources> </resources>
</document> </document>

View File

@ -21,15 +21,15 @@ enum DemoAppConfig {
static let host = ZcashSDK.isMainnet ? "mainnet.lightwalletd.com" : "lightwalletd.testnet.electriccoin.co" static let host = ZcashSDK.isMainnet ? "mainnet.lightwalletd.com" : "lightwalletd.testnet.electriccoin.co"
static let port: Int = 9067 static let port: Int = 9067
// static let defaultBirthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 935000 : 1386000 static let defaultBirthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 935000 : 1386000
// static let defaultSeed = try! Mnemonic.deterministicSeedBytes(from: """
// live combine flight accident slow soda mind bright absent bid hen shy decade biology amazing mix enlist ensure biology rhythm snap duty soap armor // static let defaultSeed = try! Mnemonic.deterministicSeedBytes(from: """
// """) // wish puppy smile loan doll curve hole maze file ginger hair nose key relax knife witness cannon grab despair throw review deal slush frame
// """)
static let defaultBirthdayHeight: BlockHeight = ZcashSDK.isMainnet ? 1935000 : 2170000
static let defaultSeed = try! Mnemonic.deterministicSeedBytes(from: """ static let defaultSeed = try! Mnemonic.deterministicSeedBytes(from: """
wish puppy smile loan doll curve hole maze file ginger hair nose key relax knife witness cannon grab despair throw review deal slush frame live combine flight accident slow soda mind bright absent bid hen shy decade biology amazing mix enlist ensure biology rhythm snap duty soap armor
""") """)
static let otherSynchronizers: [SynchronizerInitData] = [ static let otherSynchronizers: [SynchronizerInitData] = [
SynchronizerInitData( SynchronizerInitData(
@ -53,7 +53,7 @@ enum DemoAppConfig {
static var address: String { static var address: String {
"\(host):\(port)" "\(host):\(port)"
} }
static var endpoint: LightWalletEndpoint { static var endpoint: LightWalletEndpoint {
return LightWalletEndpoint(address: self.host, port: self.port, secure: true, streamingCallTimeoutInMillis: 10 * 60 * 60 * 1000) return LightWalletEndpoint(address: self.host, port: self.port, secure: true, streamingCallTimeoutInMillis: 10 * 60 * 60 * 1000)
} }

View File

@ -9,7 +9,7 @@ import Foundation
final class DownloadAction { final class DownloadAction {
let configProvider: CompactBlockProcessor.ConfigProvider let configProvider: CompactBlockProcessor.ConfigProvider
let downloader: BlockDownloader var downloader: BlockDownloader
let transactionRepository: TransactionRepository let transactionRepository: TransactionRepository
let logger: Logger let logger: Logger

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
final class EnhanceAction { final class EnhanceAction {
let blockEnhancer: BlockEnhancer var blockEnhancer: BlockEnhancer
let configProvider: CompactBlockProcessor.ConfigProvider let configProvider: CompactBlockProcessor.ConfigProvider
let logger: Logger let logger: Logger

View File

@ -8,7 +8,7 @@
import Foundation import Foundation
final class FetchUTXOsAction { final class FetchUTXOsAction {
let utxoFetcher: UTXOFetcher var utxoFetcher: UTXOFetcher
let logger: Logger let logger: Logger
init(container: DIContainer) { init(container: DIContainer) {

View File

@ -9,7 +9,7 @@ import Foundation
final class ProcessSuggestedScanRangesAction { final class ProcessSuggestedScanRangesAction {
let rustBackend: ZcashRustBackendWelding let rustBackend: ZcashRustBackendWelding
let service: LightWalletService var service: LightWalletService
let logger: Logger let logger: Logger
let metrics: SDKMetrics let metrics: SDKMetrics

View File

@ -8,9 +8,9 @@
import Foundation import Foundation
final class RewindAction { final class RewindAction {
let downloader: BlockDownloader var downloader: BlockDownloader
let rustBackend: ZcashRustBackendWelding let rustBackend: ZcashRustBackendWelding
let downloaderService: BlockDownloaderService var downloaderService: BlockDownloaderService
let logger: Logger let logger: Logger
init(container: DIContainer) { init(container: DIContainer) {

View File

@ -15,7 +15,7 @@ final class ScanAction {
let configProvider: CompactBlockProcessor.ConfigProvider let configProvider: CompactBlockProcessor.ConfigProvider
let blockScanner: BlockScanner let blockScanner: BlockScanner
let rustBackend: ZcashRustBackendWelding let rustBackend: ZcashRustBackendWelding
let latestBlocksDataProvider: LatestBlocksDataProvider var latestBlocksDataProvider: LatestBlocksDataProvider
let logger: Logger let logger: Logger
var progressReportReducer = 0 var progressReportReducer = 0

View File

@ -9,9 +9,9 @@ import Foundation
final class UpdateChainTipAction { final class UpdateChainTipAction {
let rustBackend: ZcashRustBackendWelding let rustBackend: ZcashRustBackendWelding
let downloader: BlockDownloader var downloader: BlockDownloader
let service: LightWalletService var service: LightWalletService
let latestBlocksDataProvider: LatestBlocksDataProvider var latestBlocksDataProvider: LatestBlocksDataProvider
let logger: Logger let logger: Logger
init(container: DIContainer) { init(container: DIContainer) {

View File

@ -10,7 +10,7 @@ import Foundation
final class UpdateSubtreeRootsAction { final class UpdateSubtreeRootsAction {
let configProvider: CompactBlockProcessor.ConfigProvider let configProvider: CompactBlockProcessor.ConfigProvider
let rustBackend: ZcashRustBackendWelding let rustBackend: ZcashRustBackendWelding
let service: LightWalletService var service: LightWalletService
let logger: Logger let logger: Logger
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) { init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {

View File

@ -10,7 +10,7 @@ import Foundation
final class ValidateServerAction { final class ValidateServerAction {
let configProvider: CompactBlockProcessor.ConfigProvider let configProvider: CompactBlockProcessor.ConfigProvider
let rustBackend: ZcashRustBackendWelding let rustBackend: ZcashRustBackendWelding
let service: LightWalletService var service: LightWalletService
init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) { init(container: DIContainer, configProvider: CompactBlockProcessor.ConfigProvider) {
self.configProvider = configProvider self.configProvider = configProvider

View File

@ -29,12 +29,12 @@ actor CompactBlockProcessor {
private var afterSyncHooksManager = AfterSyncHooksManager() private var afterSyncHooksManager = AfterSyncHooksManager()
private let accountRepository: AccountRepository private let accountRepository: AccountRepository
let blockDownloaderService: BlockDownloaderService var blockDownloaderService: BlockDownloaderService
private let latestBlocksDataProvider: LatestBlocksDataProvider private var latestBlocksDataProvider: LatestBlocksDataProvider
private let logger: Logger private let logger: Logger
private let metrics: SDKMetrics private let metrics: SDKMetrics
private let rustBackend: ZcashRustBackendWelding private let rustBackend: ZcashRustBackendWelding
let service: LightWalletService var service: LightWalletService
let storage: CompactBlockRepository let storage: CompactBlockRepository
private let transactionRepository: TransactionRepository private let transactionRepository: TransactionRepository
private let fileManager: ZcashFileManager private let fileManager: ZcashFileManager
@ -412,6 +412,52 @@ extension CompactBlockProcessor {
} }
} }
// MARK: - Switch server
extension CompactBlockProcessor {
func updateService(_ container: DIContainer) {
// LightWalletGRPCService
let updatedLWDService = container.resolve(LightWalletService.self)
(actions[.processSuggestedScanRanges] as? ProcessSuggestedScanRangesAction)?.service = updatedLWDService
(actions[.updateChainTip] as? UpdateChainTipAction)?.service = updatedLWDService
(actions[.updateSubtreeRoots] as? UpdateSubtreeRootsAction)?.service = updatedLWDService
(actions[.validateServer] as? ValidateServerAction)?.service = updatedLWDService
self.service = updatedLWDService
// BlockDownloaderService
let updatedDownloaderService = container.resolve(BlockDownloaderService.self)
(actions[.rewind] as? RewindAction)?.downloaderService = updatedDownloaderService
self.blockDownloaderService = updatedDownloaderService
// LatestBlocksDataProvider
let updatedLBDProvider = container.resolve(LatestBlocksDataProvider.self)
(actions[.scan] as? ScanAction)?.latestBlocksDataProvider = updatedLBDProvider
(actions[.updateChainTip] as? UpdateChainTipAction)?.latestBlocksDataProvider = updatedLBDProvider
self.latestBlocksDataProvider = updatedLBDProvider
// BlockDownloader
let updatedBlockDownloader = container.resolve(BlockDownloader.self)
(actions[.download] as? DownloadAction)?.downloader = updatedBlockDownloader
(actions[.updateChainTip] as? UpdateChainTipAction)?.downloader = updatedBlockDownloader
(actions[.rewind] as? RewindAction)?.downloader = updatedBlockDownloader
self.blockDownloaderService = updatedDownloaderService
// BlockEnhancer
let updatedEnhancer = container.resolve(BlockEnhancer.self)
(actions[.enhance] as? EnhanceAction)?.blockEnhancer = updatedEnhancer
// UTXOFetcher
let updatedUTXOFetcher = container.resolve(UTXOFetcher.self)
(actions[.fetchUTXO] as? FetchUTXOsAction)?.utxoFetcher = updatedUTXOFetcher
}
}
// MARK: - Events // MARK: - Events
extension CompactBlockProcessor { extension CompactBlockProcessor {

View File

@ -3,7 +3,7 @@
scriptDir=${0:a:h} scriptDir=${0:a:h}
cd "${scriptDir}" cd "${scriptDir}"
sourcery_version=2.0.3 sourcery_version=2.1.7
if which sourcery >/dev/null; then if which sourcery >/dev/null; then
if [[ $(sourcery --version) != $sourcery_version ]]; then if [[ $(sourcery --version) != $sourcery_version ]]; then

View File

@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.3 https://github.com/krzysztofzablocki/Sourcery // Generated using Sourcery 2.1.7 https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT // DO NOT EDIT
/* /*
@ -121,6 +121,11 @@ public enum ZcashError: Equatable, Error {
/// - `rustError` contains error generated by the rust layer. /// - `rustError` contains error generated by the rust layer.
/// ZRUST0003 /// ZRUST0003
case rustDecryptAndStoreTransaction(_ rustError: String) case rustDecryptAndStoreTransaction(_ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.getBalance
/// - `account` is account passed to ZcashRustBackend.getBalance.
/// - `rustError` contains error generated by the rust layer.
/// ZRUST0004
case rustGetBalance(_ account: Int, _ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.getCurrentAddress /// Error from rust layer when calling ZcashRustBackend.getCurrentAddress
/// - `rustError` contains error generated by the rust layer. /// - `rustError` contains error generated by the rust layer.
/// ZRUST0005 /// ZRUST0005
@ -148,6 +153,11 @@ public enum ZcashError: Equatable, Error {
/// - `rustError` contains error generated by the rust layer. /// - `rustError` contains error generated by the rust layer.
/// ZRUST0011 /// ZRUST0011
case rustGetTransparentBalance(_ account: Int, _ rustError: String) case rustGetTransparentBalance(_ account: Int, _ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.getVerifiedBalance
/// - `account` is account passed to ZcashRustBackend.getVerifiedBalance.
/// - `rustError` contains error generated by the rust layer.
/// ZRUST0012
case rustGetVerifiedBalance(_ account: Int, _ rustError: String)
/// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance /// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance
/// - `account` is account passed to ZcashRustBackend.getVerifiedTransparentBalance. /// - `account` is account passed to ZcashRustBackend.getVerifiedTransparentBalance.
/// ZRUST0013 /// ZRUST0013
@ -287,6 +297,10 @@ public enum ZcashError: Equatable, Error {
/// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes. /// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes.
/// ZRUST0050 /// ZRUST0050
case rustGetMemoInvalidTxIdLength case rustGetMemoInvalidTxIdLength
/// Error from rust layer when calling ZcashRustBackend.getScanProgress
/// - `rustError` contains error generated by the rust layer.
/// ZRUST0051
case rustGetScanProgress(_ rustError: String)
/// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight /// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight
/// - `rustError` contains error generated by the rust layer. /// - `rustError` contains error generated by the rust layer.
/// ZRUST0052 /// ZRUST0052
@ -570,6 +584,9 @@ public enum ZcashError: Equatable, Error {
/// Indicates that this Synchronizer is disconnected from its lightwalletd server. /// Indicates that this Synchronizer is disconnected from its lightwalletd server.
/// ZSYNCO0006 /// ZSYNCO0006
case synchronizerDisconnected case synchronizerDisconnected
/// The attempt to switch endpoints failed. Check that the hostname and port are correct, and are formatted as <hostname>:<port>.
/// ZSYNCO0007
case synchronizerServerSwitch
public var message: String { public var message: String {
switch self { switch self {
@ -604,6 +621,7 @@ public enum ZcashError: Equatable, Error {
case .rustCreateAccount: return "Error from rust layer when calling ZcashRustBackend.createAccount" case .rustCreateAccount: return "Error from rust layer when calling ZcashRustBackend.createAccount"
case .rustCreateToAddress: return "Error from rust layer when calling ZcashRustBackend.createToAddress" case .rustCreateToAddress: return "Error from rust layer when calling ZcashRustBackend.createToAddress"
case .rustDecryptAndStoreTransaction: return "Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction" case .rustDecryptAndStoreTransaction: return "Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction"
case .rustGetBalance: return "Error from rust layer when calling ZcashRustBackend.getBalance"
case .rustGetCurrentAddress: return "Error from rust layer when calling ZcashRustBackend.getCurrentAddress" case .rustGetCurrentAddress: return "Error from rust layer when calling ZcashRustBackend.getCurrentAddress"
case .rustGetCurrentAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress" case .rustGetCurrentAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress"
case .rustGetNearestRewindHeight: return "Error from rust layer when calling ZcashRustBackend.getNearestRewindHeight" case .rustGetNearestRewindHeight: return "Error from rust layer when calling ZcashRustBackend.getNearestRewindHeight"
@ -611,6 +629,7 @@ public enum ZcashError: Equatable, Error {
case .rustGetNextAvailableAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getNextAvailableAddress" case .rustGetNextAvailableAddressInvalidAddress: return "Unified address generated by rust layer is invalid when calling ZcashRustBackend.getNextAvailableAddress"
case .rustGetTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getTransparentBalance" case .rustGetTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getTransparentBalance"
case .rustGetTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getTransparentBalance" case .rustGetTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getTransparentBalance"
case .rustGetVerifiedBalance: return "Error from rust layer when calling ZcashRustBackend.getVerifiedBalance"
case .rustGetVerifiedTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance" case .rustGetVerifiedTransparentBalanceNegativeAccount: return "account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance"
case .rustGetVerifiedTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance" case .rustGetVerifiedTransparentBalance: return "Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance"
case .rustInitDataDb: return "Error from rust layer when calling ZcashRustBackend.initDataDb" case .rustInitDataDb: return "Error from rust layer when calling ZcashRustBackend.initDataDb"
@ -648,6 +667,7 @@ public enum ZcashError: Equatable, Error {
case .rustUpdateChainTip: return "Error from rust layer when calling ZcashRustBackend.updateChainTip" case .rustUpdateChainTip: return "Error from rust layer when calling ZcashRustBackend.updateChainTip"
case .rustSuggestScanRanges: return "Error from rust layer when calling ZcashRustBackend.suggestScanRanges" case .rustSuggestScanRanges: return "Error from rust layer when calling ZcashRustBackend.suggestScanRanges"
case .rustGetMemoInvalidTxIdLength: return "Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes." case .rustGetMemoInvalidTxIdLength: return "Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes."
case .rustGetScanProgress: return "Error from rust layer when calling ZcashRustBackend.getScanProgress"
case .rustFullyScannedHeight: return "Error from rust layer when calling ZcashRustBackend.fullyScannedHeight" case .rustFullyScannedHeight: return "Error from rust layer when calling ZcashRustBackend.fullyScannedHeight"
case .rustMaxScannedHeight: return "Error from rust layer when calling ZcashRustBackend.maxScannedHeight" case .rustMaxScannedHeight: return "Error from rust layer when calling ZcashRustBackend.maxScannedHeight"
case .rustLatestCachedBlockHeight: return "Error from rust layer when calling ZcashRustBackend.latestCachedBlockHeight" case .rustLatestCachedBlockHeight: return "Error from rust layer when calling ZcashRustBackend.latestCachedBlockHeight"
@ -737,6 +757,7 @@ public enum ZcashError: Equatable, Error {
case .synchronizerLatestUTXOsInvalidTAddress: return "LatestUTXOs for the address failed, invalid t-address." case .synchronizerLatestUTXOsInvalidTAddress: return "LatestUTXOs for the address failed, invalid t-address."
case .synchronizerRewindUnknownArchorHeight: return "Rewind failed, unknown archor height" case .synchronizerRewindUnknownArchorHeight: return "Rewind failed, unknown archor height"
case .synchronizerDisconnected: return "Indicates that this Synchronizer is disconnected from its lightwalletd server." case .synchronizerDisconnected: return "Indicates that this Synchronizer is disconnected from its lightwalletd server."
case .synchronizerServerSwitch: return "The attempt to switch endpoints failed. Check that the hostname and port are correct, and are formatted as <hostname>:<port>."
} }
} }
@ -773,6 +794,7 @@ public enum ZcashError: Equatable, Error {
case .rustCreateAccount: return .rustCreateAccount case .rustCreateAccount: return .rustCreateAccount
case .rustCreateToAddress: return .rustCreateToAddress case .rustCreateToAddress: return .rustCreateToAddress
case .rustDecryptAndStoreTransaction: return .rustDecryptAndStoreTransaction case .rustDecryptAndStoreTransaction: return .rustDecryptAndStoreTransaction
case .rustGetBalance: return .rustGetBalance
case .rustGetCurrentAddress: return .rustGetCurrentAddress case .rustGetCurrentAddress: return .rustGetCurrentAddress
case .rustGetCurrentAddressInvalidAddress: return .rustGetCurrentAddressInvalidAddress case .rustGetCurrentAddressInvalidAddress: return .rustGetCurrentAddressInvalidAddress
case .rustGetNearestRewindHeight: return .rustGetNearestRewindHeight case .rustGetNearestRewindHeight: return .rustGetNearestRewindHeight
@ -780,6 +802,7 @@ public enum ZcashError: Equatable, Error {
case .rustGetNextAvailableAddressInvalidAddress: return .rustGetNextAvailableAddressInvalidAddress case .rustGetNextAvailableAddressInvalidAddress: return .rustGetNextAvailableAddressInvalidAddress
case .rustGetTransparentBalanceNegativeAccount: return .rustGetTransparentBalanceNegativeAccount case .rustGetTransparentBalanceNegativeAccount: return .rustGetTransparentBalanceNegativeAccount
case .rustGetTransparentBalance: return .rustGetTransparentBalance case .rustGetTransparentBalance: return .rustGetTransparentBalance
case .rustGetVerifiedBalance: return .rustGetVerifiedBalance
case .rustGetVerifiedTransparentBalanceNegativeAccount: return .rustGetVerifiedTransparentBalanceNegativeAccount case .rustGetVerifiedTransparentBalanceNegativeAccount: return .rustGetVerifiedTransparentBalanceNegativeAccount
case .rustGetVerifiedTransparentBalance: return .rustGetVerifiedTransparentBalance case .rustGetVerifiedTransparentBalance: return .rustGetVerifiedTransparentBalance
case .rustInitDataDb: return .rustInitDataDb case .rustInitDataDb: return .rustInitDataDb
@ -817,6 +840,7 @@ public enum ZcashError: Equatable, Error {
case .rustUpdateChainTip: return .rustUpdateChainTip case .rustUpdateChainTip: return .rustUpdateChainTip
case .rustSuggestScanRanges: return .rustSuggestScanRanges case .rustSuggestScanRanges: return .rustSuggestScanRanges
case .rustGetMemoInvalidTxIdLength: return .rustGetMemoInvalidTxIdLength case .rustGetMemoInvalidTxIdLength: return .rustGetMemoInvalidTxIdLength
case .rustGetScanProgress: return .rustGetScanProgress
case .rustFullyScannedHeight: return .rustFullyScannedHeight case .rustFullyScannedHeight: return .rustFullyScannedHeight
case .rustMaxScannedHeight: return .rustMaxScannedHeight case .rustMaxScannedHeight: return .rustMaxScannedHeight
case .rustLatestCachedBlockHeight: return .rustLatestCachedBlockHeight case .rustLatestCachedBlockHeight: return .rustLatestCachedBlockHeight
@ -906,6 +930,7 @@ public enum ZcashError: Equatable, Error {
case .synchronizerLatestUTXOsInvalidTAddress: return .synchronizerLatestUTXOsInvalidTAddress case .synchronizerLatestUTXOsInvalidTAddress: return .synchronizerLatestUTXOsInvalidTAddress
case .synchronizerRewindUnknownArchorHeight: return .synchronizerRewindUnknownArchorHeight case .synchronizerRewindUnknownArchorHeight: return .synchronizerRewindUnknownArchorHeight
case .synchronizerDisconnected: return .synchronizerDisconnected case .synchronizerDisconnected: return .synchronizerDisconnected
case .synchronizerServerSwitch: return .synchronizerServerSwitch
} }
} }

View File

@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.3 https://github.com/krzysztofzablocki/Sourcery // Generated using Sourcery 2.1.7 https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT // DO NOT EDIT
/* /*
@ -71,6 +71,8 @@ public enum ZcashErrorCode: String {
case rustCreateToAddress = "ZRUST0002" case rustCreateToAddress = "ZRUST0002"
/// Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction /// Error from rust layer when calling ZcashRustBackend.decryptAndStoreTransaction
case rustDecryptAndStoreTransaction = "ZRUST0003" case rustDecryptAndStoreTransaction = "ZRUST0003"
/// Error from rust layer when calling ZcashRustBackend.getBalance
case rustGetBalance = "ZRUST0004"
/// Error from rust layer when calling ZcashRustBackend.getCurrentAddress /// Error from rust layer when calling ZcashRustBackend.getCurrentAddress
case rustGetCurrentAddress = "ZRUST0005" case rustGetCurrentAddress = "ZRUST0005"
/// Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress /// Unified address generated by rust layer is invalid when calling ZcashRustBackend.getCurrentAddress
@ -85,6 +87,8 @@ public enum ZcashErrorCode: String {
case rustGetTransparentBalanceNegativeAccount = "ZRUST0010" case rustGetTransparentBalanceNegativeAccount = "ZRUST0010"
/// Error from rust layer when calling ZcashRustBackend.getTransparentBalance /// Error from rust layer when calling ZcashRustBackend.getTransparentBalance
case rustGetTransparentBalance = "ZRUST0011" case rustGetTransparentBalance = "ZRUST0011"
/// Error from rust layer when calling ZcashRustBackend.getVerifiedBalance
case rustGetVerifiedBalance = "ZRUST0012"
/// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance /// account parameter is lower than 0 when calling ZcashRustBackend.getVerifiedTransparentBalance
case rustGetVerifiedTransparentBalanceNegativeAccount = "ZRUST0013" case rustGetVerifiedTransparentBalanceNegativeAccount = "ZRUST0013"
/// Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance /// Error from rust layer when calling ZcashRustBackend.getVerifiedTransparentBalance
@ -159,6 +163,8 @@ public enum ZcashErrorCode: String {
case rustSuggestScanRanges = "ZRUST0049" case rustSuggestScanRanges = "ZRUST0049"
/// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes. /// Invalid transaction ID length when calling ZcashRustBackend.getMemo. txId must be 32 bytes.
case rustGetMemoInvalidTxIdLength = "ZRUST0050" case rustGetMemoInvalidTxIdLength = "ZRUST0050"
/// Error from rust layer when calling ZcashRustBackend.getScanProgress
case rustGetScanProgress = "ZRUST0051"
/// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight /// Error from rust layer when calling ZcashRustBackend.fullyScannedHeight
case rustFullyScannedHeight = "ZRUST0052" case rustFullyScannedHeight = "ZRUST0052"
/// Error from rust layer when calling ZcashRustBackend.maxScannedHeight /// Error from rust layer when calling ZcashRustBackend.maxScannedHeight
@ -337,4 +343,6 @@ public enum ZcashErrorCode: String {
case synchronizerRewindUnknownArchorHeight = "ZSYNCO0005" case synchronizerRewindUnknownArchorHeight = "ZSYNCO0005"
/// Indicates that this Synchronizer is disconnected from its lightwalletd server. /// Indicates that this Synchronizer is disconnected from its lightwalletd server.
case synchronizerDisconnected = "ZSYNCO0006" case synchronizerDisconnected = "ZSYNCO0006"
/// The attempt to switch endpoints failed. Check that the hostname and port are correct, and are formatted as <hostname>:<port>.
case synchronizerServerSwitch = "ZSYNCO0007"
} }

View File

@ -344,7 +344,11 @@ enum ZcashErrorDefinition {
/// - `progress` value reported /// - `progress` value reported
// sourcery: code="ZRUST0055" // sourcery: code="ZRUST0055"
case rustScanProgressOutOfRange(_ progress: String) case rustScanProgressOutOfRange(_ progress: String)
/// Error from rust layer when calling ZcashRustBackend.getWalletSummary
/// - `rustError` contains error generated by the rust layer.
// sourcery: code="ZRUST0056"
case rustGetWalletSummary(_ rustError: String)
// MARK: - Account DAO // MARK: - Account DAO
/// SQLite query failed when fetching all accounts from the database. /// SQLite query failed when fetching all accounts from the database.
@ -659,4 +663,7 @@ enum ZcashErrorDefinition {
/// Indicates that this Synchronizer is disconnected from its lightwalletd server. /// Indicates that this Synchronizer is disconnected from its lightwalletd server.
// sourcery: code="ZSYNCO0006" // sourcery: code="ZSYNCO0006"
case synchronizerDisconnected case synchronizerDisconnected
/// The attempt to switch endpoints failed. Check that the hostname and port are correct, and are formatted as <hostname>:<port>.
// sourcery: code="ZSYNCO0007"
case synchronizerServerSwitch
} }

View File

@ -111,18 +111,18 @@ public class Initializer {
let container: DIContainer let container: DIContainer
let alias: ZcashSynchronizerAlias let alias: ZcashSynchronizerAlias
let endpoint: LightWalletEndpoint var endpoint: LightWalletEndpoint
let fsBlockDbRoot: URL let fsBlockDbRoot: URL
let generalStorageURL: URL let generalStorageURL: URL
let dataDbURL: URL let dataDbURL: URL
let spendParamsURL: URL let spendParamsURL: URL
let outputParamsURL: URL let outputParamsURL: URL
let saplingParamsSourceURL: SaplingParamsSourceURL let saplingParamsSourceURL: SaplingParamsSourceURL
let lightWalletService: LightWalletService var lightWalletService: LightWalletService
let transactionRepository: TransactionRepository let transactionRepository: TransactionRepository
let accountRepository: AccountRepository let accountRepository: AccountRepository
let storage: CompactBlockRepository let storage: CompactBlockRepository
let blockDownloaderService: BlockDownloaderService var blockDownloaderService: BlockDownloaderService
let network: ZcashNetwork let network: ZcashNetwork
let logger: Logger let logger: Logger
let rustBackend: ZcashRustBackendWelding let rustBackend: ZcashRustBackendWelding
@ -286,10 +286,6 @@ public class Initializer {
self.logger = container.resolve(Logger.self) self.logger = container.resolve(Logger.self)
} }
private static func makeLightWalletServiceFactory(endpoint: LightWalletEndpoint) -> LightWalletServiceFactory {
return LightWalletServiceFactory(endpoint: endpoint)
}
// swiftlint:disable:next function_parameter_count // swiftlint:disable:next function_parameter_count
private static func setup( private static func setup(
container: DIContainer, container: DIContainer,

View File

@ -295,6 +295,12 @@ public protocol Synchronizer: AnyObject {
/// this happens it means that some path passed to `Initializer` is invalid. The SDK can't recover from this and this instance won't do anything. /// this happens it means that some path passed to `Initializer` is invalid. The SDK can't recover from this and this instance won't do anything.
/// ///
func wipe() -> AnyPublisher<Void, Error> func wipe() -> AnyPublisher<Void, Error>
/// This API stops the synchronization and re-initalizes everything according to the new endpoint provided.
/// It can be called anytime.
/// - Throws: ZcashError when failures occur and related to `synchronizer.start(retry: Bool)`, it's the only throwing operation
/// during the whole endpoint change.
func switchTo(endpoint: LightWalletEndpoint) async throws
} }
public enum SyncStatus: Equatable { public enum SyncStatus: Equatable {

View File

@ -18,7 +18,7 @@ enum Dependencies {
enableBackendTracing: Bool = false enableBackendTracing: Bool = false
) { ) {
container.register(type: CheckpointSource.self, isSingleton: true) { _ in container.register(type: CheckpointSource.self, isSingleton: true) { _ in
return CheckpointSourceFactory.fromBundle(for: networkType) CheckpointSourceFactory.fromBundle(for: networkType)
} }
container.register(type: Logger.self, isSingleton: true) { _ in container.register(type: Logger.self, isSingleton: true) { _ in
@ -36,7 +36,7 @@ enum Dependencies {
} }
container.register(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in container.register(type: ZcashRustBackendWelding.self, isSingleton: true) { _ in
return ZcashRustBackend( ZcashRustBackend(
dbData: urls.dataDbURL, dbData: urls.dataDbURL,
fsBlockDbRoot: urls.fsBlockDbRoot, fsBlockDbRoot: urls.fsBlockDbRoot,
spendParamsPath: urls.spendParamsURL, spendParamsPath: urls.spendParamsURL,
@ -47,7 +47,7 @@ enum Dependencies {
} }
container.register(type: LightWalletService.self, isSingleton: true) { _ in container.register(type: LightWalletService.self, isSingleton: true) { _ in
return LightWalletGRPCService(endpoint: endpoint) LightWalletGRPCService(endpoint: endpoint)
} }
container.register(type: TransactionRepository.self, isSingleton: true) { _ in container.register(type: TransactionRepository.self, isSingleton: true) { _ in

View File

@ -44,7 +44,7 @@ public class SDKSynchronizer: Synchronizer {
private let syncSessionIDGenerator: SyncSessionIDGenerator private let syncSessionIDGenerator: SyncSessionIDGenerator
private let syncSession: SyncSession private let syncSession: SyncSession
private let syncSessionTicker: SessionTicker private let syncSessionTicker: SessionTicker
let latestBlocksDataProvider: LatestBlocksDataProvider var latestBlocksDataProvider: LatestBlocksDataProvider
/// Creates an SDKSynchronizer instance /// Creates an SDKSynchronizer instance
/// - Parameter initializer: a wallet Initializer object /// - Parameter initializer: a wallet Initializer object
@ -532,6 +532,90 @@ public class SDKSynchronizer: Synchronizer {
return subject.eraseToAnyPublisher() return subject.eraseToAnyPublisher()
} }
// MARK: Server switch
public func switchTo(endpoint: LightWalletEndpoint) async throws {
// Stop synchronization
let status = await self.status
if status != .stopped && status != .disconnected {
await blockProcessor.stop()
}
// Validation of the server is first because any custom endpoint can be passed here
// Extra instance of the service is created with lower timeout ofr a single call
initializer.container.register(type: LightWalletService.self, isSingleton: true) { _ in
LightWalletGRPCService(
host: endpoint.host,
port: endpoint.port,
secure: endpoint.secure,
singleCallTimeout: 5000,
streamingCallTimeout: endpoint.streamingCallTimeoutInMillis
)
}
let validateSever = ValidateServerAction(
container: initializer.container,
configProvider: CompactBlockProcessor.ConfigProvider(config: await blockProcessor.config)
)
do {
_ = try await validateSever.run(with: ActionContextImpl(state: .idle)) { _ in }
} catch {
throw ZcashError.synchronizerServerSwitch
}
// The `ValidateServerAction` confirmed the server is ok and we can continue
// final instance of the service will be instantiated and propagated to the all parties
// SWITCH TO NEW ENDPOINT
// LightWalletService dependency update
initializer.container.register(type: LightWalletService.self, isSingleton: true) { _ in
LightWalletGRPCService(endpoint: endpoint)
}
// DEPENDENCIES
// BlockDownloaderService dependency update
initializer.container.register(type: BlockDownloaderService.self, isSingleton: true) { di in
let service = di.resolve(LightWalletService.self)
let storage = di.resolve(CompactBlockRepository.self)
return BlockDownloaderServiceImpl(service: service, storage: storage)
}
// LatestBlocksDataProvider dependency update
initializer.container.register(type: LatestBlocksDataProvider.self, isSingleton: true) { di in
let service = di.resolve(LightWalletService.self)
let rustBackend = di.resolve(ZcashRustBackendWelding.self)
return LatestBlocksDataProviderImpl(service: service, rustBackend: rustBackend)
}
// CompactBlockProcessor dependency update
Dependencies.setupCompactBlockProcessor(
in: initializer.container,
config: await blockProcessor.config,
accountRepository: initializer.accountRepository
)
// INITIALIZER
initializer.lightWalletService = initializer.container.resolve(LightWalletService.self)
initializer.blockDownloaderService = initializer.container.resolve(BlockDownloaderService.self)
initializer.endpoint = endpoint
// SELF
self.latestBlocksDataProvider = initializer.container.resolve(LatestBlocksDataProvider.self)
// COMPACT BLOCK PROCESSOR
await blockProcessor.updateService(initializer.container)
// Start synchronization
if status != .unprepared {
try await start(retry: true)
}
}
// MARK: notify state // MARK: notify state
private func snapshotState(status: InternalSyncStatus) async -> SynchronizerState { private func snapshotState(status: InternalSyncStatus) async -> SynchronizerState {

View File

@ -1733,6 +1733,25 @@ class SynchronizerMock: Synchronizer {
} }
} }
// MARK: - switchTo
var switchToEndpointThrowableError: Error?
var switchToEndpointCallsCount = 0
var switchToEndpointCalled: Bool {
return switchToEndpointCallsCount > 0
}
var switchToEndpointReceivedEndpoint: LightWalletEndpoint?
var switchToEndpointClosure: ((LightWalletEndpoint) async throws -> Void)?
func switchTo(endpoint: LightWalletEndpoint) async throws {
if let error = switchToEndpointThrowableError {
throw error
}
switchToEndpointCallsCount += 1
switchToEndpointReceivedEndpoint = endpoint
try await switchToEndpointClosure!(endpoint)
}
} }
class TransactionRepositoryMock: TransactionRepository { class TransactionRepositoryMock: TransactionRepository {