- attached to the processor's timer - added latest scanned time and latest block height - sample app showing the new values alongside with the % - unit tests fixed - latestBlock() API added - the transaction repository is no longer used to update the exposed values during the syncing
This commit is contained in:
parent
b73ac78960
commit
99b24c2081
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" 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="21701" 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"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21678"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -979,16 +979,16 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<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="201.33333333333337"/>
|
||||
<rect key="frame" x="0.0" y="79.000000000000014" width="374" height="177.33333333333337"/>
|
||||
<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">
|
||||
<rect key="frame" x="0.0" y="81.666666666666657" width="95.666666666666671" height="38.333333333333343"/>
|
||||
<rect key="frame" x="0.0" y="69.666666666666657" width="95.666666666666671" height="38.333333333333343"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="32"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</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">
|
||||
<rect key="frame" x="108.66666666666666" y="87" width="265.33333333333337" height="27.666666666666671"/>
|
||||
<rect key="frame" x="108.66666666666666" y="75" width="265.33333333333337" height="27.666666666666671"/>
|
||||
<fontDescription key="fontDescription" type="italicSystem" pointSize="23"/>
|
||||
<color key="textColor" systemColor="scrollViewTexturedBackgroundColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
|
@ -999,20 +999,26 @@
|
|||
</constraints>
|
||||
</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">
|
||||
<rect key="frame" x="0.0" y="304.33333333333331" width="366" height="43"/>
|
||||
<rect key="frame" x="0.0" y="280.33333333333331" width="366" height="43"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="36"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<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="371.33333333333331" width="366" height="2.6666666666666856"/>
|
||||
<rect key="frame" x="0.0" y="347.33333333333331" width="366" height="2.6666666666666856"/>
|
||||
</progressView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="0%" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kXE-5z-HN2">
|
||||
<rect key="frame" x="0.0" y="397" width="374" height="39.666666666666686"/>
|
||||
<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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="33"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</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">
|
||||
<rect key="frame" x="0.0" y="436.66666666666663" width="0.0" height="0.0"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="27"/>
|
||||
|
@ -1071,6 +1077,7 @@
|
|||
<connections>
|
||||
<outlet property="metricLabel" destination="XK2-GA-Ufv" id="oej-al-2Of"/>
|
||||
<outlet property="progressBar" destination="oKg-9s-8Ym" id="fbY-Hb-EPl"/>
|
||||
<outlet property="progressDataLabel" destination="x3B-hR-coo" id="uyX-dj-EVb"/>
|
||||
<outlet property="progressLabel" destination="kXE-5z-HN2" id="Eez-By-eZj"/>
|
||||
<outlet property="startPause" destination="G5M-gm-1ux" id="Odc-mw-E1D"/>
|
||||
<outlet property="statusLabel" destination="Jj9-7r-s2Y" id="nuZ-ad-FaF"/>
|
||||
|
@ -1086,17 +1093,17 @@
|
|||
<objects>
|
||||
<viewController id="tq2-zN-roj" customClass="LatestHeightViewController" customModule="ZcashLightClientSample" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="tie-BL-1Ip">
|
||||
<rect key="frame" x="0.0" y="0.0" width="390" height="787"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="390" height="834"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0Hj-Jx-J3i">
|
||||
<rect key="frame" x="0.0" y="393.66666666666669" width="390" height="0.0"/>
|
||||
<rect key="frame" x="0.0" y="417" width="390" height="0.0"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="23"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Latest Block Height" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WKf-j9-SjN">
|
||||
<rect key="frame" x="16" y="305" width="358" height="49"/>
|
||||
<rect key="frame" x="16" y="258" width="358" height="49"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="49" id="AXS-cf-OMk"/>
|
||||
</constraints>
|
||||
|
|
|
@ -16,6 +16,7 @@ class SyncBlocksViewController: UIViewController {
|
|||
@IBOutlet weak var statusLabel: UILabel!
|
||||
@IBOutlet weak var progressBar: UIProgressView!
|
||||
@IBOutlet weak var progressLabel: UILabel!
|
||||
@IBOutlet weak var progressDataLabel: UILabel!
|
||||
@IBOutlet weak var startPause: UIButton!
|
||||
@IBOutlet weak var metricLabel: UILabel!
|
||||
@IBOutlet weak var summaryLabel: UILabel!
|
||||
|
@ -36,6 +37,7 @@ class SyncBlocksViewController: UIViewController {
|
|||
}
|
||||
|
||||
var cancellables: [AnyCancellable] = []
|
||||
let dateFormatter = DateFormatter()
|
||||
|
||||
let synchronizer = AppDelegate.shared.sharedSynchronizer
|
||||
let closureSynchronizer = ClosureSDKSynchronizer(synchronizer: AppDelegate.shared.sharedSynchronizer)
|
||||
|
@ -55,6 +57,8 @@ class SyncBlocksViewController: UIViewController {
|
|||
|
||||
statusLabel.text = textFor(state: synchronizer.latestState.syncStatus)
|
||||
progressBar.progress = 0
|
||||
dateFormatter.dateStyle = .short
|
||||
dateFormatter.timeStyle = .short
|
||||
|
||||
synchronizer.stateStream
|
||||
.throttle(for: .seconds(0.2), scheduler: DispatchQueue.main, latest: true)
|
||||
|
@ -80,6 +84,13 @@ class SyncBlocksViewController: UIViewController {
|
|||
|
||||
progressBar.progress = progress.progress
|
||||
progressLabel.text = "\(floor(progress.progress * 1000) / 10)%"
|
||||
let syncedDate = dateFormatter.string(from: Date(timeIntervalSince1970: state.latestScannedTime))
|
||||
let progressText = """
|
||||
synced date \(syncedDate)
|
||||
synced block \(state.latestScannedHeight)
|
||||
target block \(state.latestBlockHeight)
|
||||
"""
|
||||
progressDataLabel.text = progressText
|
||||
|
||||
if let currentMetric {
|
||||
let report = synchronizer.metrics.popBlock(operation: currentMetric)?.last
|
||||
|
|
|
@ -311,6 +311,7 @@ actor CompactBlockProcessor {
|
|||
let blockEnhancer: BlockEnhancer
|
||||
let utxoFetcher: UTXOFetcher
|
||||
let saplingParametersHandler: SaplingParametersHandler
|
||||
private let latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
|
||||
var service: LightWalletService
|
||||
var storage: CompactBlockRepository
|
||||
|
@ -347,7 +348,8 @@ actor CompactBlockProcessor {
|
|||
rustBackend: ZcashRustBackendWelding,
|
||||
config: Configuration,
|
||||
metrics: SDKMetrics,
|
||||
logger: Logger
|
||||
logger: Logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
) {
|
||||
self.init(
|
||||
service: service,
|
||||
|
@ -357,7 +359,8 @@ actor CompactBlockProcessor {
|
|||
repository: TransactionRepositoryBuilder.build(dataDbURL: config.dataDb),
|
||||
accountRepository: AccountRepositoryBuilder.build(dataDbURL: config.dataDb, readOnly: true, logger: logger),
|
||||
metrics: metrics,
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -368,6 +371,7 @@ actor CompactBlockProcessor {
|
|||
initializer: Initializer,
|
||||
metrics: SDKMetrics,
|
||||
logger: Logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider,
|
||||
walletBirthdayProvider: @escaping () -> BlockHeight
|
||||
) {
|
||||
self.init(
|
||||
|
@ -387,7 +391,8 @@ actor CompactBlockProcessor {
|
|||
repository: initializer.transactionRepository,
|
||||
accountRepository: initializer.accountRepository,
|
||||
metrics: metrics,
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -399,10 +404,12 @@ actor CompactBlockProcessor {
|
|||
repository: TransactionRepository,
|
||||
accountRepository: AccountRepository,
|
||||
metrics: SDKMetrics,
|
||||
logger: Logger
|
||||
logger: Logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
) {
|
||||
self.metrics = metrics
|
||||
self.logger = logger
|
||||
self.latestBlocksDataProvider = latestBlocksDataProvider
|
||||
let internalSyncProgress = InternalSyncProgress(alias: config.alias, storage: UserDefaults.standard, logger: logger)
|
||||
self.internalSyncProgress = internalSyncProgress
|
||||
let blockDownloaderService = BlockDownloaderServiceImpl(service: service, storage: storage)
|
||||
|
@ -433,7 +440,8 @@ actor CompactBlockProcessor {
|
|||
rustBackend: rustBackend,
|
||||
transactionRepository: repository,
|
||||
metrics: metrics,
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
)
|
||||
|
||||
self.blockEnhancer = BlockEnhancerImpl(
|
||||
|
@ -710,8 +718,6 @@ actor CompactBlockProcessor {
|
|||
/// Processes new blocks on the given range based on the configuration set for this instance
|
||||
func processNewBlocks(ranges: SyncRanges) async {
|
||||
self.foundBlocks = true
|
||||
self.backoffTimer?.invalidate()
|
||||
self.backoffTimer = nil
|
||||
|
||||
cancelableTask = Task(priority: .userInitiated) {
|
||||
do {
|
||||
|
@ -991,11 +997,12 @@ actor CompactBlockProcessor {
|
|||
|
||||
private func nextBatch() async {
|
||||
await updateState(.syncing)
|
||||
if backoffTimer == nil { await setTimer() }
|
||||
do {
|
||||
let nextState = try await NextStateHelper.nextState(
|
||||
service: self.service,
|
||||
downloaderService: blockDownloaderService,
|
||||
transactionRepository: transactionRepository,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider,
|
||||
config: self.config,
|
||||
rustBackend: self.rustBackend,
|
||||
internalSyncProgress: internalSyncProgress
|
||||
|
@ -1085,18 +1092,23 @@ actor CompactBlockProcessor {
|
|||
block: { [weak self] _ in
|
||||
Task { [weak self] in
|
||||
guard let self else { return }
|
||||
if await self.shouldStart {
|
||||
self.logger.debug(
|
||||
"""
|
||||
Timer triggered: Starting compact Block processor!.
|
||||
Processor State: \(await self.state)
|
||||
latestHeight: \(try await self.transactionRepository.lastScannedHeight())
|
||||
attempts: \(await self.retryAttempts)
|
||||
"""
|
||||
)
|
||||
await self.start()
|
||||
} else if await self.maxAttemptsReached {
|
||||
await self.fail(CompactBlockProcessorError.maxAttemptsReached(attempts: self.config.retries))
|
||||
switch await self.state {
|
||||
case .syncing, .enhancing, .fetching, .handlingSaplingFiles:
|
||||
await self.latestBlocksDataProvider.updateBlockData()
|
||||
case .stopped, .error, .synced:
|
||||
if await self.shouldStart {
|
||||
self.logger.debug(
|
||||
"""
|
||||
Timer triggered: Starting compact Block processor!.
|
||||
Processor State: \(await self.state)
|
||||
latestHeight: \(try await self.transactionRepository.lastScannedHeight())
|
||||
attempts: \(await self.retryAttempts)
|
||||
"""
|
||||
)
|
||||
await self.start()
|
||||
} else if await self.maxAttemptsReached {
|
||||
await self.fail(CompactBlockProcessorError.maxAttemptsReached(attempts: self.config.retries))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1329,7 +1341,7 @@ extension CompactBlockProcessor {
|
|||
return try await CompactBlockProcessor.NextStateHelper.nextState(
|
||||
service: service,
|
||||
downloaderService: downloaderService,
|
||||
transactionRepository: transactionRepository,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider,
|
||||
config: config,
|
||||
rustBackend: rustBackend,
|
||||
internalSyncProgress: internalSyncProgress
|
||||
|
@ -1346,7 +1358,7 @@ extension CompactBlockProcessor {
|
|||
static func nextState(
|
||||
service: LightWalletService,
|
||||
downloaderService: BlockDownloaderService,
|
||||
transactionRepository: TransactionRepository,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider,
|
||||
config: Configuration,
|
||||
rustBackend: ZcashRustBackendWelding,
|
||||
internalSyncProgress: InternalSyncProgress
|
||||
|
@ -1367,12 +1379,12 @@ extension CompactBlockProcessor {
|
|||
|
||||
await internalSyncProgress.migrateIfNeeded(latestDownloadedBlockHeightFromCacheDB: latestDownloadHeight)
|
||||
|
||||
let latestBlockHeight = try await service.latestBlockHeight()
|
||||
let latestScannedHeight = try await transactionRepository.lastScannedHeight()
|
||||
await latestBlocksDataProvider.updateScannedData()
|
||||
await latestBlocksDataProvider.updateBlockData()
|
||||
|
||||
return try await internalSyncProgress.computeNextState(
|
||||
latestBlockHeight: latestBlockHeight,
|
||||
latestScannedHeight: latestScannedHeight,
|
||||
latestBlockHeight: latestBlocksDataProvider.latestBlockHeight,
|
||||
latestScannedHeight: latestBlocksDataProvider.latestScannedHeight,
|
||||
walletBirthday: config.walletBirthday
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ struct BlockScannerImpl {
|
|||
let transactionRepository: TransactionRepository
|
||||
let metrics: SDKMetrics
|
||||
let logger: Logger
|
||||
let latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
}
|
||||
|
||||
extension BlockScannerImpl: BlockScanner {
|
||||
|
@ -52,8 +53,12 @@ extension BlockScannerImpl: BlockScanner {
|
|||
|
||||
let scanFinishTime = Date()
|
||||
|
||||
lastScannedHeight = try await transactionRepository.lastScannedHeight()
|
||||
|
||||
if let lastScannedBlock = try await transactionRepository.lastScannedBlock() {
|
||||
lastScannedHeight = lastScannedBlock.height
|
||||
await latestBlocksDataProvider.updateLatestScannedHeight(lastScannedHeight)
|
||||
await latestBlocksDataProvider.updateLatestScannedTime(TimeInterval(lastScannedBlock.time))
|
||||
}
|
||||
|
||||
scannedNewBlocks = previousScannedHeight != lastScannedHeight
|
||||
if scannedNewBlocks {
|
||||
await didScan(lastScannedHeight)
|
||||
|
|
|
@ -11,6 +11,7 @@ import SQLite
|
|||
|
||||
protocol BlockDao {
|
||||
func latestBlockHeight() throws -> BlockHeight
|
||||
func latestBlock() throws -> Block?
|
||||
func block(at height: BlockHeight) throws -> Block?
|
||||
}
|
||||
|
||||
|
@ -41,7 +42,7 @@ class BlockSQLDAO: BlockDao {
|
|||
var dbProvider: ConnectionProvider
|
||||
var table: Table
|
||||
var height = Expression<Int>("height")
|
||||
|
||||
|
||||
init(dbProvider: ConnectionProvider) {
|
||||
self.dbProvider = dbProvider
|
||||
self.table = Table("Blocks")
|
||||
|
@ -54,10 +55,18 @@ class BlockSQLDAO: BlockDao {
|
|||
.map({ try $0.decode() })
|
||||
.first
|
||||
}
|
||||
|
||||
|
||||
func latestBlockHeight() throws -> BlockHeight {
|
||||
try dbProvider.connection().scalar(table.select(height.max)) ?? BlockHeight.empty()
|
||||
}
|
||||
|
||||
func latestBlock() throws -> Block? {
|
||||
try dbProvider
|
||||
.connection()
|
||||
.prepare(Block.table.order(height.desc).limit(1))
|
||||
.map({ try $0.decode() })
|
||||
.first
|
||||
}
|
||||
}
|
||||
|
||||
extension BlockSQLDAO: BlockRepository {
|
||||
|
|
|
@ -43,6 +43,10 @@ class TransactionSQLDAO: TransactionRepository {
|
|||
try blockDao.latestBlockHeight()
|
||||
}
|
||||
|
||||
func lastScannedBlock() async throws -> Block? {
|
||||
try blockDao.latestBlock()
|
||||
}
|
||||
|
||||
func isInitialized() async throws -> Bool {
|
||||
true
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// File.swift
|
||||
// URL+UpdateWithAlias.swift
|
||||
//
|
||||
//
|
||||
// Created by Michal Fousek on 23.03.2023.
|
||||
|
|
|
@ -154,7 +154,6 @@ protocol LightWalletService: AnyObject {
|
|||
func getInfo() async throws -> LightWalletdInfo
|
||||
|
||||
/// Return the latest block height known to the service.
|
||||
/// Blocking API
|
||||
func latestBlockHeight() async throws -> BlockHeight
|
||||
|
||||
/// Return the given range of blocks.
|
||||
|
@ -162,7 +161,7 @@ protocol LightWalletService: AnyObject {
|
|||
/// For instance if 1..5 is given, then every block in that will be fetched, including 1 and 5.
|
||||
func blockRange(_ range: CompactBlockRange) -> AsyncThrowingStream<ZcashCompactBlock, Error>
|
||||
|
||||
/// Submits a raw transaction over lightwalletd. Non-Blocking
|
||||
/// Submits a raw transaction over lightwalletd.
|
||||
/// - Parameter spendTransaction: data representing the transaction to be sent
|
||||
func submit(spendTransaction: Data) async throws -> LightWalletServiceResponse
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// LatestBlocksDataProvider.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 11.04.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol LatestBlocksDataProvider {
|
||||
var latestScannedHeight: BlockHeight { get async }
|
||||
var latestScannedTime: TimeInterval { get async }
|
||||
var latestBlockHeight: BlockHeight { get async }
|
||||
var walletBirthday: BlockHeight { get async }
|
||||
|
||||
func updateScannedData() async
|
||||
func updateBlockData() async
|
||||
func updateWalletBirthday(_ walletBirthday: BlockHeight) async
|
||||
func updateLatestScannedHeight(_ latestScannedHeight: BlockHeight) async
|
||||
func updateLatestScannedTime(_ latestScannedTime: TimeInterval) async
|
||||
}
|
||||
|
||||
actor LatestBlocksDataProviderImpl: LatestBlocksDataProvider {
|
||||
let service: LightWalletService
|
||||
let transactionRepository: TransactionRepository
|
||||
|
||||
// Valid values are stored here after Synchronizer's `prepare` is called.
|
||||
private(set) var latestScannedHeight: BlockHeight = .zero
|
||||
private(set) var latestScannedTime: TimeInterval = 0.0
|
||||
// Valid value is stored here after block processor's `nextState` is called.
|
||||
private(set) var latestBlockHeight: BlockHeight = .zero
|
||||
// Valid values are stored here after Synchronizer's `prepare` is called.
|
||||
private(set) var walletBirthday: BlockHeight = .zero
|
||||
|
||||
init(service: LightWalletService, transactionRepository: TransactionRepository) {
|
||||
self.service = service
|
||||
self.transactionRepository = transactionRepository
|
||||
}
|
||||
|
||||
/// Call of this function is potentially dangerous and can result in `database lock` errors.
|
||||
/// Typical use is outside of a sync process. Example: Synchronizer's prepare function, call there is a safe one.
|
||||
/// The update of `latestScannedHeight` and `latestScannedTime` during the syncing is done via
|
||||
/// appropriate `updateX()` methods inside `BlockScanner` so `transactionRepository` is omitted.
|
||||
func updateScannedData() async {
|
||||
latestScannedHeight = (try? await transactionRepository.lastScannedHeight()) ?? walletBirthday
|
||||
if let time = try? await transactionRepository.blockForHeight(latestScannedHeight)?.time {
|
||||
latestScannedTime = TimeInterval(time)
|
||||
}
|
||||
}
|
||||
|
||||
func updateBlockData() async {
|
||||
if let newLatestBlockHeight = try? await service.latestBlockHeight(),
|
||||
latestBlockHeight < newLatestBlockHeight {
|
||||
latestBlockHeight = newLatestBlockHeight
|
||||
}
|
||||
}
|
||||
|
||||
func updateWalletBirthday(_ walletBirthday: BlockHeight) async {
|
||||
self.walletBirthday = walletBirthday
|
||||
}
|
||||
|
||||
func updateLatestScannedHeight(_ latestScannedHeight: BlockHeight) async {
|
||||
self.latestScannedHeight = latestScannedHeight
|
||||
}
|
||||
|
||||
func updateLatestScannedTime(_ latestScannedTime: TimeInterval) async {
|
||||
self.latestScannedTime = latestScannedTime
|
||||
}
|
||||
}
|
|
@ -38,7 +38,6 @@ protocol CompactBlockRepository {
|
|||
|
||||
/**
|
||||
Write the given blocks to this store, which may be anything from an in-memory cache to a DB.
|
||||
Non-Blocking
|
||||
- Parameters:
|
||||
- Parameter blocks: array of blocks to be written to storage
|
||||
- Throws: an error when there's a failure
|
||||
|
|
|
@ -24,12 +24,12 @@ public protocol PaginatedTransactionRepository {
|
|||
var itemCount: Int { get async }
|
||||
|
||||
/**
|
||||
Returns the page number if exists. Blocking
|
||||
Returns the page number if exists.
|
||||
*/
|
||||
func page(_ number: Int) async throws -> [ZcashTransaction.Overview]?
|
||||
|
||||
/**
|
||||
Returns the page number if exists. Non-blocking
|
||||
Returns the page number if exists.
|
||||
*/
|
||||
func page(_ number: Int, result: @escaping (Result<[ZcashTransaction.Overview]?, Error>) -> Void)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ protocol TransactionRepository {
|
|||
func countUnmined() async throws -> Int
|
||||
func blockForHeight(_ height: BlockHeight) async throws -> Block?
|
||||
func lastScannedHeight() async throws -> BlockHeight
|
||||
func lastScannedBlock() async throws -> Block?
|
||||
func isInitialized() async throws -> Bool
|
||||
func find(id: Int) async throws -> ZcashTransaction.Overview
|
||||
func find(rawID: Data) async throws -> ZcashTransaction.Overview
|
||||
|
|
|
@ -80,6 +80,11 @@ public struct SynchronizerState: Equatable {
|
|||
public var syncStatus: SyncStatus
|
||||
/// height of the latest scanned block known to this synchronizer.
|
||||
public var latestScannedHeight: BlockHeight
|
||||
/// height of the latest block on the blockchain known to this synchronizer.
|
||||
public var latestBlockHeight: BlockHeight
|
||||
/// timestamp of the latest scanned block on the blockchain known to this synchronizer.
|
||||
/// The anchor point is timeIntervalSince1970
|
||||
public var latestScannedTime: TimeInterval
|
||||
|
||||
/// Represents a synchronizer that has made zero progress hasn't done a sync attempt
|
||||
public static var zero: SynchronizerState {
|
||||
|
@ -88,7 +93,9 @@ public struct SynchronizerState: Equatable {
|
|||
shieldedBalance: .zero,
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .unprepared,
|
||||
latestScannedHeight: .zero
|
||||
latestScannedHeight: .zero,
|
||||
latestBlockHeight: .zero,
|
||||
latestScannedTime: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +275,6 @@ public protocol Synchronizer: AnyObject {
|
|||
func allConfirmedTransactions(from transaction: ZcashTransaction.Overview, limit: Int) async throws -> [ZcashTransaction.Overview]
|
||||
|
||||
/// Returns the latest block height from the provided Lightwallet endpoint
|
||||
/// Blocking
|
||||
func latestHeight() async throws -> BlockHeight
|
||||
|
||||
/// Returns the latests UTXOs for the given address from the specified height on
|
||||
|
|
|
@ -35,8 +35,6 @@ public class SDKSynchronizer: Synchronizer {
|
|||
lazy var blockProcessorEventProcessingQueue = { DispatchQueue(label: "blockProcessorEventProcessingQueue_\(initializer.alias.description)") }()
|
||||
|
||||
public private(set) var initializer: Initializer
|
||||
// Valid value is stored here after `prepare` is called.
|
||||
public private(set) var latestScannedHeight: BlockHeight = .zero
|
||||
public private(set) var connectionState: ConnectionState
|
||||
public private(set) var network: ZcashNetwork
|
||||
private var transactionManager: OutboundTransactionManager
|
||||
|
@ -47,11 +45,16 @@ public class SDKSynchronizer: Synchronizer {
|
|||
private var syncSession: SyncSession
|
||||
private var syncSessionTicker: SessionTicker
|
||||
private var syncStartDate: Date?
|
||||
let latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
|
||||
/// Creates an SDKSynchronizer instance
|
||||
/// - Parameter initializer: a wallet Initializer object
|
||||
public convenience init(initializer: Initializer) {
|
||||
let metrics = SDKMetrics()
|
||||
let latestBlocksDataProvider = LatestBlocksDataProviderImpl(
|
||||
service: initializer.lightWalletService,
|
||||
transactionRepository: initializer.transactionRepository
|
||||
)
|
||||
self.init(
|
||||
status: .unprepared,
|
||||
initializer: initializer,
|
||||
|
@ -62,11 +65,13 @@ public class SDKSynchronizer: Synchronizer {
|
|||
initializer: initializer,
|
||||
metrics: metrics,
|
||||
logger: initializer.logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider,
|
||||
walletBirthdayProvider: { initializer.walletBirthday }
|
||||
),
|
||||
metrics: metrics,
|
||||
syncSessionIDGenerator: UniqueSyncSessionIDGenerator(),
|
||||
syncSessionTicker: .live
|
||||
syncSessionTicker: .live,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -79,7 +84,8 @@ public class SDKSynchronizer: Synchronizer {
|
|||
blockProcessor: CompactBlockProcessor,
|
||||
metrics: SDKMetrics,
|
||||
syncSessionIDGenerator: SyncSessionIDGenerator,
|
||||
syncSessionTicker: SessionTicker
|
||||
syncSessionTicker: SessionTicker,
|
||||
latestBlocksDataProvider: LatestBlocksDataProvider
|
||||
) {
|
||||
self.connectionState = .idle
|
||||
self.underlyingStatus = GenericActor(status)
|
||||
|
@ -94,6 +100,7 @@ public class SDKSynchronizer: Synchronizer {
|
|||
self.syncSessionIDGenerator = syncSessionIDGenerator
|
||||
self.syncSession = SyncSession(.nullID)
|
||||
self.syncSessionTicker = syncSessionTicker
|
||||
self.latestBlocksDataProvider = latestBlocksDataProvider
|
||||
|
||||
initializer.lightWalletService.connectionStateChange = { [weak self] oldState, newState in
|
||||
self?.connectivityStateChanged(oldState: oldState, newState: newState)
|
||||
|
@ -149,8 +156,9 @@ public class SDKSynchronizer: Synchronizer {
|
|||
return .seedRequired
|
||||
}
|
||||
|
||||
latestScannedHeight = (try? await transactionRepository.lastScannedHeight()) ?? initializer.walletBirthday
|
||||
|
||||
await latestBlocksDataProvider.updateWalletBirthday(initializer.walletBirthday)
|
||||
await latestBlocksDataProvider.updateScannedData()
|
||||
|
||||
await updateStatus(.disconnected)
|
||||
|
||||
return .success
|
||||
|
@ -241,8 +249,8 @@ public class SDKSynchronizer: Synchronizer {
|
|||
}
|
||||
|
||||
private func finished(lastScannedHeight: BlockHeight, foundBlocks: Bool) async {
|
||||
await latestBlocksDataProvider.updateScannedData()
|
||||
// FIX: Pending transaction updates fail if done from another thread. Improvement needed: explicitly define queues for sql repositories see: https://github.com/zcash/ZcashLightClientKit/issues/450
|
||||
latestScannedHeight = lastScannedHeight
|
||||
await refreshPendingTransactions()
|
||||
await updateStatus(.synced)
|
||||
|
||||
|
@ -328,7 +336,7 @@ public class SDKSynchronizer: Synchronizer {
|
|||
let tBalance = try await self.getTransparentBalance(accountIndex: accountIndex)
|
||||
|
||||
// Verify that at least there are funds for the fee. Ideally this logic will be improved by the shielding wallet.
|
||||
guard tBalance.verified >= self.network.constants.defaultFee(for: self.latestScannedHeight) else {
|
||||
guard tBalance.verified >= self.network.constants.defaultFee(for: await self.latestBlocksDataProvider.latestScannedHeight) else {
|
||||
throw ShieldFundsError.insuficientTransparentFunds
|
||||
}
|
||||
|
||||
|
@ -574,7 +582,7 @@ public class SDKSynchronizer: Synchronizer {
|
|||
// MARK: notify state
|
||||
|
||||
private func snapshotState(status: SyncStatus) async -> SynchronizerState {
|
||||
await SynchronizerState(
|
||||
return await SynchronizerState(
|
||||
syncSessionID: syncSession.value,
|
||||
shieldedBalance: WalletBalance(
|
||||
verified: (try? await getShieldedVerifiedBalance()) ?? .zero,
|
||||
|
@ -582,7 +590,9 @@ public class SDKSynchronizer: Synchronizer {
|
|||
),
|
||||
transparentBalance: (try? await blockProcessor.getTransparentBalance(accountIndex: 0)) ?? .zero,
|
||||
syncStatus: status,
|
||||
latestScannedHeight: self.latestScannedHeight
|
||||
latestScannedHeight: latestBlocksDataProvider.latestScannedHeight,
|
||||
latestBlockHeight: latestBlocksDataProvider.latestBlockHeight,
|
||||
latestScannedTime: latestBlocksDataProvider.latestScannedTime
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -602,21 +612,10 @@ public class SDKSynchronizer: Synchronizer {
|
|||
nextState.syncSessionID = nextSessionID
|
||||
newState = nextState
|
||||
} else {
|
||||
if oldStatus.isDifferent(from: newStatus) {
|
||||
if SessionTicker.live.isNewSyncSession(oldStatus, newStatus) {
|
||||
await self.syncSession.newSession(with: self.syncSessionIDGenerator)
|
||||
}
|
||||
|
||||
newState = await snapshotState(status: newStatus)
|
||||
} else {
|
||||
newState = await SynchronizerState(
|
||||
syncSessionID: syncSession.value,
|
||||
shieldedBalance: latestState.shieldedBalance,
|
||||
transparentBalance: latestState.transparentBalance,
|
||||
syncStatus: newStatus,
|
||||
latestScannedHeight: latestState.latestScannedHeight
|
||||
)
|
||||
if SessionTicker.live.isNewSyncSession(oldStatus, newStatus) {
|
||||
await self.syncSession.newSession(with: self.syncSessionIDGenerator)
|
||||
}
|
||||
newState = await snapshotState(status: newStatus)
|
||||
}
|
||||
|
||||
latestState = newState
|
||||
|
|
|
@ -21,7 +21,6 @@ protocol TransactionEncoder {
|
|||
/// Creates a transaction, throwing an exception whenever things are missing. When the provided wallet implementation
|
||||
/// doesn't throw an exception, we wrap the issue into a descriptive exception ourselves (rather than using
|
||||
/// double-bangs for things).
|
||||
/// Non-blocking
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - Parameter spendingKey: a `UnifiedSpendingKey` containing the spending key
|
||||
|
@ -37,16 +36,15 @@ protocol TransactionEncoder {
|
|||
from accountIndex: Int
|
||||
) async throws -> ZcashTransaction.Overview
|
||||
|
||||
/**
|
||||
Creates a transaction that will attempt to shield transparent funds that are present on the blocks cache .throwing an exception whenever things are missing. When the provided wallet implementation doesn't throw an exception, we wrap the issue into a descriptive exception ourselves (rather than using double-bangs for things).
|
||||
Blocking
|
||||
|
||||
- Parameters:
|
||||
- Parameter spendingKey: `UnifiedSpendingKey` to spend the UTXOs
|
||||
- Parameter memoBytes: containing the memo (optional)
|
||||
- Parameter accountIndex: index of the account that will be used to send the funds
|
||||
- Throws: a TransactionEncoderError
|
||||
*/
|
||||
/// Creates a transaction that will attempt to shield transparent funds that are present on the blocks cache .throwing
|
||||
/// an exception whenever things are missing. When the provided wallet implementation doesn't throw an exception,
|
||||
/// we wrap the issue into a descriptive exception ourselves (rather than using double-bangs for things).
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - Parameter spendingKey: `UnifiedSpendingKey` to spend the UTXOs
|
||||
/// - Parameter memoBytes: containing the memo (optional)
|
||||
/// - Parameter accountIndex: index of the account that will be used to send the funds
|
||||
/// - Throws: a TransactionEncoderError
|
||||
func createShieldingTransaction(
|
||||
spendingKey: UnifiedSpendingKey,
|
||||
shieldingThreshold: Zatoshi,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// File.swift
|
||||
// SyncSessionIDGenerator.swift
|
||||
//
|
||||
//
|
||||
// Created by Francisco Gindre on 3/31/23.
|
||||
|
|
|
@ -1336,7 +1336,7 @@ class AdvancedReOrgTests: XCTestCase {
|
|||
|
||||
wait(for: [firstSyncExpectation], timeout: 600)
|
||||
|
||||
let latestScannedHeight = coordinator.synchronizer.latestScannedHeight
|
||||
let latestScannedHeight = await coordinator.synchronizer.latestBlocksDataProvider.latestScannedHeight
|
||||
XCTAssertEqual(latestScannedHeight, birthday + fullSyncLength)
|
||||
}
|
||||
|
||||
|
|
|
@ -180,33 +180,42 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
shieldedBalance: .zero,
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .disconnected,
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1576821833
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: .zero,
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .syncing(BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1576821833
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: .zero,
|
||||
// shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .syncing(BlockProgress(startHeight: 663150, targetHeight: 663189, progressHeight: 663189)),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .enhancing(EnhancementProgress(totalTransactions: 0, enhancedTransactions: 0, lastFoundTransaction: nil, range: 0...0)),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .enhancing(
|
||||
EnhancementProgress(
|
||||
totalTransactions: 2,
|
||||
|
@ -230,12 +239,14 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
range: 663150...663189
|
||||
)
|
||||
),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .enhancing(
|
||||
EnhancementProgress(
|
||||
totalTransactions: 2,
|
||||
|
@ -259,21 +270,27 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
range: 663150...663189
|
||||
)
|
||||
),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .synced,
|
||||
latestScannedHeight: 663189
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 663189,
|
||||
latestScannedTime: 1
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -317,28 +334,36 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
shieldedBalance: .zero,
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .disconnected,
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: .zero,
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .syncing(BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: .zero,
|
||||
transparentBalance: .zero,
|
||||
syncStatus: .syncing(BlockProgress(startHeight: 663150, targetHeight: 663189, progressHeight: 663189)),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .enhancing(EnhancementProgress(totalTransactions: 0, enhancedTransactions: 0, lastFoundTransaction: nil, range: 0...0)),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
|
@ -367,7 +392,9 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
range: 663150...663189
|
||||
)
|
||||
),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
|
@ -396,21 +423,27 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
range: 663150...663189
|
||||
)
|
||||
),
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 663150
|
||||
latestScannedHeight: 663150,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[0],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .synced,
|
||||
latestScannedHeight: 663189
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
)
|
||||
]
|
||||
|
||||
|
@ -439,35 +472,45 @@ class SynchronizerDarksideTests: XCTestCase {
|
|||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .syncing(BlockProgress(startHeight: 0, targetHeight: 0, progressHeight: 0)),
|
||||
latestScannedHeight: 663189
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[1],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .syncing(BlockProgress(startHeight: 663190, targetHeight: 663200, progressHeight: 663200)),
|
||||
latestScannedHeight: 663189
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[1],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .enhancing(EnhancementProgress(totalTransactions: 0, enhancedTransactions: 0, lastFoundTransaction: nil, range: 0...0)),
|
||||
latestScannedHeight: 663189
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[1],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 663189
|
||||
latestScannedHeight: 663189,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
),
|
||||
SynchronizerState(
|
||||
syncSessionID: uuids[1],
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(200000), total: Zatoshi(200000)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(0), total: Zatoshi(0)),
|
||||
syncStatus: .synced,
|
||||
latestScannedHeight: 663200
|
||||
latestScannedHeight: 663200,
|
||||
latestBlockHeight: 0,
|
||||
latestScannedTime: 0
|
||||
)
|
||||
]
|
||||
|
||||
|
|
|
@ -125,6 +125,14 @@ class TransactionEnhancementTests: XCTestCase {
|
|||
)
|
||||
try! await storage.create()
|
||||
|
||||
let transactionRepository = MockTransactionRepository(
|
||||
unminedCount: 0,
|
||||
receivedCount: 0,
|
||||
sentCount: 0,
|
||||
scannedHeight: 0,
|
||||
network: network
|
||||
)
|
||||
|
||||
downloader = BlockDownloaderServiceImpl(service: service, storage: storage)
|
||||
processor = CompactBlockProcessor(
|
||||
service: service,
|
||||
|
@ -132,7 +140,8 @@ class TransactionEnhancementTests: XCTestCase {
|
|||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||
)
|
||||
|
||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||
|
|
|
@ -110,7 +110,8 @@ class BlockScanTests: XCTestCase {
|
|||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
let repository = BlockSQLDAO(dbProvider: SimpleConnectionProvider.init(path: self.dataDbURL.absoluteString, readonly: true))
|
||||
|
@ -197,7 +198,8 @@ class BlockScanTests: XCTestCase {
|
|||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: metrics,
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
let eventClosure: CompactBlockProcessor.EventClosure = { [weak self] event in
|
||||
|
|
|
@ -96,7 +96,8 @@ class BlockStreamingTest: XCTestCase {
|
|||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
let cancelableTask = Task {
|
||||
|
@ -160,7 +161,8 @@ class BlockStreamingTest: XCTestCase {
|
|||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
let date = Date()
|
||||
|
|
|
@ -90,13 +90,22 @@ class CompactBlockProcessorTests: XCTestCase {
|
|||
|
||||
try await storage.create()
|
||||
|
||||
let transactionRepository = MockTransactionRepository(
|
||||
unminedCount: 0,
|
||||
receivedCount: 0,
|
||||
sentCount: 0,
|
||||
scannedHeight: 0,
|
||||
network: network
|
||||
)
|
||||
|
||||
processor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: storage,
|
||||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||
)
|
||||
|
||||
let dbInit = try await rustBackend.initDataDb(seed: nil)
|
||||
|
|
|
@ -104,13 +104,22 @@ class CompactBlockReorgTests: XCTestCase {
|
|||
mockValidateCombinedChainFailureError: .invalidChain(upperBound: Int32(network.constants.saplingActivationHeight + 320))
|
||||
)
|
||||
|
||||
let transactionRepository = MockTransactionRepository(
|
||||
unminedCount: 0,
|
||||
receivedCount: 0,
|
||||
sentCount: 0,
|
||||
scannedHeight: 0,
|
||||
network: network
|
||||
)
|
||||
|
||||
processor = CompactBlockProcessor(
|
||||
service: service,
|
||||
storage: realCache,
|
||||
rustBackend: rustBackendMockHelper.rustBackendMock,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderImpl(service: service, transactionRepository: transactionRepository)
|
||||
)
|
||||
|
||||
syncStartedExpect = XCTestExpectation(description: "\(self.description) syncStartedExpect")
|
||||
|
|
|
@ -61,7 +61,8 @@ class DownloadTests: XCTestCase {
|
|||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
do {
|
||||
|
|
|
@ -84,7 +84,8 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
do {
|
||||
|
@ -156,7 +157,8 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
do {
|
||||
|
@ -228,7 +230,8 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
do {
|
||||
|
@ -301,7 +304,8 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
rustBackend: mockBackend.rustBackendMock,
|
||||
config: config,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
do {
|
||||
|
@ -353,14 +357,6 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
network: network
|
||||
)
|
||||
|
||||
let transactionRepository = MockTransactionRepository(
|
||||
unminedCount: 0,
|
||||
receivedCount: 0,
|
||||
sentCount: 0,
|
||||
scannedHeight: expectedStoredLatestHeight,
|
||||
network: network
|
||||
)
|
||||
|
||||
var info = LightdInfo()
|
||||
info.blockHeight = UInt64(expectedLatestHeight)
|
||||
info.branch = "d34db33f"
|
||||
|
@ -378,7 +374,10 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
nextBatch = try await CompactBlockProcessor.NextStateHelper.nextState(
|
||||
service: service,
|
||||
downloaderService: downloaderService,
|
||||
transactionRepository: transactionRepository,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock(
|
||||
latestScannedHeight: expectedStoredLatestHeight,
|
||||
latestBlockHeight: expectedLatestHeight
|
||||
),
|
||||
config: config,
|
||||
rustBackend: mockBackend.rustBackendMock,
|
||||
internalSyncProgress: InternalSyncProgress(
|
||||
|
@ -417,21 +416,21 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
latestBlockHeight: expectedLatestHeight,
|
||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||
)
|
||||
let expectedStoreLatestHeight = BlockHeight(1220000)
|
||||
let expectedStoredLatestHeight = BlockHeight(1220000)
|
||||
let walletBirthday = BlockHeight(1210000)
|
||||
|
||||
let ranges = SyncRanges(
|
||||
latestBlockHeight: expectedLatestHeight,
|
||||
downloadedButUnscannedRange: nil,
|
||||
downloadAndScanRange: expectedStoreLatestHeight + 1...expectedLatestHeight,
|
||||
downloadAndScanRange: expectedStoredLatestHeight + 1...expectedLatestHeight,
|
||||
enhanceRange: walletBirthday...expectedLatestHeight,
|
||||
fetchUTXORange: walletBirthday...expectedLatestHeight,
|
||||
latestScannedHeight: expectedStoreLatestHeight,
|
||||
latestDownloadedBlockHeight: expectedStoreLatestHeight
|
||||
latestScannedHeight: expectedStoredLatestHeight,
|
||||
latestDownloadedBlockHeight: expectedStoredLatestHeight
|
||||
)
|
||||
let expectedResult = CompactBlockProcessor.NextState.processNewBlocks(ranges: ranges)
|
||||
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoredLatestHeight)
|
||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
let config = CompactBlockProcessor.Configuration(
|
||||
alias: .default,
|
||||
|
@ -449,14 +448,6 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
network: network
|
||||
)
|
||||
|
||||
let transactionRepository = MockTransactionRepository(
|
||||
unminedCount: 0,
|
||||
receivedCount: 0,
|
||||
sentCount: 0,
|
||||
scannedHeight: expectedStoreLatestHeight,
|
||||
network: network
|
||||
)
|
||||
|
||||
var info = LightdInfo()
|
||||
info.blockHeight = UInt64(expectedLatestHeight)
|
||||
info.branch = "d34db33f"
|
||||
|
@ -474,7 +465,10 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
nextBatch = try await CompactBlockProcessor.NextStateHelper.nextState(
|
||||
service: service,
|
||||
downloaderService: downloaderService,
|
||||
transactionRepository: transactionRepository,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock(
|
||||
latestScannedHeight: expectedStoredLatestHeight,
|
||||
latestBlockHeight: expectedLatestHeight
|
||||
),
|
||||
config: config,
|
||||
rustBackend: mockBackend.rustBackendMock,
|
||||
internalSyncProgress: InternalSyncProgress(
|
||||
|
@ -513,10 +507,10 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
latestBlockHeight: expectedLatestHeight,
|
||||
service: LightWalletServiceFactory(endpoint: LightWalletEndpointBuilder.default).make()
|
||||
)
|
||||
let expectedStoreLatestHeight = BlockHeight(1230000)
|
||||
let expectedStoredLatestHeight = BlockHeight(1230000)
|
||||
let walletBirthday = BlockHeight(1210000)
|
||||
let expectedResult = CompactBlockProcessor.NextState.finishProcessing(height: expectedStoreLatestHeight)
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoreLatestHeight)
|
||||
let expectedResult = CompactBlockProcessor.NextState.finishProcessing(height: expectedStoredLatestHeight)
|
||||
let repository = ZcashConsoleFakeStorage(latestBlockHeight: expectedStoredLatestHeight)
|
||||
let downloaderService = BlockDownloaderServiceImpl(service: service, storage: repository)
|
||||
let config = CompactBlockProcessor.Configuration(
|
||||
alias: .default,
|
||||
|
@ -539,16 +533,8 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
storage: InternalSyncProgressMemoryStorage(),
|
||||
logger: logger
|
||||
)
|
||||
await internalSyncProgress.set(expectedStoreLatestHeight, .latestEnhancedHeight)
|
||||
await internalSyncProgress.set(expectedStoreLatestHeight, .latestUTXOFetchedHeight)
|
||||
|
||||
let transactionRepository = MockTransactionRepository(
|
||||
unminedCount: 0,
|
||||
receivedCount: 0,
|
||||
sentCount: 0,
|
||||
scannedHeight: expectedStoreLatestHeight,
|
||||
network: network
|
||||
)
|
||||
await internalSyncProgress.set(expectedStoredLatestHeight, .latestEnhancedHeight)
|
||||
await internalSyncProgress.set(expectedStoredLatestHeight, .latestUTXOFetchedHeight)
|
||||
|
||||
var info = LightdInfo()
|
||||
info.blockHeight = UInt64(expectedLatestHeight)
|
||||
|
@ -567,7 +553,10 @@ class BlockBatchValidationTests: XCTestCase {
|
|||
nextBatch = try await CompactBlockProcessor.NextStateHelper.nextState(
|
||||
service: service,
|
||||
downloaderService: downloaderService,
|
||||
transactionRepository: transactionRepository,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock(
|
||||
latestScannedHeight: expectedStoredLatestHeight,
|
||||
latestBlockHeight: expectedLatestHeight
|
||||
),
|
||||
config: config,
|
||||
rustBackend: mockBackend.rustBackendMock,
|
||||
internalSyncProgress: internalSyncProgress
|
||||
|
|
|
@ -39,13 +39,7 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testStateStreamEmitsAsExpected() {
|
||||
let state = SynchronizerState(
|
||||
syncSessionID: .nullID,
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100), total: Zatoshi(200)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(200), total: Zatoshi(300)),
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 111111
|
||||
)
|
||||
let state = SynchronizerState.mock
|
||||
synchronizerMock.underlyingStateStream = Just(state).eraseToAnyPublisher()
|
||||
|
||||
let expectation = XCTestExpectation()
|
||||
|
@ -70,13 +64,7 @@ class ClosureSynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testLatestStateIsAsExpected() {
|
||||
let state = SynchronizerState(
|
||||
syncSessionID: .nullID,
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100), total: Zatoshi(200)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(200), total: Zatoshi(300)),
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 111111
|
||||
)
|
||||
let state = SynchronizerState.mock
|
||||
synchronizerMock.underlyingLatestState = state
|
||||
|
||||
XCTAssertEqual(synchronizer.latestState, state)
|
||||
|
|
|
@ -37,13 +37,7 @@ class CombineSynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testStateStreamEmitsAsExpected() {
|
||||
let state = SynchronizerState(
|
||||
syncSessionID: .nullID,
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100), total: Zatoshi(200)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(200), total: Zatoshi(300)),
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 111111
|
||||
)
|
||||
let state = SynchronizerState.mock
|
||||
synchronizerMock.underlyingStateStream = Just(state).eraseToAnyPublisher()
|
||||
|
||||
let expectation = XCTestExpectation()
|
||||
|
@ -68,13 +62,7 @@ class CombineSynchronizerOfflineTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testLatestStateIsAsExpected() {
|
||||
let state = SynchronizerState(
|
||||
syncSessionID: .nullID,
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100), total: Zatoshi(200)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(200), total: Zatoshi(300)),
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 111111
|
||||
)
|
||||
let state = SynchronizerState.mock
|
||||
synchronizerMock.underlyingLatestState = state
|
||||
|
||||
XCTAssertEqual(synchronizer.latestState, state)
|
||||
|
|
|
@ -56,7 +56,8 @@ class CompactBlockProcessorOfflineTests: XCTestCase {
|
|||
rustBackend: rustBackend,
|
||||
config: processorConfig,
|
||||
metrics: SDKMetrics(),
|
||||
logger: logger
|
||||
logger: logger,
|
||||
latestBlocksDataProvider: LatestBlocksDataProviderMock()
|
||||
)
|
||||
|
||||
let fullRange = 0...1000
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// LatestBlocksDataProviderMock.swift
|
||||
//
|
||||
//
|
||||
// Created by Lukáš Korba on 12.04.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@testable import ZcashLightClientKit
|
||||
|
||||
actor LatestBlocksDataProviderMock: LatestBlocksDataProvider {
|
||||
private(set) var latestScannedHeight: BlockHeight = .zero
|
||||
private(set) var latestScannedTime: TimeInterval = 0.0
|
||||
private(set) var latestBlockHeight: BlockHeight = .zero
|
||||
private(set) var walletBirthday: BlockHeight = .zero
|
||||
|
||||
init(
|
||||
latestScannedHeight: BlockHeight = .zero,
|
||||
latestScannedTime: TimeInterval = 0,
|
||||
latestBlockHeight: BlockHeight = .zero,
|
||||
walletBirthday: BlockHeight = .zero
|
||||
) {
|
||||
self.latestScannedHeight = latestScannedHeight
|
||||
self.latestScannedTime = latestScannedTime
|
||||
self.latestBlockHeight = latestBlockHeight
|
||||
self.walletBirthday = walletBirthday
|
||||
}
|
||||
|
||||
func updateScannedData() async { }
|
||||
|
||||
func updateBlockData() async { }
|
||||
|
||||
func updateWalletBirthday(_ walletBirthday: BlockHeight) async { }
|
||||
|
||||
func updateLatestScannedHeight(_ latestScannedHeight: BlockHeight) async { }
|
||||
|
||||
func updateLatestScannedTime(_ latestScannedTime: TimeInterval) async { }
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// File.swift
|
||||
// MockSessionIDGenerator.swift
|
||||
//
|
||||
//
|
||||
// Created by Francisco Gindre on 3/31/23.
|
||||
|
|
|
@ -100,7 +100,11 @@ extension MockTransactionRepository: TransactionRepository {
|
|||
}
|
||||
|
||||
func lastScannedHeight() throws -> BlockHeight {
|
||||
return scannedHeight
|
||||
scannedHeight
|
||||
}
|
||||
|
||||
func lastScannedBlock() throws -> Block? {
|
||||
nil
|
||||
}
|
||||
|
||||
func isInitialized() throws -> Bool {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// File.swift
|
||||
// SDKSynchronizer+Utils.swift
|
||||
//
|
||||
//
|
||||
// Created by Francisco Gindre on 3/31/23.
|
||||
|
@ -11,6 +11,10 @@ import Foundation
|
|||
extension SDKSynchronizer {
|
||||
convenience init(initializer: Initializer, sessionGenerator: SyncSessionIDGenerator, sessionTicker: SessionTicker) {
|
||||
let metrics = SDKMetrics()
|
||||
let latestBlocksDataProvider = LatestBlocksDataProviderImpl(
|
||||
service: initializer.lightWalletService,
|
||||
transactionRepository: initializer.transactionRepository
|
||||
)
|
||||
self.init(
|
||||
status: .unprepared,
|
||||
initializer: initializer,
|
||||
|
@ -21,11 +25,13 @@ extension SDKSynchronizer {
|
|||
initializer: initializer,
|
||||
metrics: metrics,
|
||||
logger: initializer.logger,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider,
|
||||
walletBirthdayProvider: { initializer.walletBirthday }
|
||||
),
|
||||
metrics: metrics,
|
||||
syncSessionIDGenerator: sessionGenerator,
|
||||
syncSessionTicker: sessionTicker
|
||||
syncSessionTicker: sessionTicker,
|
||||
latestBlocksDataProvider: latestBlocksDataProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,3 +200,17 @@ extension CompactBlockProcessor.Configuration {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension SynchronizerState {
|
||||
static var mock: SynchronizerState {
|
||||
SynchronizerState(
|
||||
syncSessionID: .nullID,
|
||||
shieldedBalance: WalletBalance(verified: Zatoshi(100), total: Zatoshi(200)),
|
||||
transparentBalance: WalletBalance(verified: Zatoshi(200), total: Zatoshi(300)),
|
||||
syncStatus: .fetching,
|
||||
latestScannedHeight: 111111,
|
||||
latestBlockHeight: 222222,
|
||||
latestScannedTime: 12345678
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue